Unity3D的内置宏 REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR

Table of Contents

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com

在Unity URP中,REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR 是一个与阴影计算相关的内置宏(Shader Variant Keyword),它的作用是:


核心含义

控制顶点着色器是否需要生成并传递阴影坐标插值器
当该宏被激活时,Unity会在顶点着色器阶段计算主光源的阴影坐标,并通过顶点着色器输出结构体(Varyings)传递到片元着色器。这使得片元着色器可以直接使用插值后的阴影坐标进行阴影采样,避免在片元阶段重复计算。


触发条件

该宏会自动激活,当以下条件满足时:

  1. 项目中启用了 主光源阴影(Main Light Shadows)
  2. 使用了 逐顶点阴影坐标插值 的优化模式(而非逐片元计算)
  3. 在Shader中通过 #pragma multi_compile 启用了阴影相关功能(例如 _MAIN_LIGHT_SHADOWS

典型应用场景

在URP的Shader中,你会在顶点着色器输出结构体 Varyings 中看到类似代码:

struct Varyings {
    float4 positionCS : SV_POSITION;
    float3 positionWS : TEXCOORD0;
    // 当 REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR 激活时,自动添加阴影坐标字段
    #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
    float4 shadowCoord : TEXCOORD1;
    #endif
};

技术原理

  1. 阴影坐标生成
    顶点着色器通过 GetShadowCoord(vertexInput) 计算阴影坐标,并存储在 shadowCoord 中。

  2. 插值优化
    阴影坐标在顶点阶段计算后,通过插值器传递到片元着色器,减少片元阶段的计算量。

  3. 自动编译控制
    Unity会根据项目设置和Shader特性,在编译时自动决定是否启用该宏,生成不同的Shader变体。


对比其他阴影模式

宏名称 计算阶段 性能消耗 精度
REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR 顶点着色器 较低 中等
REQUIRES_FRAGMENT_SHADOW_COORD_INTERPOLATOR 片元着色器 较高 较高

调试与手动控制

  1. 强制启用/禁用(不推荐)
    在Shader顶部添加以下代码,手动控制宏的状态:

    #define REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR // 强制启用
    // #undef REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR // 强制禁用
    
  2. 查看激活状态
    通过 #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) 判断宏是否生效。

  3. 依赖的Unity配置
    确保以下设置正确:

    • Project Settings > Graphics > URP Asset 中启用 Shadows
    • 光源的 Cast Shadows 属性为开启状态

常见问题解决

问题现象
编译Shader时出现类似错误:

error CS0103: The name 'shadowCoord' does not exist in the current context

解决方案

  1. 检查是否遗漏阴影相关宏定义:
    #pragma multi_compile _ _MAIN_LIGHT_SHADOWS
    #pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
    
  2. 确保在片元着色器中正确获取阴影坐标:
    #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
    float4 shadowCoord = input.shadowCoord;
    #else
    float4 shadowCoord = TransformWorldToShadowCoord(input.positionWS);
    #endif
    

最佳实践

  1. 保持自动管理:通常无需手动操作该宏,依赖Unity的自动编译机制即可。
  2. 性能敏感场景:在移动端项目中,优先使用顶点插值模式(激活该宏)以减少片元计算。
  3. 复杂阴影需求:需要高质量软阴影时,可考虑禁用该宏,改用片元阶段计算。

通过理解这一宏的作用机制,可以更高效地调试URP Shader中的阴影相关问题。

kumakoko avatar
kumakoko
pure coder
comments powered by Disqus