0基础UnityURP渲染管线之阴影ShadowCaster-ShadowMask-Map傻傻分不清楚(代码向)

本文详细解析了Unity中ShadowMask的原理,包括ShadowCasterPass的作用、阴影的计算方式以及在不同光源类型下的应用。通过代码示例,展示了如何在URP中实现和调整阴影效果,强调了理解代码比理论更重要的实践观念。
摘要由CSDN通过智能技术生成

这里不是说图形学理论,也不是说URP这个分支的区别(另外2个分支:built-in,HDRP),最终还是想说说自定义编程管线(自定义变成相当于,实现一整个渲染引擎),之后会说,但现在也不是说自定义编程的时候

其实下面说的还是HLSL编程,Shader代码(只不过披了一个URP模板的皮)

目录

Unity 的 ShadowMask原理

各种名字,概念傻傻分不清楚

实战Shader阴影”魔改“。。。。??

1.无阴影

2.有阴影

3.阴影又没有了

4.诶,又有了

参考


Unity 的 ShadowMask原理

很多刚接触图形学渲染Renderer,特别是入门工具是Unity的同学,

很容易混淆各种Shadow概念;

第一眼看到这样的代码:Pass{ “ShadowCaster",就先入为主认为这是渲染Shadow的代码

投影的最基本原理就是

1.光源

2.遮挡者(投射源)

3.阴影绘制(Object Render)

 

其实ShadowCaster Pass,就是是投射源(主要是告诉引擎,如何定位,阴影的粒度,是否要偏移,然后引擎在某些时段就会烘培对应阴影贴图);而阴影的绘制和颜色的绘制没差,其实都在ForwardPass(或者DefferPass, 这个下个文章会说到)

void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData)
{
//。。。。。。。。。。。

    inputData.shadowMask = SAMPLE_SHADOWMASK(input.lightmapUV);

因为上面的代码,我们知道,.shadowMask存放在inputData

所以,

half4 UniversalFragmentPBR(InputData inputData, SurfaceData surfaceData)
{
//。。。。。。。
   
// To ensure backward compatibility we have to avoid using shadowMask input, as it is not present in older shaders
#if defined(SHADOWS_SHADOWMASK) && defined(LIGHTMAP_ON)
    half4 shadowMask = inputData.shadowMask;
#elif !defined (LIGHTMAP_ON)
    half4 shadowMask = unity_ProbesOcclusion;
#else
    half4 shadowMask = half4(1, 1, 1, 1);
#endif

    Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, shadowMask);

又由这段代码,我们知道了shadowMask其实是混在了主光(平行光)一同计算的,其实光==1,阴影==0,光++,阴影--;也不是那么难以理解的事情

但是,点光源就不需要阴影了吗?

#ifdef _ADDITIONAL_LIGHTS
    uint pixelLightCount = GetAdditionalLightsCount();
    for (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex)
    {
        Light light = GetAdditionalLight(lightIndex, inputData.positionWS, shadowMask);

由于这段代码,我们也知道了,点光源的阴影和平行光的阴影是一样的

//平行光(其他工具类似的名字:Main Lit,主光源,直接光源)
light.shadowAttenuation = MainLightShadow(shadowCoord, positionWS, shadowMask, _MainLightOcclusionProbes);

//点光源,聚光灯   (其他工具类似的名字:Other Lit,辅助光,间接光源) 
light.shadowAttenuation = AdditionalLightShadow(perObjectLightIndex, positionWS, shadowMask, occlusionProbeChannels);

再看一段代码:

#ifdef CALCULATE_BAKED_SHADOWS
    half bakedShadow = BakedShadow(shadowMask, occlusionProbeChannels);
#else
    half bakedShadow = 1.0h;
#endif

 所以我们知道了 shadowMask只再Baked模式下起作用,也顺带了解了要给关键字:occlusionProbeChannels

各种名字,概念傻傻分不清楚

<具体分析,之后再补上>

结论还是上一个文章的结论:

尽信书不如无书

其实没那么多深奥的道理

掌握了天下的理论(实际上不可能全部掌握),还不如一句代码

实战Shader阴影”魔改“。。。。??

1.无阴影

根据上一个文章的代码(实现了点光源和聚光灯),一个阴影 ??

一开始以为,是这个问题

 后来发现,还是代码(官方)作怪

#if !defined(ADDITIONAL_LIGHT_CALCULATE_SHADOWS)
    return 1.0h;
#endif

 <因为被官方坑了很多次,所以不怎么会浪费时间,直接看代码就好了,都能从代码中找到解决方法>

2.有阴影

// 官方建议的打开宏写法,_ADDITIONAL_LIGHT_SHADOWS_CASCADE不知道什么作用
//#pragma multi_compile _ _MAIN_LIGHT_SHADOWS
//#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE

//#define _ADDITIONAL_LIGHT_SHADOWS_CASCADE
//#define _ADDITIONAL_LIGHT_SHADOWS;

//目测,_ADDITIONAL_LIGHT_SHADOWS开了,就会把ADDITIONAL_LIGHT_CALCULATE_SHADOWS打开
//所以光是 ADDITIONAL_LIGHT_CALCULATE_SHADOWS 也就可以了,_ADDITIONAL_LIGHT_SHADOWS_CASCADE暂时作用不明
#define ADDITIONAL_LIGHT_CALCULATE_SHADOWS 0;
//测试宏是否有打开,需要某付费IDE支持
#if !defined(ADDITIONAL_LIGHT_CALCULATE_SHADOWS)
    abc = 1 //ADDITIONAL_LIGHT_CALCULATE_SHADOWS已定义,所以即使这行错误不完整的代码,也不会报错
#endif
            //Light light = GetAdditionalLight(lightIndex, positionWS);
            float4 shadowMask = SAMPLE_SHADOWMASK(i.uv.zw);//lightmapUV
            Light light = GetAdditionalLight(lightIndex,positionWS,shadowMask);
//现在这个light结构体就会带着阴影信息

3.阴影又没有了

我们改一下,没有了(我们要的?)

 

4.诶,又有了

 

 <最后,你还是发现人物的影音并没有>

这里,有无阴影的区别在于:是否有勾选静态物件,是否MeshRenderer

然而SkinnedMeshRenderer并没有这个选项,《Unity2020》 

 

参考

Unity实时阴影实现——Shadow Mapping - 知乎

Shadowmask vs DistanceShadowmask - Unity Forum

如何在unity的URP下实现阴影_黄琅的博客-CSDN博客_unity urp 阴影

Unity SRP搞事(四)影 - 知乎




 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

avi9111

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

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

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

打赏作者

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

抵扣说明:

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

余额充值