您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
147 行
3.9 KiB
147 行
3.9 KiB
Shader "Hidden/HDPipeline/Lighting/ScreenSpaceAmbientOcclusion"
|
|
{
|
|
HLSLINCLUDE
|
|
|
|
#include "../../../Core/ShaderLibrary/Common.hlsl"
|
|
#include "../../ShaderVariables.hlsl"
|
|
|
|
#define UNITY_MATERIAL_LIT // Needs to be defined before including Material.hlsl
|
|
#include "../../Material/Material.hlsl"
|
|
|
|
DECLARE_GBUFFER_TEXTURE(_GBufferTexture);
|
|
|
|
// The constant below determines the contrast of occlusion. This allows
|
|
// users to control over/under occlusion. At the moment, this is not exposed
|
|
// to the editor because it's rarely useful.
|
|
static const float kContrast = 0.6;
|
|
|
|
// The constant below controls the geometry-awareness of the bilateral
|
|
// filter. The higher value, the more sensitive it is.
|
|
static const float kGeometryCoeff = 0.8;
|
|
|
|
// The constants below are used in the AO estimator. Beta is mainly used
|
|
// for suppressing self-shadowing noise, and Epsilon is used to prevent
|
|
// calculation underflow. See the paper (Morgan 2011 http://goo.gl/2iz3P)
|
|
// for further details of these constants.
|
|
static const float kBeta = 0.002;
|
|
|
|
// A small value used for avoiding self-occlusion.
|
|
static const float kEpsilon = 1e-6;
|
|
|
|
// Interleaved gradient function from Jimenez 2014 http://goo.gl/eomGso
|
|
float GradientNoise(float2 uv)
|
|
{
|
|
uv = floor(uv * _ScreenParams.xy);
|
|
float f = dot(float2(0.06711056, 0.00583715), uv);
|
|
return frac(52.9829189 * frac(f));
|
|
}
|
|
|
|
// Check if the depth value is valid.
|
|
bool CheckDepth(float rawDepth)
|
|
{
|
|
#if defined(UNITY_REVERSED_Z)
|
|
return rawDepth > 0.00001;
|
|
#else
|
|
return rawDepth < 0.99999;
|
|
#endif
|
|
}
|
|
|
|
// AO/normal packed format conversion
|
|
half4 PackAONormal(half ao, half3 n)
|
|
{
|
|
return half4(ao, n * 0.5 + 0.5);
|
|
}
|
|
|
|
half GetPackedAO(half4 p)
|
|
{
|
|
return p.x;
|
|
}
|
|
|
|
half3 GetPackedNormal(half4 p)
|
|
{
|
|
return p.yzw * 2.0 - 1.0;
|
|
}
|
|
|
|
half3 SampleNormal(uint2 unPositionSS)
|
|
{
|
|
float3 unused;
|
|
BSDFData bsdfData;
|
|
FETCH_GBUFFER(gbuffer, _GBufferTexture, unPositionSS);
|
|
DECODE_FROM_GBUFFER(gbuffer, 0xFFFFFFFF, bsdfData, unused);
|
|
return mul((float3x3)unity_WorldToCamera, bsdfData.normalWS);
|
|
}
|
|
|
|
// Normal vector comparer (for geometry-aware weighting)
|
|
half CompareNormal(half3 d1, half3 d2)
|
|
{
|
|
return smoothstep(kGeometryCoeff, 1.0, dot(d1, d2));
|
|
}
|
|
|
|
// Default vertex shader
|
|
struct Attributes
|
|
{
|
|
uint vertexID : SV_VertexID;
|
|
};
|
|
|
|
struct Varyings
|
|
{
|
|
float4 positionCS : SV_POSITION;
|
|
};
|
|
|
|
Varyings Vert(Attributes input)
|
|
{
|
|
Varyings output;
|
|
output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID);
|
|
return output;
|
|
}
|
|
|
|
ENDHLSL
|
|
|
|
SubShader
|
|
{
|
|
Cull Off ZWrite Off ZTest Always
|
|
|
|
// 0: Ambient occlusion estimation
|
|
Pass
|
|
{
|
|
HLSLPROGRAM
|
|
#pragma vertex Vert
|
|
#pragma fragment FragAO
|
|
#include "AOEstimator.hlsl"
|
|
ENDHLSL
|
|
}
|
|
|
|
// 1: Denoising (horizontal pass)
|
|
Pass
|
|
{
|
|
HLSLPROGRAM
|
|
#pragma vertex Vert
|
|
#pragma fragment FragSeparableFilter
|
|
#define SSAO_NOISEFILTER_HORIZONTAL
|
|
#define SSAO_NOISEFILTER_CENTERNORMAL
|
|
#include "NoiseFilter.hlsl"
|
|
ENDHLSL
|
|
}
|
|
|
|
// 2: Denoising (vertical pass)
|
|
Pass
|
|
{
|
|
HLSLPROGRAM
|
|
#pragma vertex Vert
|
|
#pragma fragment FragSeparableFilter
|
|
#define SSAO_NOISEFILTER_VERTICAL
|
|
#include "NoiseFilter.hlsl"
|
|
ENDHLSL
|
|
}
|
|
|
|
// 3: Final filtering
|
|
Pass
|
|
{
|
|
HLSLPROGRAM
|
|
#pragma vertex Vert
|
|
#pragma fragment FragFinalFilter
|
|
#include "NoiseFilter.hlsl"
|
|
ENDHLSL
|
|
}
|
|
}
|
|
}
|