Phong模型引出的一系列问题

Phong模型引出的一系列问题

如下是实现phong模型时出现的一系列问题,在此归纳整理。


ShaderGraph中实现模型出现的问题

ShaderGraph中如何获取场景中的平行光

  1. 创建一个Custom Function节点:

  2. 节点的面板如下图,和下图保持一样即可:

body的代码如下:

body
1
2
3
4
5
6
7
8
#ifdef SHADERGRAPH_PREVIEW
Direction = normalize(float3(1,1,-0.4));
Color = float4(1,1,1,1);
#else
Light mainLight = GetMainLight();
Direction = mainLight.direction;
Color = mainLight.color;
#endif
  1. 再给节点打个组让他看起来好看一些😏:

高光的错误

错误1:

在使用shader graph写phong模型的时候,当视角离物体较远,如上面的前3张图所示,出现这样又大又圆且极其生硬的高光,不管怎么调整Specular Power参数都没有变化。

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

错误2:

在使用shader graph写blinn phong模型的时候,不管怎么转动视角和光源的方向发现高光都不怎么移动。

原因:
上面两个错误都是使用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窗口中显示正常。

如上gif图所示,有的时候scene和game窗口中当把手写的shader给物体时,物体的材质会抖动。(该问题好像是在urp里才存在,如果切换回built-in管线不会有这样的问题)

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


手写Shader代码出现的问题

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

评论