UnityShader自定义渲染管线LWRP学习第四章阴影部分遗留问题

目录

国外大佬的最终效果图

网上找的总结:

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);
                }

 

就是没有阴影

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

avi9111

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值