您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
61 行
2.4 KiB
61 行
2.4 KiB
#ifndef UNITY_HDRENDERPIPELINE_SSAO_AOESTIMATOR
|
|
#define UNITY_HDRENDERPIPELINE_SSAO_AOESTIMATOR
|
|
|
|
half _Intensity;
|
|
float _Radius;
|
|
half _Downsample;
|
|
int _SampleCount;
|
|
|
|
float3 SampleInsideHemisphere(float2 uv, half3 norm, int index)
|
|
{
|
|
float gn = GradientNoise(uv * _Downsample);
|
|
float2 u = frac(Hammersley2d(index, _SampleCount) + gn);
|
|
float3 v = SampleSphereUniform(u.x, u.y);
|
|
v *= sqrt((index + 1.0) / _SampleCount) * _Radius;
|
|
return faceforward(v, -norm, v);
|
|
}
|
|
|
|
// Distance-based AO estimator based on Morgan 2011 http://goo.gl/2iz3P
|
|
half4 FragAO(Varyings input) : SV_Target
|
|
{
|
|
PositionInputs posInput = GetPositionInput(input.positionCS.xy / _Downsample, _ScreenSize.zw);
|
|
|
|
// Get normal, depth and view-space position of the center point.
|
|
half3 norm_o = SampleNormal(posInput.unPositionSS);
|
|
|
|
float depth_o_raw = LOAD_TEXTURE2D(_MainDepthTexture, posInput.unPositionSS).x;
|
|
float depth_o = LinearEyeDepth(depth_o_raw, _ZBufferParams);
|
|
|
|
if (!CheckDepth(depth_o_raw)) return PackAONormal(0, norm_o); // TODO: We should use the stencil to not affect the sky
|
|
|
|
float3 vpos_o = ComputeViewSpacePosition(posInput.positionSS, depth_o_raw, _InvProjMatrix);
|
|
|
|
float ao = 0.0;
|
|
|
|
// TODO: Setup several variant based on number of sample count to avoid dynamic loop here
|
|
for (int s = 0; s < _SampleCount; s++)
|
|
{
|
|
// Sample inside the hemisphere defined by the normal.
|
|
float3 vpos_s1 = vpos_o + SampleInsideHemisphere(posInput.positionSS, norm_o, s);
|
|
|
|
// Project the sample point and get the view-space position.
|
|
float2 spos_s1 = float2(dot(unity_CameraProjection[0].xyz, vpos_s1),
|
|
dot(unity_CameraProjection[1].xyz, vpos_s1));
|
|
float2 uv_s1_01 = saturate((spos_s1 / vpos_s1.z + 1.0) * 0.5);
|
|
float depth_s1_raw = LOAD_TEXTURE2D(_MainDepthTexture, uint2(uv_s1_01 * _ScreenSize.xy)).x;
|
|
float3 vpos_s2 = ComputeViewSpacePosition(uv_s1_01, depth_s1_raw, _InvProjMatrix);
|
|
|
|
// Estimate the obscurance value
|
|
float3 v_s2 = vpos_s2 - vpos_o;
|
|
float a1 = max(dot(v_s2, norm_o) - kBeta * depth_o, 0.0);
|
|
float a2 = dot(v_s2, v_s2) + kEpsilon;
|
|
ao += CheckDepth(depth_s1_raw) ? a1 / a2 : 0;
|
|
}
|
|
|
|
// Apply intensity normalization/amplifier/contrast.
|
|
ao = pow(max(0, ao * _Radius * _Intensity / _SampleCount), kContrast);
|
|
|
|
return PackAONormal(ao, norm_o);
|
|
}
|
|
|
|
#endif // UNITY_HDRENDERPIPELINE_SSAO_AOESTIMATOR
|