Phong模型引出的一系列问题
如下是实现phong模型时出现的一系列问题,在此归纳整理。
ShaderGraph中实现模型出现的问题
ShaderGraph中如何获取场景中的平行光
创建一个Custom Function节点:
节点的面板如下图,和下图保持一样即可:
body的代码如下:
1 |
|
- 再给节点打个组让他看起来好看一些😏:
高光的错误
错误1:




当视角靠近物体时,如上面第4张图所示,高光的边才稍微软了一些并且高光变小了。
错误2:

原因:
上面两个错误都是使用shader graph才引起的错误,但是使用shader forge或者自己手写shader的时候却没有这样的错误。
错误来源于View Direction
这个节点,该节点输出一个向量,按照常识一般以Direction命名的向量应该是单位化(normalize)了的,但是shader graph中没有😂。该节点输出的向量是片元或顶点到视角的距离向量,如果你想把它当方向向量使用的话需要自己加一个normalize节点:

由于phong模型当中会有光线方向L的反射点乘视角方向V,因此当视角方向向量过大的时候L和V点乘的结果将会变大,距离越远结果越大,就会造成隔远了高光又大又圆隔近了会稍微缓解的现象。
而在blinn phong模型中,会有光线方向L加上视角方向V去获得半角向量H这个操作,因此当V过大的时候L的影响将会变小,H就会和V的方向保持一致,最终H点乘片元或顶点的法向量N时就相当于是V在和N做点乘,因此会出现不管怎么移动视角和光源高光都不怎么移动的现象。
布局引起的bug

如上图所示,不管如何转动光源的方向,scene窗口中物体都没有变化,但是game窗口中显示正常。

上面的问题可能是unity的bug吧,解决办法,更换一个布局:

手写Shader代码出现的问题

如上图所示,用phong模型实现的高光有那种一块快,在某个顶点出很亮的感觉,这样的效果很差。
产生这种效果的原因是,在插值的时候,有些插值片元的法线长度被缩短了归一化被破坏了,需要重新归一化——float3 N = normalize(i.normal);
。更改之后的效果:
