Unity shader中TransformWorldToShadowCoord原理解析

TransformWorldToShadowCoord 的核心作用很简单:将你提供的世界坐标,转换到一个可以用于采样 Shadow Map 的坐标空间。它本质上是为你省去了手动编写矩阵乘法的繁琐步骤。

🔍 核心原理:一个"三步走"的幕后过程

函数内部主要执行了以下三个步骤:

  1. 获取矩阵 :获取从"世界空间"转换到"阴影空间"的核心矩阵 unity_WorldToShadow

    • 方向光 :需处理阴影级联(Shadow Cascades),因此是一个包含最多4个矩阵的数组 unity_WorldToShadow[4]

    • 聚光灯/点光源 :通常只用一个矩阵 unity_WorldToLight

  2. 执行变换 :执行矩阵乘法 mul(unity_WorldToShadow[selectedIndex], float4(worldPos, 1.0)),将世界坐标转换到阴影空间的齐次坐标。

  3. 处理齐次坐标 :对于聚光灯点光源 这类透视投影,需要执行透视除法(shadowCoord.xyz / shadowCoord.w),将坐标映射到0-1范围以得到最终的Shadow Map UV坐标;而方向光 由于是正交投影(w 分量为1),则无需此步骤。

此外,函数内部还会根据是否启用级联阴影映射(_MAIN_LIGHT_SHADOWS_CASCADE)进行相应处理。当启用时,它会选择正确的 unity_WorldToShadow 矩阵索引来计算坐标。

💡 一个更直观的理解

你可以将这个过程类比为:

  • TransformWorldToShadowCoord:是一个翻译器,它将物体的世界坐标,翻译成Shadow Map上每个像素点的"门牌号"。

  • Shadow Map:是由光源"拍摄"的深度信息图,记录了场景中每个点离光源的远近。

  • MainLightRealtimeShadow 等采样函数 :拿着翻译出来的"门牌号"(shadowCoord),去Shadow Map这张"地图"上,找到对应的深度信息进行比较,最终判定当前像素点是否处于阴影中。

🔧 实际使用示例

一个典型的URP Shader中接收阴影的流程大致如下:

cs 复制代码
// 1. 在着色器代码中包含必要的头文件并声明编译宏
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE

// ... 顶点着色器中输出世界坐标
VertexPositionInputs vertexInput = GetVertexPositionInputs(IN.positionOS.xyz);
OUT.positionWS = vertexInput.positionWS;

// 2. 在片元着色器中,将世界坐标转换为阴影坐标
float4 shadowCoord = TransformWorldToShadowCoord(IN.positionWS);

// 3. 获取主光源,传入阴影坐标,得到带有阴影衰减值的光源信息
Light mainLight = GetMainLight(shadowCoord);
float3 attenuatedLightColor = mainLight.color * mainLight.shadowAttenuation;

⚠️ 注意事项

  • 宏定义_MAIN_LIGHT_SHADOWS_MAIN_LIGHT_SHADOWS_CASCADE 宏是正确启用功能的"开关",确保它们被正确定义非常重要。

  • 性能考量 :在顶点着色器中计算 shadowCoord 通常更高效(只计算一次),但在顶点动画较多时,为了保证阴影准确,可能需要在片元着色器中计算。

  • 管线差异 :该函数主要适用于URP,Built-in管线通常使用TRANSFER_SHADOW宏,而HDRP则使用 EvalShadow_WorldToShadow 函数。

相关推荐
叶帆5 天前
【YFIOs】用C#开发硬件之设备上云
开发语言·unity·c#
久数君5 天前
AI三维建模工具“造形家”:地理场景三维化的高效解决方案
unity·glb·ai算法·ai三维建模工具·地图框选·造形家·城市建筑模型
会思考的猴子5 天前
Unity VFX 属性 Postion 和 TargetPostion
unity
hai3152475435 天前
九章编程法 · 猜数字游戏 (GW-BASIC 重构版) *
人工智能·microsoft·游戏引擎·游戏程序
心前阳光5 天前
Unity资源导入之自动化资源导入
unity·自动化·游戏引擎
心前阳光5 天前
Unity之2021.3.45f2c1发布安卓程序遇到的问题
android·unity·游戏引擎
纪纯5 天前
PicoVR Unity Integration SDK 3.4 常用交互API
unity·游戏引擎·vr·pico
龙智DevSecOps解决方案5 天前
3A 游戏优化技术栈:如何打通引擎级分析工具与 DevOps 持续集成管线?
unity·性能优化·游戏开发·技术美术·perforce·unrealengine
葛兰岱尔6 天前
从 SolidWorks 到 Three.js,从 Inventor 到 Unity——制造业CAD模型“几何-语义一体化“转换,不再是天方夜谭!
开发语言·javascript·unity
鼎艺创新科技6 天前
三维电子沙盘中OSGB倾斜摄影数据的加载与渲染
游戏引擎·cocos2d