纠结了半天,错误和各种不规范,最后看到一句话:计算机图形学的第一定律:如果他看起来是对的,那么他就是对的。

《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

注意

推荐内容