Cg入门17:Fragment shader - 片段级光照(添加阴影)
Posted Potter
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cg入门17:Fragment shader - 片段级光照(添加阴影)相关的知识,希望对你有一定的参考价值。
投射阴影
方法一:添加一个单独的pass通道
pass
{
Tags{"LightMode" = "ShadowCaster"}
}
ShadowCaster:阴影投射器,可以投射阴影
方法二:添加物体默认阴影投射
FallBack "Diffuse"
然后给光线开启阴影:
效果如下:(效果图为添加平行光)
如果要让我们的shader支持点光源阴影投射,就添加 FallBack "Diffuse"
添加点光源后效果:
接收阴影:让我们的球平面接受阴影
源代码:
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
以上是关于Cg入门17:Fragment shader - 片段级光照(添加阴影)的主要内容,如果未能解决你的问题,请参考以下文章
Cg入门25: Fragment shader – UV动画(模糊)
Cg入门24: Fragment shader – UV动画(波纹)
Cg入门21:Fragment shader - 2D纹理采样
Cg入门16:Fragment shader - 片段级光照