环境
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));
);
- 搜索 GetPunctualShadowAttenuation,并添加代码
shadowP *= saturate(dot(normalWS, L));
- 最后回去你自己的着色器,修改一下头文件
#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"
效果就出来了捏
参考
- SebLagarde-HDRP getting shadow attenuation-https://forum.unity.com/threads/hdrp-getting-shadow-attenuation.863620/
- Material\Lit\Lit.shader 中的 “Forward” Pass(毕竟自定义通道似乎都是向前渲染来着…)
抛砖引玉,恳请批评指正!