支持剔除阴影
使用抖动
近似半透明阴影
在半透明和剔除阴影之间切换
本节是渲染课程的第12节。在前一小节中,学习如何绘制半透明物体,但是对于半透明物体的阴影没有涉及,本节将讲解此知识点。
本节使用的unity版本为:unity5.5.0f3
1 剔除阴影
目前,半透明材质的阴影和不透明物体的阴影一样。这种效果不是我们想要的。
1.1 重构阴影
为了把透明度考虑进去,我们必须在shadow caster通道中访问alpha值。所以我们要采样漫反射贴图。但是,但是对于不透明物体这个采样又不需要。
我目前有两个版本的阴影,一个是立方体阴影,它是对点光源而使用的。另外一个是针对其他光源使用的。为了阅读方便,我们要重构MyShadow这个文件。我们的差值结构体是所有的变体都要使用的,所以要单独提取出来。
struct VertexData
{
float4 position:POSITION;
float3 normal:NORMAL;
};
struct Interpolators
{
float4 position:SV_POSITION;
#if defined(SHADOWS_CUBE)
float3 lightVec:TEXCOORD0;
#endif
};
接下来,我们就要重新写一下vertex program函数,它区分了是否是点光源的阴影,如下:
Interpolators MyShadowVertexProgram(VertexData v)
{
Interpolators i;
#if defined(SHADOWS_CUBE)
i.position = UnityObjectToClipPos(v.position);
i.lightVec = mul(unity_ObjectToWorld, v.position).xyz - _LightPositionRange.xyz;
#else
i.position = UnityClipSpaceShadowCasterPos(v.position.xyz, v.normal);
i.position = UnityApplyLinearShadowBias(i.position);
#endif
return i;
}
同样的,在片段着色器中,也要这样书写:
float4 MyShadowFragmentProgram(Interpolators i):SV_TARGET
{
#if defined(SHADOWS_CUBE)
float depth = length(i.lightVec) + unity_LightShadowBias.x;
depth *= _LightPositionRange.w;
return UnityEncodeCubeShadowDepth(depth);
#else
return 0;
#endif
}