SurfaceShader中的finalcolor覆盖雾化

发表于2017-12-08
评论0 1.2k浏览

前天美术同事让我调一个Tree的Shader,起因是因为他在另外一个游戏里看到的树亮部很亮,暗部很暗,反差很大,而一般的shader做不到,而且每棵树也没有对应的高光贴图。

于是找到Unity内置的一个Shader,一个alpha裁剪+漫反射shader,修改了他的明部暗部的反差(做了一个双重插值),发给他之后,同事感觉很满意。

没想到第二天同事发现那个模型却不再受全局雾影响。finalcolor用的少,但是那个shader源码是surfaceShader,调节明部暗部的色值只能去finalcolor下手,原因就不表述了,问题就出在这里。因为我没有具体去看finalcolor宏是否对应的是帧缓存里的颜色?我以前的记忆中,可帧缓存似乎属于pipeline中的不可编程环节,可雾化确实因为它被抵消了,surfaceShader默认处理了全局雾,打开finalcolor啥也不做,就有效果,一旦指定finalcolor函数,雾化在该物体就失效。


解决问题思路:

1.查阅所有surfaceShader关于finalColor的官方文档说明与文章。

无果

2.阅读所有内置shader源码,寻找相关处理。

无果


最后解决办法:

1.指定vertex函数进行UNITY_TRANSFER_FOG,输出到surf后,在surf函数中进行UNITY_APPLY_FOG_COLOR。

无果

原因:雾化会在表面着色器进行后,再进行光照着色(Lightingxxxxx函数),最后出来的效果美术不满意,因为完全被雾遮住后由于光照计算,亮部仍然没有隐去,应该先光照,再雾化。


2.直接在finalcolor进行UNITY_APPLY_FOG_COLOR

顺序出错

如果先进行双重插值,再进行雾化,那么雾化后的整体颜色会偏亮,并且镜头拉远无法完全在场景中隐去,只看见一个亮亮的灰色。


正确顺序:在finalcolor中先进行全局雾化(finalcolor执行时本身已经计算过光照),再进行最后的双重插值,完美解决。


分析:

由于我的插值算法让颜色的取值范围有所降低,即最亮的颜色色值已经超过了1(没有进行边界判断),先插值,再雾化时,雾化函数应该也没有把颜色值域归到[0-1]之间,造成了最后的灰色。

而先雾化再插值,那么插值之前的颜色值域在[0-1]之间,能够正常隐去,最后再进行插值,没有隐去的部分,颜色也是美术想要的颜色。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引