您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
315 行
7.3 KiB
315 行
7.3 KiB
Shader "Hidden/DigitalHuman/NormalBufferBlurPass"
|
|
{
|
|
Properties
|
|
{
|
|
[HideInInspector] _StencilBit("_StencilBit", Int) = 4
|
|
}
|
|
|
|
HLSLINCLUDE
|
|
#pragma target 4.5
|
|
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/NormalBuffer.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl"
|
|
|
|
TEXTURE2D_X(_InputDepth);
|
|
|
|
Texture2D<float> _NormalBufferBlur_Regions;
|
|
Texture2D<float4> _NormalBufferBlur_Decoded;
|
|
|
|
#if defined(PLATFORM_NEEDS_UNORM_UAV_SPECIFIER) && defined(PLATFORM_SUPPORTS_EXPLICIT_BINDING)
|
|
RW_TEXTURE2D_X(unorm float4, _NormalBuffer) : register(u2);
|
|
#else
|
|
RW_TEXTURE2D_X(float4, _NormalBuffer);
|
|
#endif
|
|
|
|
struct SurfaceAttributes
|
|
{
|
|
float3 positionOS : POSITION;
|
|
};
|
|
|
|
struct SurfaceVaryings
|
|
{
|
|
float4 positionCS : SV_POSITION;
|
|
UNITY_VERTEX_OUTPUT_STEREO
|
|
};
|
|
|
|
struct FullScreenAttributes
|
|
{
|
|
uint vertexID : SV_VertexID;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
struct FullScreenVaryings
|
|
{
|
|
float4 positionCS : SV_POSITION;
|
|
float2 texcoord : TEXCOORD0;
|
|
UNITY_VERTEX_OUTPUT_STEREO
|
|
};
|
|
|
|
struct FullScreenOutputs
|
|
{
|
|
float4 dbuffer0 : SV_Target0;
|
|
float4 dbuffer1 : SV_Target1;
|
|
};
|
|
|
|
SurfaceVaryings VertSurface(SurfaceAttributes input)
|
|
{
|
|
SurfaceVaryings output;
|
|
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
|
|
float depthOffset = 0.0002;// world space offset towards camera
|
|
float3 positionWS = TransformObjectToWorld(input.positionOS) - GetViewForwardDir() * depthOffset;
|
|
output.positionCS = TransformWorldToHClip(positionWS);
|
|
return output;
|
|
}
|
|
|
|
float FragSurface_Mark(SurfaceVaryings input) : SV_Target0
|
|
{
|
|
return 0.0;// 0 == interior
|
|
}
|
|
|
|
FullScreenVaryings VertFullScreen(FullScreenAttributes input)
|
|
{
|
|
FullScreenVaryings output;
|
|
UNITY_SETUP_INSTANCE_ID(input);
|
|
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
|
|
output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID);
|
|
output.texcoord = GetFullScreenTriangleTexCoord(input.vertexID);
|
|
return output;
|
|
}
|
|
|
|
float FragFullScreen_CopyDepth(FullScreenVaryings input) : SV_Depth
|
|
{
|
|
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
|
uint2 positionSS = uint2(input.positionCS.xy);
|
|
return _InputDepth[COORD_TEXTURE2D_X(positionSS)].x;
|
|
}
|
|
|
|
[earlydepthstencil]
|
|
float4 FragFullScreen_Decode(FullScreenVaryings input) : SV_Target0
|
|
{
|
|
uint2 positionSS = uint2(input.positionCS.xy);
|
|
float4 normalBuffer = _NormalBuffer[COORD_TEXTURE2D_X(positionSS)];
|
|
|
|
NormalData normalData;
|
|
DecodeFromNormalBuffer(normalBuffer, uint2(0, 0), normalData);
|
|
return float4(normalData.normalWS, normalData.perceptualRoughness);
|
|
}
|
|
|
|
float4 NormalRoughnessRegionalBlur(int2 positionSS)
|
|
{
|
|
const int MAX_EXT = 20;// PACKAGETODO variable?
|
|
const float RCP_MAX_EXT = 1.0 / float(MAX_EXT);
|
|
|
|
// binary search for edge of blur region
|
|
int ext_hi = MAX_EXT;
|
|
int ext_lo = 0;
|
|
while (ext_hi > ext_lo)
|
|
{
|
|
int mid = (ext_lo + ext_hi + 1) >> 1;
|
|
|
|
float4 outside = float4(
|
|
_NormalBufferBlur_Regions[positionSS + int2(-mid, 0)],
|
|
_NormalBufferBlur_Regions[positionSS + int2( mid, 0)],
|
|
_NormalBufferBlur_Regions[positionSS + int2( 0, -mid)],
|
|
_NormalBufferBlur_Regions[positionSS + int2( 0, mid)]);
|
|
|
|
if (any(outside))// if any of the samples are outside the blur region
|
|
ext_hi = mid - 1;
|
|
else
|
|
ext_lo = mid;
|
|
}
|
|
int ext = ext_lo;
|
|
|
|
// gaussian blur within region
|
|
//
|
|
// x^2 + y^2
|
|
// 1 - ---------
|
|
// G(x,y) = ------------ exp 2 sigma^2
|
|
// 2 PI sigma^2
|
|
#define ADJUST_SIGMA
|
|
#ifdef ADJUST_SIGMA
|
|
const float sigma = ext / 1.5 + FLT_EPS;
|
|
#else
|
|
const float sigma = 0.5;
|
|
#endif
|
|
const float rcp_2sigmasq = -1.0 / (2.0 * sigma * sigma);
|
|
const float rcp_2PIsigmasq = 1.0 / (2 * 3.14159265 * sigma * sigma);
|
|
|
|
#ifndef ADJUST_SIGMA
|
|
float rcp_ext = 1.0 / (ext + FLT_EPS);
|
|
float rcp_ext_sq = rcp_ext * rcp_ext;
|
|
#endif
|
|
float4 sum = 0.0;
|
|
float gsum = 0.0;
|
|
|
|
for (int dy = -ext; dy <= ext; dy++)
|
|
{
|
|
for (int dx = -ext; dx <= ext; dx++)
|
|
{
|
|
#ifdef ADJUST_SIGMA
|
|
float dd = (dx * dx + dy * dy);
|
|
#else
|
|
float dd = (dx * dx + dy * dy) * rcp_ext_sq;
|
|
#endif
|
|
float g = rcp_2PIsigmasq * exp(dd * rcp_2sigmasq);
|
|
sum += g * _NormalBufferBlur_Decoded[positionSS + int2(dx, dy)];
|
|
gsum += g;
|
|
}
|
|
}
|
|
|
|
sum.xyz = normalize(sum.xyz);
|
|
sum.a = sum.a / gsum;
|
|
|
|
return sum;// xyz = normalWS, w = smoothness
|
|
}
|
|
|
|
[earlydepthstencil]
|
|
void FragFullScreen_BlurAndEncode(FullScreenVaryings input)
|
|
{
|
|
float4 normalRoughness = NormalRoughnessRegionalBlur(input.positionCS.xy);
|
|
|
|
// write to gbuffer
|
|
NormalData normalData;
|
|
normalData.normalWS = normalRoughness.xyz;
|
|
normalData.perceptualRoughness = normalRoughness.a;
|
|
|
|
float4 normalBuffer;
|
|
EncodeIntoNormalBuffer(normalData, uint2(0, 0), normalBuffer);
|
|
_NormalBuffer[COORD_TEXTURE2D_X(input.positionCS.xy)] = normalBuffer;
|
|
}
|
|
|
|
[earlydepthstencil]
|
|
FullScreenOutputs FragFullScreen_BlurAndEncodeAndDecal(FullScreenVaryings input)
|
|
{
|
|
float4 normalRoughness = NormalRoughnessRegionalBlur(input.positionCS.xy);
|
|
|
|
// write to gbuffer
|
|
NormalData normalData;
|
|
normalData.normalWS = normalRoughness.xyz;
|
|
normalData.perceptualRoughness = normalRoughness.a;
|
|
|
|
float4 normalBuffer;
|
|
EncodeIntoNormalBuffer(normalData, uint2(0, 0), normalBuffer);
|
|
_NormalBuffer[COORD_TEXTURE2D_X(input.positionCS.xy)] = normalBuffer;
|
|
|
|
// write to dbuffer
|
|
FullScreenOutputs output;
|
|
output.dbuffer0 = float4(normalRoughness.xyz * 0.5 + 0.5, 0.0);
|
|
output.dbuffer1 = float4(0, 0, 1.0 - normalRoughness.w, 0.0);
|
|
return output;
|
|
}
|
|
ENDHLSL
|
|
|
|
SubShader
|
|
{
|
|
Tags { "RenderPipeline" = "HDRenderPipeline" }
|
|
|
|
Cull Off
|
|
Blend Off
|
|
|
|
Pass// == 0
|
|
{
|
|
Name "CopyDepth"
|
|
|
|
ZTest Always
|
|
ZWrite On
|
|
|
|
HLSLPROGRAM
|
|
#pragma vertex VertFullScreen
|
|
#pragma fragment FragFullScreen_CopyDepth
|
|
ENDHLSL
|
|
}
|
|
|
|
Pass// == 1
|
|
{
|
|
Name "Mark"
|
|
|
|
ZTest LEqual
|
|
ZWrite Off
|
|
|
|
Stencil
|
|
{
|
|
WriteMask [_StencilBit]
|
|
ReadMask 0
|
|
Ref [_StencilBit]
|
|
Comp Equal
|
|
Pass Replace
|
|
}
|
|
|
|
HLSLPROGRAM
|
|
#pragma vertex VertSurface
|
|
#pragma fragment FragSurface_Mark
|
|
ENDHLSL
|
|
}
|
|
|
|
Pass// == 2
|
|
{
|
|
Name "Decode"
|
|
|
|
ZTest Always
|
|
ZWrite Off
|
|
|
|
Stencil
|
|
{
|
|
ReadMask [_StencilBit]
|
|
Ref [_StencilBit]
|
|
Comp Equal
|
|
Pass Keep
|
|
}
|
|
|
|
HLSLPROGRAM
|
|
#pragma vertex VertFullScreen
|
|
#pragma fragment FragFullScreen_Decode
|
|
ENDHLSL
|
|
}
|
|
|
|
Pass// == 3
|
|
{
|
|
Name "BlurAndEncode"
|
|
|
|
ZTest Always
|
|
ZWrite Off
|
|
|
|
Stencil
|
|
{
|
|
WriteMask [_StencilBit]
|
|
ReadMask [_StencilBit]
|
|
Ref [_StencilBit]
|
|
Comp Equal
|
|
Pass Zero
|
|
}
|
|
|
|
HLSLPROGRAM
|
|
#pragma vertex VertFullScreen
|
|
#pragma fragment FragFullScreen_BlurAndEncode
|
|
ENDHLSL
|
|
}
|
|
|
|
Pass// == 4
|
|
{
|
|
Name "BlurAndEncodeAndDecal"
|
|
|
|
ZTest Always
|
|
ZWrite Off
|
|
|
|
ColorMask RGBA 0
|
|
ColorMask BA 1
|
|
|
|
Stencil
|
|
{
|
|
WriteMask [_StencilBit]
|
|
ReadMask [_StencilBit]
|
|
Ref [_StencilBit]
|
|
Comp Equal
|
|
Pass Zero
|
|
}
|
|
|
|
HLSLPROGRAM
|
|
#pragma vertex VertFullScreen
|
|
#pragma fragment FragFullScreen_BlurAndEncodeAndDecal
|
|
ENDHLSL
|
|
}
|
|
}
|
|
}
|