目录
国外大佬的最终效果图
网上找的总结:
ShadowCaster
Shadows.hlsl,而实际,应该是:ShadowSamplingTent.hlsl
搞定渲染阴影的几个步骤
其他错误
缺了_ShadowMap
光线错误
就是没有阴影
国外大佬的最终效果图
网上找的总结:
ShadowCaster
- 通过ScriptableRenderContext的DrawShadows方法渲染ShadowCaster这个pass,写入shadowmap。
- https://docs.unity3d.com/ScriptReference/Rendering.ScriptableRenderContext.DrawShadows.html接口说明在这。
- 实现在ShadowCasterPass
- 顶点shader,主要是做坐标变换,和一般坐标变换不同点,一个是要加上偏移值,偏移值通过_ShadowBias获取,在c#设置。另一个问题是要考虑UNITY_REVERSED_Z。
- 像素shader也比较简单,固定返回0。调用Alpha函数,只是为了做裁剪,配合物体的挖洞效果,如果没定义_ALPHATEST_ON,这个函数调用是没用的,返回的alpha并不会用到。
Shadows.hlsl,而实际,应该是:ShadowSamplingTent.hlsl
(#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Shadow/ShadowSamplingTent.hlsl")
阴影计算的核心文件。重要的函数有以下几个
- SampleShadowmap:看名字就知道这是用来采样shadowmap贴图的。
- ShadowParams这个参数,x是强度,y区分是否软阴影。
- 对于软阴影,SampleShadowmapFiltered函数计算,采样周围像素做混合,周围像素uv通过SampleShadow_ComputeSamples_Tent_5x5计算。
- 超过光源范围的点,返回1,否则返回shadowmap值。
- GetShadowCoord:用于计算主光的级联坐标,在顶点shader调用,结果保存为shadowCoord。
- MainLightRealtimeShadow:计算主光实时阴影,参数是变换为对应级联贴图的坐标。
- AdditionalLightRealtimeShadow:计算附加光源的阴影,每个光源调用一次。
- USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA这个目前没定义,先不看。
- 计算当前像素在阴影图集中的坐标,通过世界坐标乘上_AdditionalLightsWorldToShadow矩阵实现。
总结下来这个文件,做的就是处理主光源的级联阴影和附加光的阴影图集,找到正确的坐标,采样阴影贴图,对软阴影进行多次采样,最后返回正确的阴影值。
搞定渲染阴影的几个步骤
1.搞定ShadowCaster生成Shadowmap
* 有一些条纹噪点
* Shadowmap是红色,而不是灰色
(会出现很多其他问题,而上面2问题已然暂时无解,先做下面的步骤)
2.0 传入ShadowData
float4 _ShadowData[MAX_VISIBLE_LIGHTS];
主要存了两个变量
shadow.x = shadowLight.shadowStrength;
shadow.y = shadowLight.shadows == LightShadows.Soft ? 1f : 0f;
每个灯对应一个ShadowData,很合理,每个Data都有x,y 2个变量,x==阴影强度,y==硬|软阴影(没用,我们只用软的)
2.1 通过方法:SampleShadow_ComputeSamples_Tent_5x5()采样策略设置
参数:
shadowMapTexture_TexelSize
coord
out fetchesWeights[9]
out fetchesUV[9]
3.控制硬阴影还是软阴影,其实很鸡肋,都2021年了,we have to use [软阴影]
控制的宏值得学些一下
4.真正的采样:SAMPLE_TEXTURE2D_SHADOW()
参数:
其他错误
缺了_ShadowMap
本来明明是按照国外大佬的代码照搬的,
发现如果没定义Shadow_Soft,就没法识别_ShadowMap, _MainTex的识别也是时有时无
光线错误
For 循环指向错误,不能用直接 i,必须用 inDices0[i]
很常见的抄程序抄错了
for (int i = 0; i < MAX_VISIBLE_LIGHTS; i++) {
int lightIndex = unity_4LightIndices0[i];
float shadowAttenuation = ShadowAttenuation(lightIndex, input.worldPos);
diffuseLight += DiffuseLight(lightIndex, worldNormal, input.worldPos, shadowAttenuation);
}
就是没有阴影