纠结了半天,错误和各种不规范,最后看到一句话:计算机图形学的第一定律:如果他看起来是对的,那么他就是对的。
《3D数学基础:图形与游戏开发》的作者邓恩说的。
“他的话看起来是对的,所以是对的。”我这么理解道。
【资料图】
嗯……大概是对的吧……这个光照模型还缺少Sph,不过问题倒也不大。
嗯……下次再考虑加上spa吧。看舞力介入的full.fx中是将影色单独拿出来写的……
首先是准备数据。这次需要的数据比上次多很多。
矩阵是必须的。接下来是这些。(唉我是真的麻了……我写的整整齐齐的代码扔进这个网页就不给我对齐,手动对齐好几遍还不齐)
参考MME手册。即可明白书写的格式。把语义写对了就没太大问题。
颜色计算。static的作用应该和C语言里的一样,用来说明静态变量,声明了static后变量就是内部变量。
简单光照模型,假定物体为非透明物体,物体表面所呈现的颜色仅由反射光决定,不考虑透射光。反射光部分被细分为漫反射光 DiffuseColor 和 镜面反射光SpecularColor两种。
简单光照模型分为 环境光模型、漫反射光模型、镜面反射光模型,全部属于经验模型,表现为:
I表示物体表面上一点反射到视点的光强,e、d、s分别为环境光光强、漫反射光光强、镜面反射光光强。
材质部分,要考虑材质属性,材质属性是指物体表面对光的吸收、反射和透射的性能。由于是简单光照模型,所以只考虑材质的反射属性。
镜面反射光较为特殊,要考虑镜面反射率,所以引用了float SPECULARPOWER
然后是
然后是采样器。
如果要调用纹理,那么就需要采样器。
然而纹理,是没法直接使用的。需要滤波。不理解也没关系,这东西绝大部分情况下都不用改,复制粘贴调用就行。
结构体准备我们需要的用到的数据。然后是顶点着色,输入输出都很正常。这里我们呢需要准备 一个Eye的视点位置的数据。这个视点位置这样计算。
Normal 顶点法线的转换,然后单位化。
这里用到了新的函数normalize(x),意思是返回单位化向量,定义为 x / length(x)。
然后是像素着色器的部分。
首先得定义个Color,后面才能用。
Color.rgb,意思是取得Color的前三维,我在上一篇有说但是没举例子。
举个例子,如果float4 Color = float4(1,0.2,0.3,1),那么Color.rgb 的意思就是调用1,0.2,0.3,这三维。Color.r,同理,调用第一维。
同理,xyzw,也可以。Color.xyzw 和 Color.rgba等效,但是不能混着用。
这里用到了新的函数saturate(x),意思是把x截取到[0, 1]之间。
函数max(x, y),意思是取x,y两者中较大的。
这里是计算物体的rgb值。就是物体的法向*漫反射颜色+环境色。
接下来计算反射光颜色。这里用到了一个半程向量,通过对观察向量和光向量取平均然后归一化得到一个新的向量,新向量称为半程向量(bisector),使用半程向量与法线点乘来计算高光。
这里有个新函数pow,pow(x, y),意思是x^y。
使用半程向量,是为了简化计算。
Phong提出的一个计算镜面反射光的经验公式,成为Phong模型。模型上一点P的镜面反射光强为:
为入射光强,为镜面反射率
对于单位向量R、V,有,考虑有大于90的情况,R·V的结果为负,应该取0,所以改写为
不难看出镜面反射的光强不仅取决于物体表面的法线方向,而且依赖于光远与视线的相对位置。只有当视点位于比较合适的位置时,才可以观察到物体表面某些区域呈现的高光。所以在简单光照模型中,“视点固定,旋转物体”和“视点旋转,物体固定”所看到的物体是有差别的。
V的计算很简单,R的计算稍微复杂。
总结下来,Phong模型的计算非常复杂,再加上环境光和漫射光,会让式子变得更长。
Blinn指出中分向量H的方向是最大反射光强方向,对模型进行改进,改进后的模型成为Blinn-Phong模型。Blinn用N·H代替R·V,其中H为中分向量,是单位光向量L和单位观察向量V的平分向量。
改进后的公式表述为
这里用到了新的函数tex2D(s,t),意思是返回纹理s在t位置的颜色。
接下来做个判断,woc我这里写错了,前边的插入的代码块不知道怎么变更了……麻烦把这个UseTexture改成UseToon,这里是在判断是否使用toon,做了一个插值计算。
虽然可能对结果影响不大,因为现在绝大部分模型都有toon。
这里用了一个新函数lerp,lerp(x, y, s),对x、y进行插值计算。Returns x + s(y - x)。
最后是个pass
注意