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

Posted avi9111

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了0基础UnityURP渲染管线之阴影ShadowCaster-ShadowMask-Map傻傻分不清楚(代码向)相关的知识,希望对你有一定的参考价值。

这里不是说图形学理论,也不是说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搞事(四)影 - 知乎




 

 

以上是关于0基础UnityURP渲染管线之阴影ShadowCaster-ShadowMask-Map傻傻分不清楚(代码向)的主要内容,如果未能解决你的问题,请参考以下文章

0基础尝试实现UnityURP渲染管线的AdditionalLit(点光源,聚光灯)非平行光的光照模型代码

unityURP管线学习+后处理

深入URP之Shader篇1: URP Shader概述

Unity-默认渲染管线-刻晴卡渲shader

unity渲染管线及升级URP

渲染管线之深度测试与α融合—如何实现同时绘制不透明物体和透明物体