untiy 3d ShaderLab_第7章_ Forward渲染路径_2_Forward渲染路径下的重要光源

来源:互联网 发布:新浪微博登陆网络异常 编辑:程序博客网 时间:2024/06/11 16:25
 第7章 Forward渲染路径
    本章的主要目的是让大家在不使用Unity的Surface Shader时,也能够正确地存取Unity的光源数据,从而定制自己的Forward渲染路径的Shader。如果读者没有这个需求,或者己经了解了Unity是如何为Forward渲染路径存放光源数据的,那么就可以跳过本章。  
7.2Forward渲染路径下的重要光源
7.2.1 设计检测用的材质

其编辑器截图如图所示,


_WorldSpaceLightPosO.x.shader文件,其主要代码如下:
Shader "Tut/Lighting/Forward/Lab_1/Add/_WorldSpaceLighPos0.x" {SubShader {pass{Tags{ "LightMode"="ForwardBase"}CGPROGRAM#pragma vertex vert#pragma fragment frag#pragma multi_compile_fwdbase#include "UnityCG.cginc"#include "Lighting.cginc"struct vertOut{float4 pos:SV_POSITION;float4 color:COLOR;};vertOut vert(appdata_base v){vertOut o;o.pos=mul(UNITY_MATRIX_MVP,v.vertex);o.color=float4(0,0.5,1,1);//输出蓝色return o;}float4 frag(vertOut i):COLOR{return i.color;}ENDCG}//end passpass{Tags{ "LightMode"="ForwardAdd"}Blend One Zero//该混合模式消去Forward Base的影响CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"#include "Lighting.cginc"struct vertOut{float4 pos:SV_POSITION;float4 color:COLOR;};vertOut vert(appdata_base v){vertOut o;o.pos=mul(UNITY_MATRIX_MVP,v.vertex);o.color=_WorldSpaceLightPos0.x;//有4个类似这样的Shader,分别输出xyzw分量return o;}float4 frag(vertOut i):COLOR{return i.color;}ENDCG}//end pass}}
    这个材质的ForwardAdd Pass使用了Blend One Zero的混合模式,因此可以正确地输出最后执行的ForwardAdd Pass的输出,而且,如果ForwardAdd Pass末被执行,将会输出ForwardBase Pass的结果,即输出1个鲜亮的蓝色(0,0.5,1.0)。
7.2.2不存在Pixel光源时的情况

    当前场景中有两个平行光和4个点光源,但是全为Vertex光源。现在我们可以将此场景编译运行一下,其结果如下图所示。可见到在LightMode = ForwardBase的Pass内_WorIdSapceLightPos0没有被设置一个光源数据,而右边的信号输出全是ForwardBase Pass输出的鲜亮的蓝色,这说明当前情况下的ForwardAdd Pass没有被执行。


7.2.3存在Pixel平行光时的情况

    我们将一个平行光改为Pixel光源,其结果如下图所示,在FowardBase的Pass内,_WorldSpaceLightPos0和_LightColor0有了数据,但是右边的鲜蓝色信号输出告诉我们此时FowardAdd Pass仍没有被执行。


7.2.4存在Pixel点光源时的情况

       如果此时我们再将一个或者多个点光源设为Pixel光源,而没有Pixel平行光,可以看到如下图所示的结果,右边的信号输出显示ForwardAdd Pass包含光源数据且被执行。左边的FowardBasePass内_WorldSpaceLightPosO内有数据,但是对应的_LightColor0没有,这样使用_WorldSpaceLightPos0和_LightColor0的组合输出仍然是黑色,对最终的光照没有影响。


      这种情形的存在原因是Unity为FowardAdd Pass准备的光源数据在再次轮回到为FowardBase准备数据时Unity未及时清除的结果。Unity出于性能方面的考虑,因为毕竟在CPU和GPU之间频繁传递数据是很耗资源的一件事情。
7.2.5  Forward渲染路径下的Pixel光源小结
    至此我们可以总结在LightMode = ForwardBase,LightMode=FowardAdd的Pass内,_WorldSapceLightPos0只会含有Pixel光源。在ForwardBase Pass内,只有场景中存在RenderMode为Important的Pixel平行光时,才会含有有效的_WorldSpaceLightPos0和_LightColor0的组合。
0 0
原创粉丝点击