浏览代码

Merge pull request #1214 from Unity-Technologies/Factore-AmbientOcclusionCode

Factor AmbientOcclusion code
/main
GitHub 7 年前
当前提交
fa4597b9
共有 4 个文件被更改,包括 91 次插入62 次删除
  1. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugFullScreen.shader
  2. 60
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightEvaluation.hlsl
  3. 70
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl
  4. 22
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariables.hlsl

1
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugFullScreen.shader


CBUFFER_END
TEXTURE2D(_DebugFullScreenTexture);
TEXTURE2D(_DepthPyramidTexture);
StructuredBuffer<ScreenSpaceTracingDebug> _DebugScreenSpaceTracingData;
struct Attributes

60
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightEvaluation.hlsl


}
// Environment map share function
#include "Reflection/VolumeProjection.hlsl"
void EvaluateLight_EnvIntersection(float3 positionWS, float3 normalWS, EnvLightData lightData, int influenceShapeType, inout float3 R, inout float weight)

// Smooth weighting
weight = Smoothstep01(weight);
weight *= lightData.weight;
}
}
// Ambient occlusion
struct AmbientOcclusionFactor
{
float3 indirectAmbientOcclusion;
float3 directAmbientOcclusion;
float3 indirectSpecularOcclusion;
};
void GetAmbientOcclusion(float2 positionSS, float NdotV, float perceptualRoughness, float specularOcclusionFromData, out AmbientOcclusionFactor aoFactor)
{
// Note: When we ImageLoad outside of texture size, the value returned by Load is 0 (Note: On Metal maybe it clamp to value of texture which is also fine)
// We use this property to have a neutral value for AO that doesn't consume a sampler and work also with compute shader (i.e use ImageLoad)
// We store inverse AO so neutral is black. So either we sample inside or outside the texture it return 0 in case of neutral
// Ambient occlusion use for indirect lighting (reflection probe, baked diffuse lighting)
#ifndef _SURFACE_TYPE_TRANSPARENT
float indirectAmbientOcclusion = 1.0 - LOAD_TEXTURE2D(_AmbientOcclusionTexture, positionSS).x;
// Ambient occlusion use for direct lighting (directional, punctual, area)
float directAmbientOcclusion = lerp(1.0, indirectAmbientOcclusion, _AmbientOcclusionParam.w);
#else
float indirectAmbientOcclusion = 1.0;
float directAmbientOcclusion = 1.0;
#endif
float roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
float specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(NdotV), indirectAmbientOcclusion, roughness);
aoFactor.indirectAmbientOcclusion = lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), indirectAmbientOcclusion);
aoFactor.directAmbientOcclusion = lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), directAmbientOcclusion);
aoFactor.indirectSpecularOcclusion = lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), min(specularOcclusionFromData, specularOcclusion));
}
void GetAmbientOcclusionMultibounce(float2 positionSS, float NdotV, float perceptualRoughness, float specularOcclusionFromData, float3 diffuseColor, float3 fresnel0, out AmbientOcclusionFactor aoFactor)
{
// Use GTAOMultiBounce approximation for ambient occlusion (allow to get a tint from the diffuseColor)
// Note: When we ImageLoad outside of texture size, the value returned by Load is 0 (Note: On Metal maybe it clamp to value of texture which is also fine)
// We use this property to have a neutral value for AO that doesn't consume a sampler and work also with compute shader (i.e use ImageLoad)
// We store inverse AO so neutral is black. So either we sample inside or outside the texture it return 0 in case of neutral
// Ambient occlusion use for indirect lighting (reflection probe, baked diffuse lighting)
#ifndef _SURFACE_TYPE_TRANSPARENT
float indirectAmbientOcclusion = 1.0 - LOAD_TEXTURE2D(_AmbientOcclusionTexture, positionSS).x;
// Ambient occlusion use for direct lighting (directional, punctual, area)
float directAmbientOcclusion = lerp(1.0, indirectAmbientOcclusion, _AmbientOcclusionParam.w);
#else
float indirectAmbientOcclusion = 1.0;
float directAmbientOcclusion = 1.0;
#endif
float roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
float specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(NdotV), indirectAmbientOcclusion, roughness);
aoFactor.indirectAmbientOcclusion = GTAOMultiBounce(indirectAmbientOcclusion, diffuseColor);
aoFactor.directAmbientOcclusion = GTAOMultiBounce(min(specularOcclusionFromData, specularOcclusion), fresnel0);
aoFactor.indirectSpecularOcclusion = GTAOMultiBounce(directAmbientOcclusion, diffuseColor);
}

70
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl


TEXTURE2D(_GBufferTexture2);
TEXTURE2D(_GBufferTexture3);
// Rough refraction texture
// Color pyramid (width, height, lodcount, Unused)
TEXTURE2D(_ColorPyramidTexture);
// Depth pyramid (width, height, lodcount, Unused)
TEXTURE2D(_DepthPyramidTexture);
CBUFFER_START(UnityLightingParameters)
// Buffer pyramid
float4 _ColorPyramidSize; // (x,y) = Actual Pixel Size, (z,w) = 1 / Actual Pixel Size
float4 _DepthPyramidSize; // (x,y) = Actual Pixel Size, (z,w) = 1 / Actual Pixel Size
float4 _ColorPyramidScale; // (x,y) = Screen Scale, z = lod count, w = unused
float4 _DepthPyramidScale; // (x,y) = Screen Scale, z = lod count, w = unused
// Screen space lighting
float _SSRefractionInvScreenWeightDistance; // Distance for screen space smoothstep with fallback
// Ambiant occlusion
float4 _AmbientOcclusionParam; // xyz occlusion color, w directLightStrenght
CBUFFER_END
// Ambient occlusion texture
TEXTURE2D(_AmbientOcclusionTexture);
// Area light textures
// TODO: This one should be set into a constant Buffer at pass frequency (with _Screensize)
TEXTURE2D(_PreIntegratedFGD);

{
float3 bakeDiffuseLighting = bakeLightingData.bakeDiffuseLighting;
AmbientOcclusionFactor aoFactor;
#define GTAO_MULTIBOUNCE_APPROX 1
// Note: When we ImageLoad outside of texture size, the value returned by Load is 0 (Note: On Metal maybe it clamp to value of texture which is also fine)
// We use this property to have a neutral value for AO that doesn't consume a sampler and work also with compute shader (i.e use ImageLoad)
// We store inverse AO so neutral is black. So either we sample inside or outside the texture it return 0 in case of neutral
// Ambient occlusion use for indirect lighting (reflection probe, baked diffuse lighting)
#ifndef _SURFACE_TYPE_TRANSPARENT
float indirectAmbientOcclusion = 1.0 - LOAD_TEXTURE2D(_AmbientOcclusionTexture, posInput.positionSS).x;
// Ambient occlusion use for direct lighting (directional, punctual, area)
float directAmbientOcclusion = lerp(1.0, indirectAmbientOcclusion, _AmbientOcclusionParam.w);
#if 0
GetAmbientOcclusion(posInput.positionSS, preLightData.NdotV, bsdfData.perceptualRoughness, bsdfData.specularOcclusion, aoFactor);
float indirectAmbientOcclusion = 1.0;
float directAmbientOcclusion = 1.0;
GetAmbientOcclusionMultibounce(posInput.positionSS, preLightData.NdotV, bsdfData.perceptualRoughness, bsdfData.specularOcclusion, bsdfData.diffuseColor, bsdfData.fresnel0, aoFactor);
#if GTAO_MULTIBOUNCE_APPROX
bakeDiffuseLighting *= GTAOMultiBounce(indirectAmbientOcclusion, bsdfData.diffuseColor);
#else
bakeDiffuseLighting *= lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), indirectAmbientOcclusion);
#endif
bakeDiffuseLighting *= aoFactor.indirectAmbientOcclusion;
lighting.indirect.specularReflected *= aoFactor.indirectSpecularOcclusion;
lighting.direct.diffuse *= aoFactor.directAmbientOcclusion;
float roughness = PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness);
float specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(preLightData.NdotV), indirectAmbientOcclusion, roughness);
// Try to mimic multibounce with specular color. Not the point of the original formula but ok result.
// Take the min of screenspace specular occlusion and visibility cone specular occlusion
#if GTAO_MULTIBOUNCE_APPROX
lighting.indirect.specularReflected *= GTAOMultiBounce(min(bsdfData.specularOcclusion, specularOcclusion), bsdfData.fresnel0);
#else
lighting.indirect.specularReflected *= lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), min(bsdfData.specularOcclusion, specularOcclusion));
#endif
lighting.direct.diffuse *=
#if GTAO_MULTIBOUNCE_APPROX
GTAOMultiBounce(directAmbientOcclusion, bsdfData.diffuseColor);
#else
lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), directAmbientOcclusion);
#endif
// Subsurface scattering mdoe
uint texturingMode = (bsdfData.materialFeatures >> MATERIAL_FEATURE_FLAGS_SSS_TEXTURING_MODE_OFFSET) & 3;
float3 modifiedDiffuseColor = ApplySubsurfaceScatteringTexturingMode(texturingMode, bsdfData.diffuseColor);

break;
case DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_OCCLUSION:
diffuseLighting = indirectAmbientOcclusion;
diffuseLighting = aoFactor.indirectAmbientOcclusion;
diffuseLighting = specularOcclusion;
diffuseLighting = aoFactor.indirectSpecularOcclusion;
break;
case DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFRACTION:

22
ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariables.hlsl


float4 _VBufferDepthDecodingParams; // See the call site for description
CBUFFER_END
CBUFFER_START(UnityLightingParameters)
// Buffer pyramid
float4 _ColorPyramidSize; // (x,y) = Actual Pixel Size, (z,w) = 1 / Actual Pixel Size
float4 _DepthPyramidSize; // (x,y) = Actual Pixel Size, (z,w) = 1 / Actual Pixel Size
float4 _ColorPyramidScale; // (x,y) = Screen Scale, z = lod count, w = unused
float4 _DepthPyramidScale; // (x,y) = Screen Scale, z = lod count, w = unused
// Screen space lighting
float _SSRefractionInvScreenWeightDistance; // Distance for screen space smoothstep with fallback
// Ambiant occlusion
float4 _AmbientOcclusionParam; // xyz occlusion color, w directLightStrenght
CBUFFER_END
// Rough refraction texture
// Color pyramid (width, height, lodcount, Unused)
TEXTURE2D(_ColorPyramidTexture);
// Depth pyramid (width, height, lodcount, Unused)
TEXTURE2D(_DepthPyramidTexture);
// Ambient occlusion texture
TEXTURE2D(_AmbientOcclusionTexture);
// Custom generated by HDRP, not from Unity Engine (passed in via HDCamera)
#if defined(USING_STEREO_MATRICES)

正在加载...
取消
保存