Cg入门17:Fragment shader - 片段级光照(添加阴影)

时间:2021-08-29 03:55:51
投射阴影
方法一:添加一个单独的pass通道
pass
{
     Tags{"LightMode" = "ShadowCaster"}
}
ShadowCaster:阴影投射器,可以投射阴影

方法二:添加物体默认阴影投射
FallBack "Diffuse"

然后给光线开启阴影:
Cg入门17:Fragment shader - 片段级光照(添加阴影)
效果如下:(效果图为添加平行光)
Cg入门17:Fragment shader - 片段级光照(添加阴影)
如果要让我们的shader支持点光源阴影投射,就添加   FallBack "Diffuse"
Cg入门17:Fragment shader - 片段级光照(添加阴影)
添加点光源后效果:
Cg入门17:Fragment shader - 片段级光照(添加阴影)
接收阴影:让我们的球平面接受阴影

源代码:
Shader "Sbin/MyDiffuse_Shadow" {
	SubShader {
	
//		pass{
//			tags{"lightmode" = "shadowcaster"}
//		}
		
		pass{
			tags{"lightmode" = "ForwardBase"}   //现实一个平行光按像素计算		
			
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			
			#include "UnityCG.cginc"
			#include "Lighting.cginc"
			#pragma multi_compile_fwdbase		//多版本编译
			#include "autolight.cginc"

			struct v2f{
				float4 pos : POSITION;
				float4 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 ndot = saturate(dot(N,L));
				o.color = _LightColor0 * ndot;
				
				//点光源
				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 v):COLOR
			{
				float atten = LIGHT_ATTENUATION(v);//光照衰减
				
				fixed4 col = (v.color + UNITY_LIGHTMODEL_AMBIENT);
				col.rgb *= atten;

				return col;
			}

			ENDCG
		}
		
		//--------------------------------------------------------------------------
		
		pass{
			tags{"lightmode" = "ForwardAdd"}	//平行光和顶点光全部按像素计算,是像素光就调用一次这个pass
			
			blend one one 	//叠加上一个pass的颜色值
			
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			
			#include "UnityCG.cginc"
			#include "Lighting.cginc"
			#pragma multi_compile_fwdadd_fullshadows
			#include "autolight.cginc"

			struct v2f{
				float4 pos : POSITION;
				float4 color : COLOR;
				LIGHTING_COORDS(0,1)
			};

			float4 _MainColor;
			float4 _SpecalarColor;
			float _Shininess; 

			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 ndot = saturate(dot(N,L));
				o.color = _LightColor0 * ndot;
				
				//点光源
				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 v):COLOR
			{
				float atten = LIGHT_ATTENUATION(v);
				
				fixed4 col = v.color;
				col.rgb *= atten;

				return col;
			}

			ENDCG
		}
	} 
	
	fallback "Diffuse"
}



总结:
1.设置支持多版本编译:
#pragma multi_compile_fwdbase        //多版本编译
2.pass 与pass 叠加
blend one one     //叠加上一个pass的颜色值
3.添加tags
tags{"lightmode" = "ForwardBase"} //现实一个平行光按像素计算    
tags{"lightmode" = "ForwardAdd //平行光和顶点光全部按像素计算,是像素光就调用一次这个pass