浏览代码

Move ambient occlusion code from LightingLoopContext to lit.hlsl

- rename ltc_linear_clamp_sampler and ltc_trilinear_clamp_sampler to
s_linear_clamp_sampler and s_trilinear_clamp_sampler
- remove ambient occlusion from LightingLoopContext as it should not be
here, and move it to EvalutePostBSDF
/Yibing-Project-2
Sebastien Lagarde 7 年前
当前提交
a0915eb9
共有 5 个文件被更改,包括 60 次插入45 次删除
  1. 13
      ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs.hlsl
  2. 4
      ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugFullScreen.shader
  3. 10
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.hlsl
  4. 7
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl
  5. 71
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl

13
ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs.hlsl


#define FULLSCREENDEBUGMODE_NONE (0)
#define FULLSCREENDEBUGMODE_MIN_LIGHTING_FULL_SCREEN_DEBUG (1)
#define FULLSCREENDEBUGMODE_SSAO (2)
#define FULLSCREENDEBUGMODE_SSAOBEFORE_FILTERING (3)
#define FULLSCREENDEBUGMODE_DEFERRED_SHADOWS (4)
#define FULLSCREENDEBUGMODE_MAX_LIGHTING_FULL_SCREEN_DEBUG (5)
#define FULLSCREENDEBUGMODE_MIN_RENDERING_FULL_SCREEN_DEBUG (6)
#define FULLSCREENDEBUGMODE_MOTION_VECTORS (7)
#define FULLSCREENDEBUGMODE_NAN_TRACKER (8)
#define FULLSCREENDEBUGMODE_MAX_RENDERING_FULL_SCREEN_DEBUG (9)
#define FULLSCREENDEBUGMODE_DEFERRED_SHADOWS (3)
#define FULLSCREENDEBUGMODE_MAX_LIGHTING_FULL_SCREEN_DEBUG (4)
#define FULLSCREENDEBUGMODE_MIN_RENDERING_FULL_SCREEN_DEBUG (5)
#define FULLSCREENDEBUGMODE_MOTION_VECTORS (6)
#define FULLSCREENDEBUGMODE_NAN_TRACKER (7)
#define FULLSCREENDEBUGMODE_MAX_RENDERING_FULL_SCREEN_DEBUG (8)
#endif

4
ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugFullScreen.shader


{
return 1.0f - SAMPLE_TEXTURE2D(_DebugFullScreenTexture, sampler_DebugFullScreenTexture, input.texcoord).xxxx;
}
if (_FullScreenDebugMode == FULLSCREENDEBUGMODE_SSAOBEFORE_FILTERING)
{
return 1.0f - SAMPLE_TEXTURE2D(_DebugFullScreenTexture, sampler_DebugFullScreenTexture, input.texcoord).xxxx;
}
if (_FullScreenDebugMode == FULLSCREENDEBUGMODE_NAN_TRACKER)
{
#if UNITY_UV_STARTS_AT_TOP

10
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.hlsl


TEXTURECUBE(_SkyTexture);
SAMPLERCUBE(sampler_SkyTexture); // NOTE: Sampler could be share here with _EnvTextures. Don't know if the shader compiler will complain...
TEXTURE2D(_AmbientOcclusionTexture);
TEXTURE2D(_DeferredShadowTexture);
CBUFFER_START(UnityPerLightLoop)

float4 _DirShadowSplitSpheres[4]; // TODO: share this max between C# and hlsl
int _EnvLightSkyEnabled; // TODO: make it a bool
float _AmbientOcclusionDirectLightStrenght;
// LightLoopContext is not visible from Material (user should not use these properties in Material file)
// It allow the lightloop to have transmit sampling information (do we use atlas, or texture array etc...)
// Visible from Material - these values are expected in any LightLoopContext
float indirectAmbientOcclusion; // Ambient occlusion use for indirect lighting (reflection probe, baked diffuse lighting)
float directAmbientOcclusion; // Ambient occlusion use for direct lighting (directional, punctual, area)
// Not visible from Material (user should not use these properties in Material file)
int sampleReflection;
ShadowContext shadowContext;
};

7
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl


out float3 specularLighting)
{
LightLoopContext context;
// 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
context.indirectAmbientOcclusion = 1.0 - LOAD_TEXTURE2D(_AmbientOcclusionTexture, posInput.unPositionSS).x;
context.directAmbientOcclusion = lerp(1.0, context.indirectAmbientOcclusion, _AmbientOcclusionDirectLightStrenght);
context.sampleReflection = 0;
context.shadowContext = InitShadowContext();

// Also Apply indiret diffuse (GI)
// PostEvaluateBSDF will perform any operation wanted by the material and sum everything into diffuseLighting and specularLighting
PostEvaluateBSDF( context, preLightData, bsdfData, accLighting, bakeDiffuseLighting,
PostEvaluateBSDF( context, V, posInput, preLightData, accLighting, bsdfData, bakeDiffuseLighting,
diffuseLighting, specularLighting);
ApplyDebug(context, posInput.positionWS, diffuseLighting, specularLighting);

71
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


// TODO: Test if this is a win
// #define LIT_USE_BSDF_PRE_LAMBDAV
// Sampler use by area light, gaussian pyramid, ambient occlusion etc...
SamplerState s_linear_clamp_sampler;
SamplerState s_trilinear_clamp_sampler;
// Rough refraction texture
// Color pyramid (width, height, lodcount, Unused)
float4 _GaussianPyramidColorMipSize;
TEXTURE2D(_GaussianPyramidColorTexture);

TEXTURE2D(_PyramidDepthTexture);
// Area light textures specific constant
SamplerState ltc_linear_clamp_sampler;
SamplerState ltc_trilinear_clamp_sampler;
// Ambient occlusion texture
TEXTURE2D(_AmbientOcclusionTexture);
float _AmbientOcclusionDirectLightStrenght;
// Area light textures
// TODO: This one should be set into a constant Buffer at pass frequency (with _Screensize)
TEXTURE2D(_PreIntegratedFGD);
TEXTURE2D_ARRAY(_LtcData); // We pack the 3 Ltc data inside a texture array

#define LTC_LUT_SCALE ((LTC_LUT_SIZE - 1) * rcp(LTC_LUT_SIZE))
#define LTC_LUT_OFFSET (0.5 * rcp(LTC_LUT_SIZE))
#define MIN_N_DOT_V 0.0001 // The minimum value of 'NdotV'
// Subsurface scattering specific constant
// Subsurface scattering constant
#define SSS_WRAP_ANGLE (PI/12) // Used for wrap lighting
#define SSS_WRAP_LIGHT cos(PI/2 - SSS_WRAP_ANGLE)

float4 _TransmissionTints[SSS_N_PROFILES]; // RGB = 1/4 * color, A = unused
CBUFFER_END
// General constant
#define MIN_N_DOT_V 0.0001 // The minimum value of 'NdotV'
//-----------------------------------------------------------------------------
// Ligth and material classification for the deferred rendering path
// Configure what kind of combination is supported

// _PreIntegratedFGD.y = Gv * Fc
// Pre integrate DisneyDiffuse FGD:
// _PreIntegratedFGD.z = DisneyDiffuse
float3 preFGD = SAMPLE_TEXTURE2D_LOD(_PreIntegratedFGD, ltc_linear_clamp_sampler, float2(NdotV, perceptualRoughness), 0).xyz;
float3 preFGD = SAMPLE_TEXTURE2D_LOD(_PreIntegratedFGD, s_linear_clamp_sampler, float2(NdotV, perceptualRoughness), 0).xyz;
// f0 * Gv * (1 - Fc) + Gv * Fc
specularFGD = fresnel0 * preFGD.x + preFGD.y;

// Note we load the matrix transpose (avoid to have to transpose it in shader)
preLightData.ltcXformClearCoat = 0.0;
preLightData.ltcXformClearCoat._m22 = 1.0;
preLightData.ltcXformClearCoat._m00_m02_m11_m20 = SAMPLE_TEXTURE2D_ARRAY_LOD(_LtcData, ltc_linear_clamp_sampler, uv, LTC_GGX_MATRIX_INDEX, 0);
preLightData.ltcXformClearCoat._m00_m02_m11_m20 = SAMPLE_TEXTURE2D_ARRAY_LOD(_LtcData, s_linear_clamp_sampler, uv, LTC_GGX_MATRIX_INDEX, 0);
float3 ltcMagnitude = SAMPLE_TEXTURE2D_ARRAY_LOD(_LtcData, ltc_linear_clamp_sampler, uv, LTC_MULTI_GGX_FRESNEL_DISNEY_DIFFUSE_INDEX, 0).rgb;
float3 ltcMagnitude = SAMPLE_TEXTURE2D_ARRAY_LOD(_LtcData, s_linear_clamp_sampler, uv, LTC_MULTI_GGX_FRESNEL_DISNEY_DIFFUSE_INDEX, 0).rgb;
float ltcClearCoatFresnelMagnitudeDiff = ltcMagnitude.r; // The difference of magnitudes of GGX and Fresnel
float ltcClearCoatFresnelMagnitude = ltcMagnitude.g;
preLightData.ltcClearCoatFresnelTerm = preLightData.coatFresnel0 * ltcClearCoatFresnelMagnitudeDiff + ltcClearCoatFresnelMagnitude;

// Get the inverse LTC matrix for Disney Diffuse
preLightData.ltcTransformDiffuse = 0.0;
preLightData.ltcTransformDiffuse._m22 = 1.0;
preLightData.ltcTransformDiffuse._m00_m02_m11_m20 = SAMPLE_TEXTURE2D_ARRAY_LOD(_LtcData, ltc_linear_clamp_sampler, uv, LTC_DISNEY_DIFFUSE_MATRIX_INDEX, 0);
preLightData.ltcTransformDiffuse._m00_m02_m11_m20 = SAMPLE_TEXTURE2D_ARRAY_LOD(_LtcData, s_linear_clamp_sampler, uv, LTC_DISNEY_DIFFUSE_MATRIX_INDEX, 0);
#endif
// Get the inverse LTC matrix for GGX

preLightData.ltcTransformSpecular._m00_m02_m11_m20 = SAMPLE_TEXTURE2D_ARRAY_LOD(_LtcData, ltc_linear_clamp_sampler, uv, LTC_GGX_MATRIX_INDEX, 0);
preLightData.ltcTransformSpecular._m00_m02_m11_m20 = SAMPLE_TEXTURE2D_ARRAY_LOD(_LtcData, s_linear_clamp_sampler, uv, LTC_GGX_MATRIX_INDEX, 0);
// Construct a right-handed view-dependent orthogonal basis around the normal
preLightData.orthoBasisViewNormal[0] = normalize(V - bsdfData.normalWS * preLightData.NdotV);

float3 ltcMagnitude = SAMPLE_TEXTURE2D_ARRAY_LOD(_LtcData, ltc_linear_clamp_sampler, uv, LTC_MULTI_GGX_FRESNEL_DISNEY_DIFFUSE_INDEX, 0).rgb;
float3 ltcMagnitude = SAMPLE_TEXTURE2D_ARRAY_LOD(_LtcData, s_linear_clamp_sampler, uv, LTC_MULTI_GGX_FRESNEL_DISNEY_DIFFUSE_INDEX, 0).rgb;
float ltcGGXFresnelMagnitudeDiff = ltcMagnitude.r; // The difference of magnitudes of GGX and Fresnel
float ltcGGXFresnelMagnitude = ltcMagnitude.g;
float ltcDisneyDiffuseMagnitude = ltcMagnitude.b;

|| any(refractedBackPointSS < 0.0)
|| any(refractedBackPointSS > 1.0))
{
diffuseLighting = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, ltc_trilinear_clamp_sampler, posInput.positionSS, 0.0).rgb;
diffuseLighting = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, s_trilinear_clamp_sampler, posInput.positionSS, 0.0).rgb;
diffuseLighting = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, ltc_trilinear_clamp_sampler, refractedBackPointSS, mipLevel).rgb;
diffuseLighting = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, s_trilinear_clamp_sampler, refractedBackPointSS, mipLevel).rgb;
// Beer-Lamber law for absorption
float3 transmittance = exp(-bsdfData.absorptionCoefficient * opticalDepth);

// Use perfect flat transparency when we cannot fetch the correct pixel color for the refracted point
diffuseLighting = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, ltc_trilinear_clamp_sampler, posInput.positionSS, 0.0).rgb;
diffuseLighting = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, s_trilinear_clamp_sampler, posInput.positionSS, 0.0).rgb;
#endif
}

// PostEvaluateBSDF
// ----------------------------------------------------------------------------
void PostEvaluateBSDF( LightLoopContext lightLoopContext, PreLightData preLightData, BSDFData bsdfData, LightLoopAccumulatedLighting accLighting, float3 bakeDiffuseLighting,
void PostEvaluateBSDF( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, LightLoopAccumulatedLighting accLighting, BSDFData bsdfData, float3 bakeDiffuseLighting,
// Use GTAOMultiBounce approximation for ambient occlusion (allow to get a tint from the baseColor)
#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)
float indirectAmbientOcclusion = 1.0 - LOAD_TEXTURE2D(_AmbientOcclusionTexture, posInput.unPositionSS).x;
// Ambient occlusion use for direct lighting (directional, punctual, area)
float directAmbientOcclusion = lerp(1.0, indirectAmbientOcclusion, _AmbientOcclusionDirectLightStrenght);
bakeDiffuseLighting *= GTAOMultiBounce(lightLoopContext.indirectAmbientOcclusion, bsdfData.diffuseColor);
#if GTAO_MULTIBOUNCE_APPROX
bakeDiffuseLighting *= GTAOMultiBounce(indirectAmbientOcclusion, bsdfData.diffuseColor);
#else
bakeDiffuseLighting *= indirectAmbientOcclusion;
#endif
float specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(preLightData.NdotV, lightLoopContext.indirectAmbientOcclusion, bsdfData.roughness);
float specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(preLightData.NdotV, indirectAmbientOcclusion, bsdfData.roughness);
#if GTAO_MULTIBOUNCE_APPROX
#else
accLighting.envSpecularLighting *= min(bsdfData.specularOcclusion, specularOcclusion);
#endif
// envDiffuseLighting is used for refraction
diffuseLighting = accLighting.envDiffuseLighting * accLighting.envDiffuseLightingWeight + (1.0 - accLighting.envDiffuseLightingWeight) * ((accLighting.dirDiffuseLighting + accLighting.punctualDiffuseLighting + accLighting.areaDiffuseLighting) * GTAOMultiBounce(lightLoopContext.directAmbientOcclusion, bsdfData.diffuseColor) + bakeDiffuseLighting);
float3 directDiffuseLighting = (accLighting.dirDiffuseLighting + accLighting.punctualDiffuseLighting + accLighting.areaDiffuseLighting) * GTAOMultiBounce(directAmbientOcclusion, bsdfData.diffuseColor);
// envDiffuseLighting is used for refraction in this Lit material. Use the weight to balance between transmission and reflection
diffuseLighting = lerp(directDiffuseLighting + bakeDiffuseLighting, accLighting.envDiffuseLighting, accLighting.envDiffuseLightingWeight);
specularLighting = accLighting.dirSpecularLighting + accLighting.punctualSpecularLighting + accLighting.areaSpecularLighting + accLighting.envSpecularLighting;
}
正在加载...
取消
保存