- 需要在投射阴影的物体上加一个shadowCaster的pass。
- 顶点着色器中GetShadowPositionHClip转换阴影到投影坐标
- 片元着色器中采样MainTex然根据alpha值和color混合到shadowmap中
- 在接收阴影的场景里的shader
- 首先需要定义对应的变量来接收全局变量的改变,主要有
- _MainLightWorldToShadow
- 从世界坐标转换到阴影坐标的矩阵
- _CascadeShadowSplitSpheres0
- 层叠阴影分割球,用于再需要分割式阴影下(_MAIN_LIGHT_SHADOWS_CASCADE)的各层分割,一共有四层。顶点着色器中计算阴影位置中用。
- _MainLightShadowOffset0
- 阴影图偏移数据,用于手机上实现软阴影的偏移数据
- _MainLightShadowData
- 阴影强度等数据存储,当前只用到了_MainLightShadowData就是阴影的强度信息,通过lwrp的灯光信息决定
- _MainLightShadowmapSize
- 这里记录的是shadowmap的比例,xy记录的是shadowmap的纹素,zw记录的是shadowmap的宽高
- _MainLightWorldToShadow
- 在顶点着色器中用TransformWorldToShadowCoord把顶点的世界坐标转换到阴影坐标系中。
- 在片元着色器中MainLightRealtimeShadow中
- GetMainLightShadowSamplingData把阴影偏移和阴影图的大小保存
- shadowStrength获取的是MainLightShadowData的x坐标
- 主要在SampleShadowmap这里计算阴影衰减值(重要的值)
- 如果是软阴影
- 如果是手机上会执行_ShadowOffset0到_ShadowOffset3这四个阴影图偏移的数值来和当前阴影的纹素相加(相当于把周围的纹理像素采样一边然后除4来完成软阴影效果)注意,采样方式和下面第二点说的SampleCmpLevelZero一样
- 如果不是手机上则拿9个周围的uv贴图信息然后按照指定的权重(5x5的话权重都是0.16)做混合,相当于按照uv周边的信息做叠加。
- 最后:
- 根据shadow贴图和阴影坐标系下的坐标,通过SampleCmpLevelZero(mipmap为0的level中的z值比较)获取到阴影衰减值。
- 如果是软阴影
- 拿到阴影衰减shadowAttenuation后,因为可能阴影颜色需要调整,所以我们需要用正片叠底把颜色混合成需要的效果。
- 首先需要定义对应的变量来接收全局变量的改变,主要有
- 备注:所有的全局变量是再lwrp的MainLightShadowCasterPass.cs中设置的,因为再lwrp中的DefaultRenderSetup中如果支持阴影,会执行MainLightShadowCasterPass类
if (renderingData.shadowData.supportsMainLightShadows)
{
mainLightShadows = m_MainLightShadowCasterPass.Setup(MainLightShadowmap, ref renderingData);
if (mainLightShadows)
renderer.EnqueuePass(m_MainLightShadowCasterPass);
}
设置他的值是
cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowOffset0, new Vector4(-invHalfShadowAtlasWidth, -invHalfShadowAtlasHeight, 0.0f, 0.0f));
cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowOffset1, new Vector4(invHalfShadowAtlasWidth, -invHalfShadowAtlasHeight, 0.0f, 0.0f));
cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowOffset2, new Vector4(-invHalfShadowAtlasWidth, invHalfShadowAtlasHeight, 0.0f, 0.0f));
cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowOffset3, new Vector4(invHalfShadowAtlasWidth, invHalfShadowAtlasHeight, 0.0f, 0.0f));
cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowmapSize, new Vector4(invShadowAtlasWidth, invShadowAtlasHeight,
shadowData.mainLightShadowmapWidth, shadowData.mainLightShadowmapHeight));
效果:
Shadowmap
其他设置相关: