HDRP shader 获取阴影(Custom Pass)

本文详细介绍了如何在Unity 2021.3.0f1的HDRP中使用LightLoop进行自定义全屏通道,包括调整直接光阴影、去除背面阴影、添加聚光灯并实现黑白着色效果。通过创建CustomHDShadowLoop hlsl文件,作者分享了修改HDRISky.shader的步骤和关键代码片段,以实现实时阴影效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

环境

Unity:2021.3.0f1
HDRP:12.1.6
以下程序均在 自定义全屏通道 中运行,详情

示例场景如图
在这里插入图片描述

直接光阴影

应该可能是这么写吧(代码出处是Lighting\LightLoop\LightLoop.hlsl

#pragma multi_compile SHADOW_LOW SHADOW_MEDIUM SHADOW_HIGH SHADOW_VERY_HIGH
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/NormalBuffer.hlsl"

#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/PunctualLightCommon.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/HDShadow.hlsl"
NormalData normalData;
DecodeFromNormalBuffer(posInput.positionSS, normalData);

HDShadowContext shadowContext = InitShadowContext();

DirectionalLightData light = _DirectionalLightDatas[_DirectionalShadowIndex];
float3 L = -light.forward;
float3 shadow = GetDirectionalShadowAttenuation(shadowContext,
					posInput.positionSS, posInput.positionWS, normalData.normalWS,
					light.shadowIndex, L);

在这里插入图片描述

去掉背面的影子

这个效果不太对劲,不过显然物体背面是接受不到影子的(毕竟照不到光),所以索性去掉背面的阴影。

shadow = dot(normalData.normalWS, L) < 0 ? 1 : shadow;

在这里插入图片描述

着色

确实是剩下影子了,不过这样看有点怪怪,所以这里来给这幅图加一个黑白版lambert着色。

// shadow = dot(normalData.normalWS, L) < 0 ? 1 : shadow;
shadow *= saturate(dot(normalData.normalWS, L));

在这里插入图片描述

所有光源

为做示例,这里加了一盏聚光灯。
在这里插入图片描述

另一个API

额外添加 #define 和 #include

#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/NormalBuffer.hlsl"

#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/PunctualLightCommon.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/HDShadow.hlsl"

// 添加以下内容
#define LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoopDef.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/HDShadowLoop.hlsl"

如下修改代码(代码出处是Sky\HDRISky\HDRISky.shader

NormalData normalData;
DecodeFromNormalBuffer(posInput.positionSS, normalData);

HDShadowContext shadowContext = InitShadowContext();

// 注释以下几行
// DirectionalLightData light = _DirectionalLightDatas[_DirectionalShadowIndex];
// float3 L = -light.forward;
// float3 shadow = GetDirectionalShadowAttenuation(shadowContext,
//                         posInput.positionSS, posInput.positionWS, normalData.normalWS,
//                         light.shadowIndex, L);
// shadow = saturate(dot(normalData.normalWS, L));

float3 shadow3;
ShadowLoopMin(shadowContext, posInput, normalData.normalWS, 
		LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_AREA, 
		DEFAULT_LIGHT_LAYERS, shadow3);
float3 shadow = dot(shadow3, float3(1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0));

![在这里插入图片描述](https://img-blog.csdnimg.cn/2723d58649b54bedab64eb4bb0ef064b.png在这里插入图片描述

可以看到,聚光灯的影子已经出来了,不过物体背面的影子也出来了,下面继续修改,在这里也来加一个黑白版lambert着色。

创建 CustomHDShadowLoop.hlsl

在你上面写的着色器的同目录下新建一个文件,命名为CustomHDShadowLoop.hlsl
在这里插入图片描述
HDShadowLoop.hlsl 的所有内容拷贝到 CustomHDShadowLoop.hlsl

HDShadowLoop.hlsl 的完整路径大概是在:
“你的项目\Library\PackageCache\com.unity.render-pipelines.high-definition@12.1.6\Runtime\Lighting\LightLoop\HDShadowLoop.hlsl”

在这里插入图片描述

修改 CustomHDShadowLoop.hlsl
  1. 在文件最顶上,把 #define SHADOW_LOOP_AVERAGE去除注释
    在这里插入图片描述
  2. 搜索 GetDirectionalShadowAttenuation,并添加代码
shadowD *= saturate(dot(normalWS, wi));

在这里插入图片描述

  1. 搜索 GetPunctualShadowAttenuation,并添加代码
shadowP *= saturate(dot(normalWS, L));

在这里插入图片描述

  1. 最后回去你自己的着色器,修改一下头文件
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/NormalBuffer.hlsl"
    
#define LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/PunctualLightCommon.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/HDShadow.hlsl"

#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoopDef.hlsl"
// 注释掉这行
// #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/HDShadowLoop.hlsl"
// 改成引用刚刚新建的文件
#include "CustomHDShadowLoop.hlsl"

效果就出来了捏
在这里插入图片描述

参考

  1. SebLagarde-HDRP getting shadow attenuation-https://forum.unity.com/threads/hdrp-getting-shadow-attenuation.863620/
  2. Material\Lit\Lit.shader 中的 “Forward” Pass(毕竟自定义通道似乎都是向前渲染来着…)

抛砖引玉,恳请批评指正!

### HDRP Shader 的语法规则概述 HDRP(High Definition Render Pipeline)是一种高级渲染管线,专为高质量视觉效果设计。其Shader语法相较于传统Unity Shader有一些独特之处,主要体现在对材质属性的支持、光照模型的定义以及性能优化方面。 #### 1. **HDRP Shader 的基本结构** HDRP Shader 文件通常由 `SubShader` 和 `Pass` 组成,其中每个 Pass 定义了一种特定的渲染行为。HDRP 中引入了新的标签和关键字,这些内容主要用于指定渲染队列、混合模式以及其他渲染特性[^2]。 ```hlsl Shader "Custom/HDRPExample" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderPipeline"="HDRenderPipeline" "RenderType"="Opaque" } Pass { HLSLPROGRAM #pragma vertex vert #pragma fragment frag // Include necessary files for HD rendering #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/Core.hlsl" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; v2f vert(appdata v) { v2f o; o.vertex = TransformObjectToHDClip(v.vertex); o.uv = v.uv; return o; } half4 frag(v2f i) : SV_Target { half4 col = tex2D(_MainTex, i.uv); return col; } ENDHLSL } } } ``` 上述代码展示了如何创建一个简单的 HDRP Shader。注意以下几点: - 使用了 `TransformObjectToHDClip` 函数来进行坐标转换[^1]。 - 包含了 HDRP 特定的核心库文件 `Core.hlsl`,这提供了许多预定义函数和支持[^3]。 --- #### 2. **HDRP Shader 的核心概念** ##### (1)**Material Attributes** HDRP 支持多种材质属性,例如 Base Color、Specular、Metallic 等。这些属性可以通过 `Properties` 块进行声明并映射到材质编辑器中。 ##### (2)**Lighting Model** HDRP 提供了 PBR(Physically Based Rendering)光照模型支持,默认情况下会应用基于物理特性的反射率计算方法。开发者也可以自定义光照模型以满足特殊需求。 ##### (3)**Tags and Keywords** 为了兼容 HDRP 渲染管线,在编写 Shader 时需设置 `"RenderPipeline"` 标签为 `"HDRenderPipeline"`。此外还可以通过关键词控制不同的渲染路径或状态。 --- #### 3. **推荐的学习资源与工具** 对于初学者来说,除了掌握基础语法外,还需要熟悉 Unity 官方文档中的相关内容。以下是几个重要的参考资料: - **官方文档**: [Unity HDRP Documentation](https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@latest/) - **Shader Graph 工具**: 自 Unity 2018.1 起推出的可视化 Shader 编辑器能够显著降低入门门槛。 如果倾向于手动编码,则建议阅读有关 HLSL 的书籍或者在线教程,因为大部分现代图形编程都依赖于这种语言。 --- #### 4. **常见注意事项** - 在开发过程中要特别留意性能问题,尤其是当项目规模较大时。合理配置纹理分辨率、减少不必要的计算操作都是提高效率的有效手段。 - 测试阶段应充分考虑目标平台硬件能力差异带来的影响。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值