阴影效果

  首先光源要开启阴影类型 :Shadow  Type 改为不是No的类型,一般选择Soft  Shadows



地板(影子的载体) : 

       5.0以前,系统内建的shader,只能接收平行光产生的投影;5.0版以后的标准着色器则就可以接收任何形式的光源的投影

       如果在4.x版本,如果想要让点光源投射的阴影也能显示,将playersettings中的Rendering  Path 的 forward 改为其它延迟光照选项即可




自编写的Shader 要达到既能投射阴影,又能接收阴影的效果

 


如果只需要接收平行光的投影,可以只加入一个空的pass通道,将标签设为 "Shadowcaster", 阴影投射器

Pass

{

     tags { " LightMode " = " Shadowcaster " } 

,不需要作其它任何代码的编写。



     加上阴影投射器后,就能对平行光投影的阴影产生效果,但是此时并不能对点光源产生效果。 如果需要对所有的光源都能投影产生阴影效果,显然,只用阴影投射器的做法是不能达到要求的。

     使用 : fallback  "Diffuse" ,即可以对所有的光源的投影都产生阴影效果。





接收阴影Shader(地板) :

      #include  "autolight.cginc"

      

 4.x版本,使用三个宏 :

      第一个宏 :LIGHTING_COORDS(idx1 , idx2)  有语义,所以只能在结构体和函数中使用,不需要分号

          放在结构体中使用 :LIGHTING_COORDS(0 , 1)       

                     // 包含了  unityShadowCoord3_LightCoord : TEXCOORD0;

                                      unityShadowCoord3_ShadowCoord : TEXCOORD1;   两个变量


      第二个宏 :TRANSFER_VERTEX_TO_FRAGMENT(struct)   放在顶点函数中,实质上是对第一个宏的两个变量进行赋值,不需要分号


      第三个宏 :LIGHT_ATTENUATION(struct) ;      需要分号,放在片段函数中,描述光的衰减程度,返回一个float值

                       float  atten = LIGHT_ATTENUATION(IN);

                       // atten变量描述最后渲染的部分是否为阴影所照射,照射后达到什么深度

      5.x版本 :第三个宏 可以换成 :UNITY_LIGHT_ATTENUATION(destName , input , worldPos) ;      

                      // 参数 :fixed类型,在宏的内部声明 、 结构体 、 顶点的世界坐标



此时,地板已经能够接收到平行光投射的阴影,如果想要再加上别的光源,很简单 :

      完全复制、粘贴一份pass通道,然后将tags改为 :

             tags { "LightMode" = "ForwardAdd"}

             Blend  one  one

    因为,当有两个pass通道时,系统只会保留第二个pass通道,达不到我们想要的结果,所以,需要作Blend操作。 在第二个pass中加上" Blend  one  one",目的是让当前pass通道全部通过。此时,便可以既能接收平行光投影,又能接收像素光的投影。


  

    优化 :因为将两个pass完全混合,所以不需要两个环境光,可以删掉一个环境光


    总结 :如果想要编写一个复杂的shader与光交互,建议使用surfaceshader




Shader  "Custom/MyDiffuseShadow" {

   SubShader

   {

       Pass

       {

            Tags { "LightMode" = "ForwardBase" }


            CGPROGRAM

            #pragma  multi_compile_fwdbase      

            #pragma  vertex  vert

            #pragma  fragment  frag

            #include  "unitycg.cginc"

            #include  "lighting.cginc"

            #include  "autolight.cginc"            // 包含三个宏


            struct2  v2f {

                   float4  pos : POSITION;

                   fixed4 color : COLOR;


                   LIGHTING_COORDS(0,1)             

                      // 第一个宏,在结构体中使用,unity自带的宏,包含两个变量 :unityShadowCoord3  _LightCoord : TEXCOORD0;   和   unityShadowCoord3   _ShadowCoord : TEXCOORD1;

            };


            v2f  vert (appdata_base  v)

            {

                   v2f  o;

                   o.pos = mul(UNITY_MATRIX_MVP , v.vertex);


                   float3  N = normalize(v.normal);          

                   float3  L = normalize(_WorldSpaceLightPos0);


                   N = mul(float4(N,0) , _World2Object).xyz ;

                   N = normalize(N);


                   float  ndotl = saturate(dot(N,L));

                   o.color = _LightColor0 * ndotl;           // 光线颜色


                   float3  wpos = mul(_Object2World , v.vertex).xyz;        // 顶点在世界坐标系中的位置


                   o.color.rgb += Shade4PointLights( unity_4LightPosX0 , unity_4LightPosY0 , unity_4LightPosZ0 ,

                                                                                 unity_LightColor[0].rgb , unity_LightColor[1].rgb , 

                                                                                 unity_LightColor[2].rgb , unity_LightColor[3].rgb ,

                                                                                 unity_4LightAtten0 ,

                                                                                wpos , N) ;



                   TRANSFER_VERTEX_TO_FRAGMENT(o)           // 第二个宏 :实质上是对结构体中的宏(LIGHTING_COORDS) 的变量进行赋值

                   return  o;

            }


            fixed4  frag(v2f  IN) : COLOR

            {

                  float  atten = LIGHT_ATTENUATION(IN) ;        // 第三个宏 :描述光的衰减程度,参数也是一个struct,返回一个float值

                  // atten变量,描述最后渲染的部分是否被阴影所照射,照射后达到什么深度


                  // UNITY_LIGHTMODEL_ATTENUATION(atten , IN , wpos)  

                  5.x版本,atten是一个fixed类型,在宏内部声明的变量;IN是结构体,wpos是顶点在世界坐标系中的位置


                  fixed4  col = IN.color + UNITY_LIGHTMODEL_AMBIENT;

                  col.rgb *= atten;

                  return  col ;

            }


            ENDCG

       }




       Pass

       {

            Tags { "LightMode" = "ForwardBase" }


            Blend  one  one


            CGPROGRAM

            #pragma  multi_compile_fwdbase      

            #pragma  vertex  vert

            #pragma  fragment  frag

            #include  "unitycg.cginc"

            #include  "lighting.cginc"

            #include  "autolight.cginc"          


            struct2  v2f {

                   float4  pos : POSITION;

                   fixed4 color : COLOR;


                   LIGHTING_COORDS(0,1)                                

            };


            v2f  vert (appdata_base  v)

            {

                   v2f  o;

                   o.pos = mul(UNITY_MATRIX_MVP , v.vertex);


                   float3  N = normalize(v.normal);          

                   float3  L = normalize(_WorldSpaceLightPos0);


                   N = mul(float4(N,0) , _World2Object).xyz ;

                   N = normalize(N);


                   float  ndotl = saturate(dot(N,L));

                   o.color = _LightColor0 * ndotl;           // 光线颜色


                   float3  wpos = mul(_Object2World , v.vertex).xyz;        // 顶点在世界坐标系中的位置


                   o.color.rgb += Shade4PointLights( unity_4LightPosX0 , unity_4LightPosY0 , unity_4LightPosZ0 ,

                                                                                 unity_LightColor[0].rgb , unity_LightColor[1].rgb , 

                                                                                 unity_LightColor[2].rgb , unity_LightColor[3].rgb ,

                                                                                 unity_4LightAtten0 ,

                                                                                wpos , N) ;



                   TRANSFER_VERTEX_TO_FRAGMENT(o)           

                   return  o;

            }


            fixed4  frag(v2f  IN) : COLOR

            {

                  float  atten = LIGHT_ATTENUATION(IN) ;       

                 

                  col.rgb *= atten;

                  return  col ;

            }


            ENDCG

       }


      

   }   

}




       Pass

       {

            Tags { "LightMode" = "ForwardBase" }


            CGPROGRAM

            #pragma  multi_compile_fwdbase      

            #pragma  vertex  vert

            #pragma  fragment  frag

            #include  "unitycg.cginc"

            #include  "lighting.cginc"

            #include  "autolight.cginc"            // 包含三个宏


            struct2  v2f {

                   float4  pos : POSITION;

                   fixed4 color : COLOR;


                   LIGHTING_COORDS(0,1)             

                      // 第一个宏,unity自带的宏,包含两个变量 :unityShadowCoord3  _LightCoord : TEXCOORD0;   和   unityShadowCoord3   _ShadowCoord : TEXCOORD1;

            };


            v2f  vert (appdata_base  v)

            {

                   v2f  o;

                   o.pos = mul(UNITY_MATRIX_MVP , v.vertex);


                   float3  N = normalize(v.normal);          

                   float3  L = normalize(_WorldSpaceLightPos0);


                   N = mul(float4(N,0) , _World2Object).xyz ;

                   N = normalize(N);


                   float  ndotl = saturate(dot(N,L));

                   o.color = _LightColor0 * ndotl;           // 光线颜色


                   float3  wpos = mul(_Object2World , v.vertex).xyz;        // 顶点在世界坐标系中的位置


                   o.color.rgb += Shade4PointLights( unity_4LightPosX0 , unity_4LightPosY0 , unity_4LightPosZ0 ,

                                                                                 unity_LightColor[0].rgb , unity_LightColor[1].rgb , 

                                                                                 unity_LightColor[2].rgb , unity_LightColor[3].rgb ,

                                                                                 unity_4LightAtten0 ,

                                                                                wpos , N) ;



                   TRANSFER_VERTEX_TO_FRAGMENT(o)           // 第二个宏 :实质上是对结构体中的宏(LIGHTING_COORDS) 的变量进行赋值

                   return  o;

            }


            fixed4  frag(v2f  IN) : COLOR

            {

                  float  atten = LIGHT_ATTENUATION(IN) ;        // 第三个宏 :参数也是一个struct,返回一个float值


                  fixed4  col = IN.color + UNITY_LIGHTMODEL_AMBIENT;

                  col.rgb *= atten;

                  return  col ;

            }


            ENDCG

       }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值