学习"WorldSpaceLightPos0"

        今天学习_WorldSpaceLightPos0这个cg内置变量的含义的时候,无意中发现了一些有趣的知识点。首先了解到_WorldSpaceLightPos0这个变量的含义是,这是一个表示世界做表中光源的位置矢量或者方向向量,如果_WorldSpaceLightPos0.w为0,则表示该光源为平行光,_WorldSpaceLightPos0.xyz为此平行光的方向向量。反之_WorldSpaceLightPos0.w不为0,则表示光源为点光源,_WorldSpaceLightPos0.xyz为此点光源。

        为此,我想尝试在unity场景中设置点光源和平行光源来验证这个效果,于是改了基础shader为:

Shader"Unlit/LightTest{

    Properties

       {

              _MainTex("Texture", 2D) ="white"{}

       }

              SubShader

       {

              Tags {"RenderType"="Opaque"}

              LOD 100

              Pass

              {

                     CGPROGRAM

                     #pragmavertex vert

                     #pragmafragment frag

                     // make fog work

                     #pragmamulti_compile_fog

                     #include"UnityCG.cginc"

                     structappdata

                     {

                           float4vertex : POSITION;

                           float2uv : TEXCOORD0;

                     };

                     structv2f

                     {

                           float2uv : TEXCOORD0;

                           UNITY_FOG_COORDS(1)

                           float4vertex : SV_POSITION;

                     };

                     sampler2D_MainTex;

                     float4_MainTex_ST;

                     fixed4 _BlackColor;

                     fixed4 _WhiteColor;

                     v2f vert(appdata v)

                     {

                           v2f o;

                           o.vertex = UnityObjectToClipPos(v.vertex);

                           o.uv = TRANSFORM_TEX(v.uv, _MainTex);

                           UNITY_TRANSFER_FOG(o,o.vertex);

                           returno;

                     }

                     fixed4 frag(v2f i) : SV_Target

                     {

                           // sample the texture

                 fixed4 col = tex2D(_MainTex, i.uv);

                     // apply fog

                     UNITY_APPLY_FOG(i.fogCoord, col);

                     if(_WorldSpaceLightPos0.w == 0)//平行光源

                     {

                           col = fixed4(1, 0, 0, 1.0);

                     }

                     else//点光源

                     {

                           col = fixed4(0, 1, 0, 1.0);

                     }

                     returncol;

              }

              ENDCG

       }

       }

}

重点是这几句,如果是平行光源,输出的颜色为红色,如果不是平行光源,输出的颜色为绿色

 if(_WorldSpaceLightPos0.w == 0)//平行光源

 {

   col = fixed4(1, 0, 0, 1.0);

  }

 else//点光源

 {

   col = fixed4(0, 1, 0, 1.0);

 }

然后在场景上分别创建了一个Directiona light和 Point light,观察结果如下:

1、Directiona light激活,Point light也激活时,金币显示为红色


学习

2、Directiona light激活,Point light不激活时,金币显示为红色


学习

3、Directiona light不激活,Point light激活时,金币显示为红色


学习

4、Directiona light不激活,Point light不激活时,金币显示为红色


学习

这就产生两个问题——

为何Point light存在的时候,没有效果呢?

为何无论平行光有没有存在,_WorldSpaceLightPos0.w一直都是0呢?

后面查找到了这篇文章https://forum.unity.com/threads/_worldspacelightpos0-how-it-works.435673/,一个同学的回答,


学习

        如果当前物体的shader设置的光照模式是ForwardBase,那么就总是对平行光有效,即使场景上没有灯光,所以要把LightMode改成"ForwardAdd",Point light才能生效,因此我将Tags标签添加了"LightMode"="ForwardAdd"看下效果:

Tags {"RenderType"="Opaque""LightMode"="ForwardAdd"}

发现:

1、Directiona light激活,Point light也激活时,金币显示为绿色


学习

2、Directional light激活,Point light不激活时,金币不显示了


学习

3、Directiona light不激活,Point light激活时,金币显示为绿色


学习

4、Directiona light不激活,Point light不激活时,金币显示为红色


学习

所以,Shader光照模型要使用Point light,需要在Tag标签上添加"LightMode"="ForwardAdd"

然而,现在又引申出新的知识点,LightMode是什么意思?从字面上的意思是"光照模式",它有多种设置选项,分别是什么含义呢?还有与之相对应的_LightColor0是什么意思?这个我们后面的章节来讲

你可能感兴趣的:(学习"WorldSpaceLightPos0")