From d120b55256ca9e7c7dc6be42d4138fcbb4a8ba4f Mon Sep 17 00:00:00 2001 From: slunity Date: Thu, 8 Apr 2021 23:56:26 -0400 Subject: [PATCH 01/12] Lit: Improve SSR light hierarchy usage when the coat is used. Improve coatmask usage consistency between forward and deferred. --- .../ScreenSpaceLighting.hlsl | 7 ++++- .../Runtime/Material/Lit/Lit.hlsl | 26 ++++++++++--------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceLighting.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceLighting.hlsl index 08313742c43..64267476006 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceLighting.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceLighting.hlsl @@ -6,6 +6,11 @@ float EdgeOfScreenFade(float2 coordNDC, float fadeRcpLength) return Smoothstep01(t.x) * Smoothstep01(t.y); } +bool HasClearCoatMask(float coatMask) +{ + return coatMask > 0.001; // If coat mask is positive, it means we're using the clear coat +} + // Function that unpacks and evaluates the clear coat mask // packedMask must be the value of GBuffer2 alpha. // Caution: This need to be in sync with Lit.hlsl code @@ -17,5 +22,5 @@ bool HasClearCoatMask(float4 packedMask) float coatMask; uint materialFeatureId; UnpackFloatInt8bit(packedMask.a, 8, coatMask, materialFeatureId); - return coatMask > 0.001; // If coat mask is positive, it mean we use clear coat + return HasClearCoatMask(coatMask); } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl index 88fa98058dc..679d8f35330 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl @@ -361,7 +361,7 @@ NormalData ConvertSurfaceDataToNormalData(SurfaceData surfaceData) // If the fragment that we are processing has clear cloat, we want to export the clear coat's perceptual roughness and geometric normal // instead of the base layer's roughness and the shader normal to be use by SSR #if (SHADERPASS == SHADERPASS_DEPTH_ONLY) || (SHADERPASS == SHADERPASS_MOTION_VECTORS) || (SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS) - if (HasFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT)) + if (HasFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT) && HasClearCoatMask(surfaceData.coatMask)) { normalData.normalWS = surfaceData.geomNormalWS; normalData.perceptualRoughness = CLEAR_COAT_PERCEPTUAL_ROUGHNESS; @@ -1805,21 +1805,23 @@ IndirectLighting EvaluateBSDF_ScreenSpaceReflection(PositionInputs posInput, ApplyScreenSpaceReflectionWeight(ssrLighting); // TODO: we should multiply all indirect lighting by the FGD value only ONCE. - // In case this material has a clear coat, we shou not be using the specularFGD. The condition for it is a combination - // of a materia feature and the coat mask. - float clampedNdotV = ClampNdotV(preLightData.NdotV); - float F = F_Schlick(CLEAR_COAT_F0, clampedNdotV); - lighting.specularReflected = ssrLighting.rgb * (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT) ? - lerp(preLightData.specularFGD, F, bsdfData.coatMask) - : preLightData.specularFGD); + // In case this material has a clear coat, we should not be using the base specularFGD. The condition for it is a combination + // of a material feature and the coat mask. + // Also note that we dont attenuate the reflection hierarchy consumed when coat feature is on but mask is 0: this mirrors what happens + // on the SSR-RTR sampling side, which uses the mask to sample either according to coat roughness or base roughness. + bool coatUsed = HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT) && HasClearCoatMask(bsdfData.coatMask); + lighting.specularReflected = ssrLighting.rgb * (coatUsed ? preLightData.coatIblF : preLightData.specularFGD); // Set the default weight value - reflectionHierarchyWeight = ssrLighting.a; + reflectionHierarchyWeight = ssrLighting.a; // In case this is a clear coat material, we only need to add to the reflectionHierarchyWeight the amount of energy that the clear coat has already // provided to the indirect specular lighting. That would be reflectionHierarchyWeight * F (if has a coat mask). In the environement lighting, - // we do something similar. The base layer coat is multiplied by (1-coatF)^2, but that we cannot do as we have no lighting to provid for the base layer. - if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT)) - reflectionHierarchyWeight = lerp(reflectionHierarchyWeight, reflectionHierarchyWeight * F, bsdfData.coatMask); + // we do something similar. The base layer is multiplied by (1-coatF)^2, but here we have no lighting to provide for the base layer, so instead, + // we leave some room in the hierarchyWeight so there is possibility to use the fallback probes later called in EvaluateBSDF_Env(). + // The drawback is that the coat will still be evaluated by those, possibly incorrectly adding again coat lighting. + if (coatUsed) + //reflectionHierarchyWeight *= 1 - Sq(1 - preLightData.coatIblF); + reflectionHierarchyWeight *= preLightData.coatIblF; return lighting; } From fd4e6eb14a73d3f279c3133a0783c3c28a1449c7 Mon Sep 17 00:00:00 2001 From: slunity Date: Fri, 9 Apr 2021 00:01:39 -0400 Subject: [PATCH 02/12] StackLit SSR-RTR: Correctly mimick what Lit does on master currently: non lerped light sampling parameters formulation (here fed from normaldata) but lerped both FGD and reflectionHierarchyWeight headroom left with coatmask. --- .../Runtime/Material/StackLit/StackLit.hlsl | 31 +++++++------------ 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLit.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLit.hlsl index 3b81107267f..be174879a48 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLit.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLit.hlsl @@ -626,13 +626,10 @@ NormalData ConvertSurfaceDataToNormalData(SurfaceData surfaceData) // When using clear cloat we want to use the coat normal for the various deferred effect // as it is the most dominant one - if (HasFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_COAT)) + if (HasFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_COAT) && (surfaceData.coatMask > 0)) { - float hasCoat = saturate(surfaceData.coatMask * FLT_MAX); - normalData.normalWS = lerp(surfaceData.coatNormalWS, surfaceData.normalWS, hasCoat); - normalData.perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(lerp(lerp(surfaceData.perceptualSmoothnessA, surfaceData.perceptualSmoothnessB, surfaceData.lobeMix), - surfaceData.coatPerceptualSmoothness, - hasCoat)); + normalData.normalWS = surfaceData.coatNormalWS; + normalData.perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(surfaceData.coatPerceptualSmoothness); } else { @@ -4213,25 +4210,21 @@ IndirectLighting EvaluateBSDF_ScreenSpaceReflection(PositionInputs posInput, if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_COAT)) { + float oneMinCoatMask = 1.0 - bsdfData.coatMask; // TODOENERGY: If vlayered, should be done in ComputeAdding with FGD formulation for non dirac lights. // Incorrect, but for now: float3 reflectanceFactorC = preLightData.specularFGD[COAT_LOBE_IDX]; - reflectanceFactorC *= preLightData.hemiSpecularOcclusion[COAT_LOBE_IDX]; reflectanceFactorC *= preLightData.energyCompensationFactor[COAT_LOBE_IDX]; - float3 reflectanceFactorB = (float3)0.0; - for(int i = 0; i < TOTAL_NB_LOBES; i++) - { - float3 lobeFactor = preLightData.specularFGD[i]; // note: includes the lobeMix factor, see PreLightData. - lobeFactor *= preLightData.hemiSpecularOcclusion[i]; - // TODOENERGY: If vlayered, should be done in ComputeAdding with FGD formulation for non dirac lights. - // Incorrect, but for now: - lobeFactor *= preLightData.energyCompensationFactor[i]; - reflectanceFactorB += lobeFactor; - } + float coatFGD = reflectanceFactorC.r; + reflectionHierarchyWeight = ssrLighting.a * (oneMinCoatMask + coatFGD); // coatMask is already multiplied in specularFGD[COAT_LOBE_IDX] + + reflectanceFactorC *= preLightData.hemiSpecularOcclusion[COAT_LOBE_IDX]; + + float3 reflectanceFactorB = (preLightData.specularFGD[BASE_LOBEA_IDX] * preLightData.hemiSpecularOcclusion[BASE_LOBEA_IDX] * preLightData.energyCompensationFactor[BASE_LOBEA_IDX]); + reflectanceFactorB += (preLightData.specularFGD[BASE_LOBEB_IDX] * preLightData.hemiSpecularOcclusion[BASE_LOBEB_IDX] * preLightData.energyCompensationFactor[BASE_LOBEB_IDX]); - lighting.specularReflected = ssrLighting.rgb * lerp(reflectanceFactorB, reflectanceFactorC, bsdfData.coatMask); - reflectionHierarchyWeight = lerp(ssrLighting.a, ssrLighting.a * reflectanceFactorC.x, bsdfData.coatMask); + lighting.specularReflected = ssrLighting.rgb * (oneMinCoatMask * reflectanceFactorB + reflectanceFactorC); } else { From af8010229c037b4dd2c260740c2feed2b9360c16 Mon Sep 17 00:00:00 2001 From: slunity Date: Thu, 8 Apr 2021 22:01:41 -0400 Subject: [PATCH 03/12] StackLit SSR-RTR: no lerp formulation, consistent with sampling: shading just ignores SSR-RTR light as coatMask goes to 0. --- .../Runtime/Material/StackLit/StackLit.hlsl | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLit.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLit.hlsl index be174879a48..d12e0e91a30 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLit.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLit.hlsl @@ -4208,27 +4208,22 @@ IndirectLighting EvaluateBSDF_ScreenSpaceReflection(PositionInputs posInput, // if the coat exist, ConvertSurfaceDataToNormalData will output the roughness of the coat and we don't need // a boost of sharp reflections from a potentially rough bottom layer. - if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_COAT)) + float3 reflectanceFactor = (float3)0.0; + reflectionHierarchyWeight = ssrLighting.a; + + if (IsVLayeredEnabled(bsdfData) && (bsdfData.coatMask > 0)) { - float oneMinCoatMask = 1.0 - bsdfData.coatMask; + reflectanceFactor = preLightData.specularFGD[COAT_LOBE_IDX]; // TODOENERGY: If vlayered, should be done in ComputeAdding with FGD formulation for non dirac lights. // Incorrect, but for now: - float3 reflectanceFactorC = preLightData.specularFGD[COAT_LOBE_IDX]; - reflectanceFactorC *= preLightData.energyCompensationFactor[COAT_LOBE_IDX]; - - float coatFGD = reflectanceFactorC.r; - reflectionHierarchyWeight = ssrLighting.a * (oneMinCoatMask + coatFGD); // coatMask is already multiplied in specularFGD[COAT_LOBE_IDX] - - reflectanceFactorC *= preLightData.hemiSpecularOcclusion[COAT_LOBE_IDX]; + reflectanceFactor *= preLightData.energyCompensationFactor[COAT_LOBE_IDX]; + float coatFGD = reflectanceFactor.r; //Max3(reflectanceFactor.r, reflectanceFactor.g, reflectanceFactor.b), but should be scalar anyway (coat) + reflectanceFactor *= preLightData.hemiSpecularOcclusion[COAT_LOBE_IDX]; - float3 reflectanceFactorB = (preLightData.specularFGD[BASE_LOBEA_IDX] * preLightData.hemiSpecularOcclusion[BASE_LOBEA_IDX] * preLightData.energyCompensationFactor[BASE_LOBEA_IDX]); - reflectanceFactorB += (preLightData.specularFGD[BASE_LOBEB_IDX] * preLightData.hemiSpecularOcclusion[BASE_LOBEB_IDX] * preLightData.energyCompensationFactor[BASE_LOBEB_IDX]); - - lighting.specularReflected = ssrLighting.rgb * (oneMinCoatMask * reflectanceFactorB + reflectanceFactorC); + reflectionHierarchyWeight *= coatFGD; } else { - float3 reflectanceFactor = (float3)0.0; for(int i = 0; i < TOTAL_NB_LOBES; i++) { float3 lobeFactor = preLightData.specularFGD[i]; // note: includes the lobeMix factor, see PreLightData. @@ -4238,11 +4233,11 @@ IndirectLighting EvaluateBSDF_ScreenSpaceReflection(PositionInputs posInput, lobeFactor *= preLightData.energyCompensationFactor[i]; reflectanceFactor += lobeFactor; } - // Note: RGB is already premultiplied by A. - lighting.specularReflected = ssrLighting.rgb * reflectanceFactor; - reflectionHierarchyWeight = ssrLighting.a; } + // Note: RGB is already premultiplied by A. + lighting.specularReflected = ssrLighting.rgb * reflectanceFactor; + return lighting; } From bde28b9515c462bf117ff836b5bb087c0d5d1285 Mon Sep 17 00:00:00 2001 From: slunity Date: Fri, 9 Apr 2021 00:05:07 -0400 Subject: [PATCH 04/12] Raytracing: Fix issues in StackLit -Fix indirect light hitting StackLit materials having wrong color for indirect ambient illumination. -Fix indirect light hitting StackLit materials not showing any specular response. --- .../ShaderGraph/ShaderPassDefine.template.hlsl | 5 ++++- .../Material/StackLit/StackLitRayTracing.hlsl | 16 +++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/StackLit/ShaderGraph/ShaderPassDefine.template.hlsl b/com.unity.render-pipelines.high-definition/Editor/Material/StackLit/ShaderGraph/ShaderPassDefine.template.hlsl index 3981b3d8759..ba30dfb3ce9 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/StackLit/ShaderGraph/ShaderPassDefine.template.hlsl +++ b/com.unity.render-pipelines.high-definition/Editor/Material/StackLit/ShaderGraph/ShaderPassDefine.template.hlsl @@ -59,7 +59,10 @@ $SpecularOcclusionConeFixupMethod.BoostAndTilt: #define _BEN #define OUTPUT_SPLIT_LIGHTING #endif -#if !( (SHADERPASS == SHADERPASS_FORWARD) || (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)) +#if !( (SHADERPASS == SHADERPASS_FORWARD) || (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT) \ + || (SHADERPASS == SHADERPASS_RAYTRACING_INDIRECT) || (SHADERPASS == SHADERPASS == SHADERPASS_RAYTRACING_INDIRECT)\ + || (SHADERPASS == SHADERPASS_PATH_TRACING) || (SHADERPASS == SHADERPASS_RAYTRACING_SUB_SURFACE) \ + || (SHADERPASS == SHADERPASS_RAYTRACING_GBUFFER) ) // StackLit.hlsl hooks the callback from PostInitBuiltinData() via #define MODIFY_BAKED_DIFFUSE_LIGHTING // but in ShaderGraph, we don't evaluate/set all input ports when the values are not used by the pass. // (In the material with the inspector UI, unused values were still normally set for all passes, here we diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLitRayTracing.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLitRayTracing.hlsl index 6aba641c083..5f07f6b3583 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLitRayTracing.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLitRayTracing.hlsl @@ -74,11 +74,21 @@ void FitToStandardLit( BSDFData bsdfData , uint2 positionSS , out StandardBSDFData outStandardlit) { - outStandardlit.baseColor = bsdfData.diffuseColor; - outStandardlit.specularOcclusion = bsdfData.specularOcclusionCustomInput; + // TODO: There's space for doing better here: + + // bool hasCoatNormal = HasFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_COAT) + // && HasFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_COAT_NORMAL_MAP); + // outStandardlit.normalWS = hasCoatNormal ? surfaceData.coatNormalWS : surfaceData.normalWS; + // Using coatnormal not necessarily better here depends on what each are vs geometric normal and the coat strength + // vs base strength. Could do something with that and specular albedos... outStandardlit.normalWS = bsdfData.normalWS; - outStandardlit.perceptualRoughness = bsdfData.perceptualRoughnessA; + + // StandardLit expects diffuse color in baseColor: + outStandardlit.baseColor = bsdfData.diffuseColor; outStandardlit.fresnel0 = bsdfData.fresnel0; + outStandardlit.specularOcclusion = 1; // TODO + + outStandardlit.perceptualRoughness = lerp(bsdfData.perceptualRoughnessA, bsdfData.perceptualRoughnessB, bsdfData.lobeMix); outStandardlit.coatMask = bsdfData.coatMask; outStandardlit.emissiveAndBaked = builtinData.bakeDiffuseLighting * bsdfData.ambientOcclusion + builtinData.emissiveColor; outStandardlit.isUnlit = 0; From b4c3aca6f63ceb615e3b8f22a0d3761d53d3012c Mon Sep 17 00:00:00 2001 From: slunity Date: Thu, 8 Apr 2021 23:20:48 -0400 Subject: [PATCH 05/12] Raytraced Reflections: Fix secondary reflection sampling for coated materials. This will only show with multi bounce indirect (so with RTR quality mode with a bounce count >= 2). -Make Lit secondary reflections also consider coat like StackLit and AxF -Fix Lit, AxF, StackLit: to use proper specular BSDF lobe sampling when a coat is present. --- .../Runtime/Material/AxF/AxFRayTracing.hlsl | 4 ++-- .../Runtime/Material/Lit/LitRaytracing.hlsl | 22 ++++++++++++++----- .../Material/StackLit/StackLitRayTracing.hlsl | 22 ++++++++++++++----- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxFRayTracing.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxFRayTracing.hlsl index 539430c67aa..1252282a6d6 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxFRayTracing.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxFRayTracing.hlsl @@ -1,7 +1,7 @@ float3 SampleSpecularBRDF(BSDFData bsdfData, float2 theSample, float3 viewWS) { - float roughness = PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness); - float3x3 localToWorld = GetLocalFrame(bsdfData.normalWS); + float roughness = HasClearcoat() ? CLEAR_COAT_ROUGHNESS : PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness); + float3x3 localToWorld = GetLocalFrame(HasClearcoat() ? bsdfData.clearcoatNormalWS : bsdfData.normalWS); float NdotL, NdotH, VdotH; float3 sampleDir; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitRaytracing.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitRaytracing.hlsl index 61546edfcc9..0fce5958689 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitRaytracing.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitRaytracing.hlsl @@ -1,15 +1,26 @@ float3 SampleSpecularBRDF(BSDFData bsdfData, float2 theSample, float3 viewWS) { - float roughness = PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness); + float roughness; float3x3 localToWorld; - if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY)) + + if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT) && HasClearCoatMask(bsdfData.coatMask)) { - localToWorld = float3x3(bsdfData.tangentWS, bsdfData.bitangentWS, bsdfData.normalWS); + roughness = CLEAR_COAT_ROUGHNESS; + localToWorld = GetLocalFrame(bsdfData.normalWS); } else { - localToWorld = GetLocalFrame(bsdfData.normalWS); + roughness = PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness); + if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY)) + { + localToWorld = float3x3(bsdfData.tangentWS, bsdfData.bitangentWS, bsdfData.normalWS); + } + else + { + localToWorld = GetLocalFrame(bsdfData.normalWS); + } } + float NdotL, NdotH, VdotH; float3 sampleDir; SampleGGXDir(theSample, viewWS, localToWorld, roughness, sampleDir, NdotL, NdotH, VdotH); @@ -24,7 +35,8 @@ IndirectLighting EvaluateBSDF_RaytracedReflection(LightLoopContext lightLoopCont { IndirectLighting lighting; ZERO_INITIALIZE(IndirectLighting, lighting); - lighting.specularReflected = reflection.rgb * preLightData.specularFGD; + lighting.specularReflected = reflection.rgb * ((HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT) && HasClearCoatMask(bsdfData.coatMask)) ? + preLightData.coatIblF : preLightData.specularFGD); return lighting; } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLitRayTracing.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLitRayTracing.hlsl index 5f07f6b3583..20d489f2678 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLitRayTracing.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLitRayTracing.hlsl @@ -1,15 +1,27 @@ float3 SampleSpecularBRDF(BSDFData bsdfData, float2 theSample, float3 viewWS) { - float roughness = bsdfData.roughnessAT; + float roughness; float3x3 localToWorld; - if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_ANISOTROPY)) + + if (IsVLayeredEnabled(bsdfData) && (bsdfData.coatMask > 0)) { - localToWorld = float3x3(bsdfData.tangentWS, bsdfData.bitangentWS, bsdfData.normalWS); + roughness = bsdfData.coatRoughness; + localToWorld = GetLocalFrame(bsdfData.normalWS); } else { - localToWorld = GetLocalFrame(bsdfData.normalWS); + roughness = PerceptualRoughnessToRoughness(lerp(bsdfData.perceptualRoughnessA, bsdfData.perceptualRoughnessB, bsdfData.lobeMix)); + + if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_ANISOTROPY)) + { + localToWorld = float3x3(bsdfData.tangentWS, bsdfData.bitangentWS, bsdfData.normalWS); + } + else + { + localToWorld = GetLocalFrame(bsdfData.normalWS); + } } + float NdotL, NdotH, VdotH; float3 sampleDir; SampleGGXDir(theSample, viewWS, localToWorld, roughness, sampleDir, NdotL, NdotH, VdotH); @@ -28,7 +40,7 @@ IndirectLighting EvaluateBSDF_RaytracedReflection(LightLoopContext lightLoopCont float3 reflectanceFactor = (float3)0.0; - if (IsVLayeredEnabled(bsdfData)) + if (IsVLayeredEnabled(bsdfData) && (bsdfData.coatMask > 0)) { reflectanceFactor = preLightData.specularFGD[COAT_LOBE_IDX]; reflectanceFactor *= preLightData.hemiSpecularOcclusion[COAT_LOBE_IDX]; From b4c0eca9ecff920a65db17e641ae8d2333ef4ad2 Mon Sep 17 00:00:00 2001 From: slunity Date: Fri, 18 Jun 2021 00:17:38 -0400 Subject: [PATCH 06/12] LightLoop and RaytracingLightLoop reflection hierarchy improvements: -RaytracingLightLoop EvaluateBSDF_RaytracedReflection() material callback now allow reflectionHierarchyWeight to be modified. This allows secondary reflections to properly deal with coated materials similarly to what the analogous EvaluateBSDF_ScreenSpaceReflection() callbacks (of the main lighting LightLoop) already can do, by using a (possibly integrated) Fresnel term to modulate it. See for example LitRaytracing.hlsl. -Both light loops now also have an opt-in (no performance hit - this is pruned by the compiler) mechanism to allow more refined reflection light hierarchies for coated/layered BSDF materials: a single reflectionHierarchyWeight is still used by the light loops, but a material can internally track the other layer weight and return eg a minimum through the main reflectionHierarchyWeight to the ligjht loop. This has many benefits: -Prevent overbright doubling of fresnel intensity for coat when using SSR-RTR lighting as there's now a way for the material to properly track the SSR-RTR contribution outside of its wanted lightprobe fallback (for performance reasons with SSR-RTR we can only sample one lobe roughness and direction) -For materials that can have different lobe directions, it allows the indirect specular lighting callbacks (ie EvaluateBSDF_Env() ) to allow further lightprobe evaluations when even one of the lobes have a fully used hierarchy. This can prevent subtle reflection artifacts for non trivial light probes setups with materials with different lobe directions. --- .../Runtime/Lighting/LightLoop/LightLoop.hlsl | 12 +- .../Runtime/Material/AxF/AxF.hlsl | 225 ++++++++++-------- .../Runtime/Material/AxF/AxFRayTracing.hlsl | 16 +- .../Runtime/Material/Eye/Eye.hlsl | 9 +- .../Runtime/Material/Eye/EyeRaytracing.hlsl | 4 +- .../Runtime/Material/Fabric/Fabric.hlsl | 9 +- .../Material/Fabric/FabricRaytracing.hlsl | 4 +- .../Runtime/Material/Hair/Hair.hlsl | 9 +- .../Runtime/Material/Hair/HairRayTracing.hlsl | 4 +- .../Runtime/Material/Lit/Lit.hlsl | 9 +- .../Runtime/Material/Lit/LitRaytracing.hlsl | 13 +- .../Runtime/Material/StackLit/StackLit.hlsl | 106 +++++---- .../Material/StackLit/StackLitRayTracing.hlsl | 15 +- .../Shaders/RaytracingLightLoop.hlsl | 12 +- 14 files changed, 284 insertions(+), 163 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.hlsl index 08c6c497cd8..5f2c469f593 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.hlsl @@ -307,7 +307,7 @@ void LightLoop( float3 V, PositionInputs posInput, PreLightData preLightData, BS // Define macro for a better understanding of the loop // TODO: this code is now much harder to understand... #define EVALUATE_BSDF_ENV_SKY(envLightData, TYPE, type) \ - IndirectLighting lighting = EvaluateBSDF_Env(context, V, posInput, preLightData, envLightData, bsdfData, envLightData.influenceShapeType, MERGE_NAME(GPUIMAGEBASEDLIGHTINGTYPE_, TYPE), MERGE_NAME(type, HierarchyWeight)); \ + IndirectLighting lighting = EvaluateBSDF_Env(context, V, posInput, preLightData, envLightData, bsdfData, envLightData.influenceShapeType, MERGE_NAME(GPUIMAGEBASEDLIGHTINGTYPE_, TYPE), MERGE_NAME(type, HierarchyWeight), lightHierarchyData); \ AccumulateIndirectLighting(lighting, aggregateLighting); // Environment cubemap test lightlayers, sky don't test it @@ -316,6 +316,14 @@ void LightLoop( float3 V, PositionInputs posInput, PreLightData preLightData, BS // First loop iteration if (featureFlags & (LIGHTFEATUREFLAGS_ENV | LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_SSREFRACTION | LIGHTFEATUREFLAGS_SSREFLECTION)) { + // This struct is defined in the material and is private to it. It can be used for multiple lobe materials when eg directions are different, + // and to avoid double lighting some lobes (eg coat from SSR vs env.) + // The Lightloop does not access it but pass it back for SSR and env evaluation. + // It is pruned out by the compiler if unused by the material. + // Accessed below by EvaluateBSDF_ScreenSpaceReflection and EVALUATE_BSDF_ENV (EvaluateBSDF_Env). + LightHierarchyData lightHierarchyData; + ZERO_INITIALIZE(LightHierarchyData, lightHierarchyData); // LightLoop is in charge of initializing the struct + float reflectionHierarchyWeight = 0.0; // Max: 1.0 float refractionHierarchyWeight = _EnableSSRefraction ? 0.0 : 1.0; // Max: 1.0 @@ -344,7 +352,7 @@ void LightLoop( float3 V, PositionInputs posInput, PreLightData preLightData, BS #if (defined(_SURFACE_TYPE_TRANSPARENT) && !defined(_DISABLE_SSR_TRANSPARENT)) || (!defined(_SURFACE_TYPE_TRANSPARENT) && !defined(_DISABLE_SSR)) { IndirectLighting indirect = EvaluateBSDF_ScreenSpaceReflection(posInput, preLightData, bsdfData, - reflectionHierarchyWeight); + reflectionHierarchyWeight, lightHierarchyData); AccumulateIndirectLighting(indirect, aggregateLighting); } #endif diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.hlsl index 37ffd0e3e9f..d6d90a4571c 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.hlsl @@ -2547,11 +2547,17 @@ DirectLighting EvaluateBSDF_Area(LightLoopContext lightLoopContext, //----------------------------------------------------------------------------- // EvaluateBSDF_SSLighting for screen space lighting // ---------------------------------------------------------------------------- +struct LightHierarchyData +{ + float coatReflectionWeight; + float baseReflectionWeight; +}; IndirectLighting EvaluateBSDF_ScreenSpaceReflection(PositionInputs posInput, PreLightData preLightData, BSDFData bsdfData, - inout float reflectionHierarchyWeight) + inout float reflectionHierarchyWeight, + inout LightHierarchyData lightHierarchyData) { IndirectLighting lighting; ZERO_INITIALIZE(IndirectLighting, lighting); @@ -2590,6 +2596,18 @@ IndirectLighting EvaluateBSDF_ScreenSpaceReflection(PositionInputs posInput, lighting.specularReflected = ssrLighting.rgb * reflectanceFactor; reflectionHierarchyWeight = ssrLighting.a; + if (HasClearcoat()) + { + // Instead of reflectionHierarchyWeight *= preLightData.coatFGD, + // with private LightHierarchyData we do: + lightHierarchyData.coatReflectionWeight = reflectionHierarchyWeight; + reflectionHierarchyWeight = 0; + } + else + { + //lightHierarchyData.coatReflectionWeight = will be unused anyway + lightHierarchyData.baseReflectionWeight = reflectionHierarchyWeight; + } return lighting; } @@ -2643,7 +2661,7 @@ IndirectLighting EvaluateBSDF_Env( LightLoopContext lightLoopContext, float3 viewWS_Clearcoat, PositionInputs posInput, PreLightData preLightData, EnvLightData lightData, BSDFData bsdfData, int _influenceShapeType, int _GPUImageBasedLightingType, - inout float hierarchyWeight) + inout float hierarchyWeight, inout LightHierarchyData lightHierarchyData) { IndirectLighting lighting; @@ -2654,121 +2672,121 @@ IndirectLighting EvaluateBSDF_Env( LightLoopContext lightLoopContext, float3 positionWS = posInput.positionWS; float weight = 1.0; - - // TODO_dir: this shouldn't be undercoat. - float3 envSamplingDirForBottomLayer = preLightData.iblDominantDirectionWS_BottomLobeOnTop; - -#if defined(_AXF_BRDF_TYPE_SVBRDF) float3 envLighting = 0.0; + float3 envSamplingDirForBottomLayer = preLightData.iblDominantDirectionWS_BottomLobeOnTop; - float NdotV = ClampNdotV(preLightData.NdotV_UnderCoat); - // Here we use bsdfData.clearcoatNormalWS: if there's no coat, bsdfData.clearcoatNormalWS == bsdfData.normalWS anyway. - // The reason is that, normally, since GetModifiedEnvSamplingDir (off-specular effect) is roughness dependent, - // we would have to store another direction (lightData is only used to escape the modification in case of planar probe) - // and in case of carpaint, one for each lobe. However, if we would like to "correctly" take into account the effect, we would have - // to calculate the effect on the bottom layer where directions are different, and then use FindAverageBaseLobeDirOnTop(). - // We decide to just apply the effect on top instead. - // (FindAverageBaseLobeDirOnTop is alreayd an approximation ignoring under-horizon or TIR. If we saturated to the critical angle undercoat - // and thus grazing when exiting on top, a tilt back for off-specular effect might in fact have no effect since the lobe could still - // be under horizon. On the other hand, if we didn't have to saturate, a little tilt-back toward normal (from GetModifiedEnvSamplingDir) - // should have translated into a bigger one on top because of angle range decompression.) - envSamplingDirForBottomLayer = GetModifiedEnvSamplingDir(lightData, bsdfData.clearcoatNormalWS, preLightData.iblDominantDirectionWS_BottomLobeOnTop, preLightData.iblPerceptualRoughness, NdotV); - - // Note: using _influenceShapeType and projectionShapeType instead of (lightData|proxyData).shapeType allow to make compiler optimization in case the type is know (like for sky) - float intersectionDistance = EvaluateLight_EnvIntersection(positionWS, bsdfData.clearcoatNormalWS, lightData, _influenceShapeType, envSamplingDirForBottomLayer, weight); - // ...here the normal is only used for normal fading mode of the influence volume. - - // Another problem with having even two fetch directions is the reflection hierarchy that only supports one weight. - // (TODO: We could have a vector tracking multiplied weights already applied per lobe that we update and that is - // passed back by the light loop but otherwise opaque to it, with the single hierarchyWeight tracked alongside. - // That way no "overlighting" would be done and by returning the hierarchyWeight = min(all weights) up to now, - // we could potentially avoid artifacts in having eg the clearcoat reflection not available from one influence volume - // while the base has full weight reflection. This ends up always preventing a blend for the coat reflection when the - // bottom reflection is full. Lit doesn't have this problem too much in practice since only GetModifiedEnvSamplingDir - // changes the direction vs the coat.) - - // Sample the pre-integrated environment lighting - float4 preLD = SampleEnvWithDistanceBaseRoughness(lightLoopContext, posInput, lightData, envSamplingDirForBottomLayer, preLightData.iblPerceptualRoughness, intersectionDistance); - weight *= preLD.w; // Used by planar reflection to discard pixel - - envLighting = GetSpecularIndirectDimmer() * preLightData.specularFGD * preLD.xyz; - - //----------------------------------------------------------------------------- -#elif defined(_AXF_BRDF_TYPE_CAR_PAINT) - - float3 envLighting = 0.0; - - // A part of this BRDF depends on thetaH and thetaD and should thus have entered - // the split sum pre-integration. We do a further approximation by pulling those - // terms out and evaluating them in the specular dominant direction, - // for BRDFColor and flakes, see GetPreLightData. - - // Note: we don't use GetModifiedEnvSamplingDir() per lobe here, and see comment above about reflection hierarchy. - float intersectionDistance = EvaluateLight_EnvIntersection(positionWS, bsdfData.clearcoatNormalWS, lightData, _influenceShapeType, envSamplingDirForBottomLayer, weight); + // If the base already grabbed all light it needed from previous lights, skip it + if (lightHierarchyData.baseReflectionWeight < 1.0) + { + #if defined(_AXF_BRDF_TYPE_SVBRDF) - #if USE_COOK_TORRANCE_MULTI_LOBES + float NdotV = ClampNdotV(preLightData.NdotV_UnderCoat); + // Here we use bsdfData.clearcoatNormalWS: if there's no coat, bsdfData.clearcoatNormalWS == bsdfData.normalWS anyway. + // The reason is that, normally, since GetModifiedEnvSamplingDir (off-specular effect) is roughness dependent, + // we would have to store another direction (lightData is only used to escape the modification in case of planar probe) + // and in case of carpaint, one for each lobe. However, if we would like to "correctly" take into account the effect, we would have + // to calculate the effect on the bottom layer where directions are different, and then use FindAverageBaseLobeDirOnTop(). + // We decide to just apply the effect on top instead. + // (FindAverageBaseLobeDirOnTop is alreayd an approximation ignoring under-horizon or TIR. If we saturated to the critical angle undercoat + // and thus grazing when exiting on top, a tilt back for off-specular effect might in fact have no effect since the lobe could still + // be under horizon. On the other hand, if we didn't have to saturate, a little tilt-back toward normal (from GetModifiedEnvSamplingDir) + // should have translated into a bigger one on top because of angle range decompression.) + envSamplingDirForBottomLayer = GetModifiedEnvSamplingDir(lightData, bsdfData.clearcoatNormalWS, preLightData.iblDominantDirectionWS_BottomLobeOnTop, preLightData.iblPerceptualRoughness, NdotV); + + // Note: using _influenceShapeType and projectionShapeType instead of (lightData|proxyData).shapeType allow to make compiler optimization in case the type is know (like for sky) + float intersectionDistance = EvaluateLight_EnvIntersection(positionWS, bsdfData.clearcoatNormalWS, lightData, _influenceShapeType, envSamplingDirForBottomLayer, weight); + // ...here the normal is only used for normal fading mode of the influence volume. + + // Another problem with having even two fetch directions is the reflection hierarchy that only supports one weight. + // (TODO: We could have a vector tracking multiplied weights already applied per lobe that we update and that is + // passed back by the light loop but otherwise opaque to it, with the single hierarchyWeight tracked alongside. + // That way no "overlighting" would be done and by returning the hierarchyWeight = min(all weights) up to now, + // we could potentially avoid artifacts in having eg the clearcoat reflection not available from one influence volume + // while the base has full weight reflection. This ends up always preventing a blend for the coat reflection when the + // bottom reflection is full. Lit doesn't have this problem too much in practice since only GetModifiedEnvSamplingDir + // changes the direction vs the coat.) + + // Sample the pre-integrated environment lighting + float4 preLD = SampleEnvWithDistanceBaseRoughness(lightLoopContext, posInput, lightData, envSamplingDirForBottomLayer, preLightData.iblPerceptualRoughness, intersectionDistance); + weight *= preLD.w; // Used by planar reflection to discard pixel + + envLighting = GetSpecularIndirectDimmer() * preLightData.specularFGD * preLD.xyz; + + //----------------------------------------------------------------------------- + #elif defined(_AXF_BRDF_TYPE_CAR_PAINT) - // Multi-lobes approach - // Each CT lobe samples the environment with the appropriate roughness - float probeSkipFactor = 1; - for (uint lobeIndex = 0; lobeIndex < CARPAINT2_LOBE_COUNT; lobeIndex++) - { - float coeff = _CarPaint2_CTCoeffs[lobeIndex]; + // A part of this BRDF depends on thetaH and thetaD and should thus have entered + // the split sum pre-integration. We do a further approximation by pulling those + // terms out and evaluating them in the specular dominant direction, + // for BRDFColor and flakes, see GetPreLightData. - float4 preLD = SampleEnvWithDistanceBaseRoughness(lightLoopContext, posInput, lightData, envSamplingDirForBottomLayer, preLightData.iblPerceptualRoughness[lobeIndex], intersectionDistance); + // Note: we don't use GetModifiedEnvSamplingDir() per lobe here, and see comment above about reflection hierarchy. + float intersectionDistance = EvaluateLight_EnvIntersection(positionWS, bsdfData.clearcoatNormalWS, lightData, _influenceShapeType, envSamplingDirForBottomLayer, weight); - //todotodo: try removing coeff - envLighting += coeff * GetCarPaintSpecularFGDForLobe(preLightData, lobeIndex) * preLD.xyz; - // Note: preLD.w is only used by planar probes, returning 0 if outside captured direction or 1 otherwise (the influence volume weight fades, not this). - // Since this is only used for planar probes, even if we had used GetModifiedEnvSamplingDir() above, all directions would be the same in that case anyway - // since GetModifiedEnvSamplingDir() doesn't do anything for planar probes. - // For that reason, only one preLD.w needs to be used, no need to average them, they should all be the same. - // sumWeights += preLD.w; - probeSkipFactor = preLD.w; - } - // See discussion about reflection hierarchy above for SVBRDF, same thing here: When we will evaluate the coat, we will ignore its weight. - weight *= probeSkipFactor; - envLighting *= GetSpecularIndirectDimmer(); - //now already in rebuilt specularFGD: envLighting *= GetBRDFColor(thetaH, thetaD); + #if USE_COOK_TORRANCE_MULTI_LOBES - // Sample flakes - //TODO_FLAKES - float flakesMipLevel = 0; // Flakes are supposed to be perfect mirrors - envLighting += preLightData.singleFlakesComponent * SampleEnv(lightLoopContext, lightData.envIndex, envSamplingDirForBottomLayer, flakesMipLevel, lightData.rangeCompressionFactorCompensation, posInput.positionNDC).xyz; + // Multi-lobes approach + // Each CT lobe samples the environment with the appropriate roughness + float probeSkipFactor = 1; + for (uint lobeIndex = 0; lobeIndex < CARPAINT2_LOBE_COUNT; lobeIndex++) + { + float coeff = _CarPaint2_CTCoeffs[lobeIndex]; + + float4 preLD = SampleEnvWithDistanceBaseRoughness(lightLoopContext, posInput, lightData, envSamplingDirForBottomLayer, preLightData.iblPerceptualRoughness[lobeIndex], intersectionDistance); + + //todotodo: try removing coeff + envLighting += coeff * GetCarPaintSpecularFGDForLobe(preLightData, lobeIndex) * preLD.xyz; + // Note: preLD.w is only used by planar probes, returning 0 if outside captured direction or 1 otherwise (the influence volume weight fades, not this). + // Since this is only used for planar probes, even if we had used GetModifiedEnvSamplingDir() above, all directions would be the same in that case anyway + // since GetModifiedEnvSamplingDir() doesn't do anything for planar probes. + // For that reason, only one preLD.w needs to be used, no need to average them, they should all be the same. + // sumWeights += preLD.w; + probeSkipFactor = preLD.w; + } + // See discussion about reflection hierarchy above for SVBRDF, same thing here: When we will evaluate the coat, we will ignore its weight. + weight *= probeSkipFactor; + envLighting *= GetSpecularIndirectDimmer(); + //now already in rebuilt specularFGD: envLighting *= GetBRDFColor(thetaH, thetaD); - #else // USE_COOK_TORRANCE_MULTI_LOBES + // Sample flakes + //TODO_FLAKES + float flakesMipLevel = 0; // Flakes are supposed to be perfect mirrors + envLighting += preLightData.singleFlakesComponent * SampleEnv(lightLoopContext, lightData.envIndex, envSamplingDirForBottomLayer, flakesMipLevel, lightData.rangeCompressionFactorCompensation, posInput.positionNDC).xyz; - // Single lobe approach - // We computed an average mip level stored in preLightData.iblPerceptualRoughness that we use for all CT lobes - // Sample the actual environment lighting - float4 preLD = SampleEnvWithDistanceBaseRoughness(lightLoopContext, posInput, lightData, envSamplingDirForBottomLayer, preLightData.iblPerceptualRoughness, intersectionDistance); - float3 envLighting; + #else // USE_COOK_TORRANCE_MULTI_LOBES - envLighting = preLightData.specularCTFGDSingleLobe * GetSpecularIndirectDimmer(); - //TODO_FLAKES - envLighting += preLightData.singleFlakesComponent; - envLighting *= preLD.xyz; - weight *= preLD.w; // Used by planar reflection to discard pixel + // Single lobe approach + // We computed an average mip level stored in preLightData.iblPerceptualRoughness that we use for all CT lobes + // Sample the actual environment lighting + float4 preLD = SampleEnvWithDistanceBaseRoughness(lightLoopContext, posInput, lightData, envSamplingDirForBottomLayer, preLightData.iblPerceptualRoughness, intersectionDistance); + float3 envLighting; - #endif // USE_COOK_TORRANCE_MULTI_LOBES + envLighting = preLightData.specularCTFGDSingleLobe * GetSpecularIndirectDimmer(); + //TODO_FLAKES + envLighting += preLightData.singleFlakesComponent; + envLighting *= preLD.xyz; + weight *= preLD.w; // Used by planar reflection to discard pixel -//----------------------------------------------------------------------------- -#else // ..._AXF_BRDF_TYPE_CAR_PAINT + #endif // USE_COOK_TORRANCE_MULTI_LOBES - float3 envLighting = 0; // error / unknown BRDF type + //----------------------------------------------------------------------------- + #else // ..._AXF_BRDF_TYPE_CAR_PAINT + // error / unknown BRDF type + #endif // BRDF type -#endif // BRDF type + UpdateLightingHierarchyWeights(lightHierarchyData.baseReflectionWeight, weight); + envLighting *= weight; + } // if (lightHierarchyData.baseReflectionWeight < 1.0) //----------------------------------------------------------------------------- // Evaluate the clearcoat component if needed - if (!IsDebugHideCoat() && HasClearcoat()) + if (!IsDebugHideCoat() && HasClearcoat() && (lightHierarchyData.coatReflectionWeight < 1.0)) { - + weight = 1.0; // Evaluate clearcoat sampling direction - float unusedWeight = 0.0; float3 lightWS_Clearcoat = preLightData.iblDominantDirectionWS_Clearcoat; - EvaluateLight_EnvIntersection(positionWS, bsdfData.clearcoatNormalWS, lightData, _influenceShapeType, lightWS_Clearcoat, unusedWeight); + EvaluateLight_EnvIntersection(positionWS, bsdfData.clearcoatNormalWS, lightData, _influenceShapeType, lightWS_Clearcoat, weight); // Attenuate environment lighting under the clearcoat by the complement to the Fresnel term //todo_energy: @@ -2777,11 +2795,20 @@ IndirectLighting EvaluateBSDF_Env( LightLoopContext lightLoopContext, // Then add the environment lighting reflected by the clearcoat (with mip level 0, like mirror) float4 preLD = SampleEnv(lightLoopContext, lightData.envIndex, lightWS_Clearcoat, 0.0, lightData.rangeCompressionFactorCompensation, posInput.positionNDC); - envLighting += preLightData.coatFGD * preLD.xyz * bsdfData.clearcoatColor; + weight *= preLD.w; + + // Update the coat weight, but make sure the weight is only then applied to the additional coat lighting: + UpdateLightingHierarchyWeights(lightHierarchyData.coatReflectionWeight, weight); + envLighting += weight * preLightData.coatFGD * preLD.xyz * bsdfData.clearcoatColor; + + hierarchyWeight = min(lightHierarchyData.baseReflectionWeight, lightHierarchyData.coatReflectionWeight); + } + else + { + hierarchyWeight = lightHierarchyData.baseReflectionWeight; } - UpdateLightingHierarchyWeights(hierarchyWeight, weight); - envLighting *= weight * lightData.multiplier; + envLighting *= lightData.multiplier; lighting.specularReflected = envLighting; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxFRayTracing.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxFRayTracing.hlsl index 1252282a6d6..26ef939d9c1 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxFRayTracing.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxFRayTracing.hlsl @@ -14,7 +14,9 @@ float3 SampleSpecularBRDF(BSDFData bsdfData, float2 theSample, float3 viewWS) IndirectLighting EvaluateBSDF_RaytracedReflection(LightLoopContext lightLoopContext, BSDFData bsdfData, PreLightData preLightData, - float3 reflection) + float3 reflection, + inout float reflectionHierarchyWeight, + inout LightHierarchyData lightHierarchyData) { IndirectLighting lighting; ZERO_INITIALIZE(IndirectLighting, lighting); @@ -48,6 +50,18 @@ IndirectLighting EvaluateBSDF_RaytracedReflection(LightLoopContext lightLoopCont } lighting.specularReflected = reflection.rgb * reflectanceFactor; + if (HasClearcoat()) + { + // Instead of reflectionHierarchyWeight *= preLightData.coatFGD, + // with private LightHierarchyData we do: + lightHierarchyData.coatReflectionWeight = reflectionHierarchyWeight; + reflectionHierarchyWeight = 0; + } + else + { + //lightHierarchyData.coatReflectionWeight = will be unused anyway + lightHierarchyData.baseReflectionWeight = reflectionHierarchyWeight; + } return lighting; } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Eye/Eye.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/Eye/Eye.hlsl index 48e061bc501..f97677ab2cd 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Eye/Eye.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Eye/Eye.hlsl @@ -712,11 +712,16 @@ DirectLighting EvaluateBSDF_Area(LightLoopContext lightLoopContext, //----------------------------------------------------------------------------- // EvaluateBSDF_SSLighting for screen space lighting // ---------------------------------------------------------------------------- +struct LightHierarchyData +{ + float unused; +}; IndirectLighting EvaluateBSDF_ScreenSpaceReflection(PositionInputs posInput, PreLightData preLightData, BSDFData bsdfData, - inout float reflectionHierarchyWeight) + inout float reflectionHierarchyWeight, + inout LightHierarchyData lightHierarchyData) { IndirectLighting lighting; ZERO_INITIALIZE(IndirectLighting, lighting); @@ -758,7 +763,7 @@ IndirectLighting EvaluateBSDF_Env( LightLoopContext lightLoopContext, float3 V, PositionInputs posInput, PreLightData preLightData, EnvLightData lightData, BSDFData bsdfData, int influenceShapeType, int GPUImageBasedLightingType, - inout float hierarchyWeight) + inout float hierarchyWeight, inout LightHierarchyData lightHierarchyData) { IndirectLighting lighting; ZERO_INITIALIZE(IndirectLighting, lighting); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Eye/EyeRaytracing.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/Eye/EyeRaytracing.hlsl index 42200efcf5d..58609828156 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Eye/EyeRaytracing.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Eye/EyeRaytracing.hlsl @@ -12,7 +12,9 @@ float3 SampleSpecularBRDF(BSDFData bsdfData, float2 theSample, float3 viewWS) IndirectLighting EvaluateBSDF_RaytracedReflection(LightLoopContext lightLoopContext, BSDFData bsdfData, PreLightData preLightData, - float3 reflection) + float3 reflection, + inout float reflectionHierarchyWeight, + inout LightHierarchyData lightHierarchyData) { IndirectLighting lighting; ZERO_INITIALIZE(IndirectLighting, lighting); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Fabric/Fabric.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/Fabric/Fabric.hlsl index 5336bb0cb7b..2331bb912d7 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Fabric/Fabric.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Fabric/Fabric.hlsl @@ -755,11 +755,16 @@ DirectLighting EvaluateBSDF_Area(LightLoopContext lightLoopContext, //----------------------------------------------------------------------------- // EvaluateBSDF_SSLighting for screen space lighting // ---------------------------------------------------------------------------- +struct LightHierarchyData +{ + float unused; +}; IndirectLighting EvaluateBSDF_ScreenSpaceReflection(PositionInputs posInput, PreLightData preLightData, BSDFData bsdfData, - inout float reflectionHierarchyWeight) + inout float reflectionHierarchyWeight, + inout LightHierarchyData lightHierarchyData) { IndirectLighting lighting; ZERO_INITIALIZE(IndirectLighting, lighting); @@ -801,7 +806,7 @@ IndirectLighting EvaluateBSDF_Env( LightLoopContext lightLoopContext, float3 V, PositionInputs posInput, PreLightData preLightData, EnvLightData lightData, BSDFData bsdfData, int influenceShapeType, int GPUImageBasedLightingType, - inout float hierarchyWeight) + inout float hierarchyWeight, inout LightHierarchyData lightHierarchyData) { IndirectLighting lighting; ZERO_INITIALIZE(IndirectLighting, lighting); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Fabric/FabricRaytracing.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/Fabric/FabricRaytracing.hlsl index f80ab99d4fa..a706d3ac9c9 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Fabric/FabricRaytracing.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Fabric/FabricRaytracing.hlsl @@ -20,7 +20,9 @@ float3 SampleSpecularBRDF(BSDFData bsdfData, float2 theSample, float3 viewWS) IndirectLighting EvaluateBSDF_RaytracedReflection(LightLoopContext lightLoopContext, BSDFData bsdfData, PreLightData preLightData, - float3 reflection) + float3 reflection, + inout float reflectionHierarchyWeight, + inout LightHierarchyData lightHierarchyData) { IndirectLighting lighting; ZERO_INITIALIZE(IndirectLighting, lighting); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Hair/Hair.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/Hair/Hair.hlsl index 74f080a5bbd..1523abb6530 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Hair/Hair.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Hair/Hair.hlsl @@ -714,11 +714,16 @@ DirectLighting EvaluateBSDF_Area(LightLoopContext lightLoopContext, //----------------------------------------------------------------------------- // EvaluateBSDF_SSLighting for screen space lighting // ---------------------------------------------------------------------------- +struct LightHierarchyData +{ + float unused; +}; IndirectLighting EvaluateBSDF_ScreenSpaceReflection(PositionInputs posInput, PreLightData preLightData, BSDFData bsdfData, - inout float reflectionHierarchyWeight) + inout float reflectionHierarchyWeight, + inout LightHierarchyData lightHierarchyData) { IndirectLighting lighting; ZERO_INITIALIZE(IndirectLighting, lighting); @@ -762,7 +767,7 @@ IndirectLighting EvaluateBSDF_Env( LightLoopContext lightLoopContext, float3 V, PositionInputs posInput, PreLightData preLightData, EnvLightData lightData, BSDFData bsdfData, int influenceShapeType, int GPUImageBasedLightingType, - inout float hierarchyWeight) + inout float hierarchyWeight, inout LightHierarchyData lightHierarchyData) { IndirectLighting lighting; ZERO_INITIALIZE(IndirectLighting, lighting); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Hair/HairRayTracing.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/Hair/HairRayTracing.hlsl index 7d4402a9654..d0c2fd17f5e 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Hair/HairRayTracing.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Hair/HairRayTracing.hlsl @@ -13,7 +13,9 @@ float3 SampleSpecularBRDF(BSDFData bsdfData, float2 theSample, float3 viewWS) IndirectLighting EvaluateBSDF_RaytracedReflection(LightLoopContext lightLoopContext, BSDFData bsdfData, PreLightData preLightData, - float3 reflection) + float3 reflection, + inout float reflectionHierarchyWeight, + inout LightHierarchyData lightHierarchyData) { IndirectLighting lighting; ZERO_INITIALIZE(IndirectLighting, lighting); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl index 679d8f35330..f1d3e8c73c3 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl @@ -1788,11 +1788,16 @@ DirectLighting EvaluateBSDF_Area(LightLoopContext lightLoopContext, //----------------------------------------------------------------------------- // EvaluateBSDF_SSLighting for screen space lighting // ---------------------------------------------------------------------------- +struct LightHierarchyData +{ + float unused; +}; IndirectLighting EvaluateBSDF_ScreenSpaceReflection(PositionInputs posInput, PreLightData preLightData, BSDFData bsdfData, - inout float reflectionHierarchyWeight) + inout float reflectionHierarchyWeight, + inout LightHierarchyData lightHierarchyData) { IndirectLighting lighting; ZERO_INITIALIZE(IndirectLighting, lighting); @@ -1911,7 +1916,7 @@ IndirectLighting EvaluateBSDF_Env( LightLoopContext lightLoopContext, float3 V, PositionInputs posInput, PreLightData preLightData, EnvLightData lightData, BSDFData bsdfData, int influenceShapeType, int GPUImageBasedLightingType, - inout float hierarchyWeight) + inout float hierarchyWeight, inout LightHierarchyData lightHierarchyData) { IndirectLighting lighting; ZERO_INITIALIZE(IndirectLighting, lighting); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitRaytracing.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitRaytracing.hlsl index 0fce5958689..332c1d56f08 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitRaytracing.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitRaytracing.hlsl @@ -31,12 +31,19 @@ float3 SampleSpecularBRDF(BSDFData bsdfData, float2 theSample, float3 viewWS) IndirectLighting EvaluateBSDF_RaytracedReflection(LightLoopContext lightLoopContext, BSDFData bsdfData, PreLightData preLightData, - float3 reflection) + float3 reflection, + inout float reflectionHierarchyWeight, + inout LightHierarchyData lightHierarchyData) { IndirectLighting lighting; ZERO_INITIALIZE(IndirectLighting, lighting); - lighting.specularReflected = reflection.rgb * ((HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT) && HasClearCoatMask(bsdfData.coatMask)) ? - preLightData.coatIblF : preLightData.specularFGD); + bool coatUsed = HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT) && HasClearCoatMask(bsdfData.coatMask); + lighting.specularReflected = reflection.rgb * (coatUsed ? preLightData.coatIblF : preLightData.specularFGD); + + if (coatUsed) + //reflectionHierarchyWeight *= 1 - Sq(1 - preLightData.coatIblF); + reflectionHierarchyWeight *= preLightData.coatIblF; + return lighting; } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLit.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLit.hlsl index d12e0e91a30..01cb9b12a10 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLit.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLit.hlsl @@ -4180,11 +4180,16 @@ DirectLighting EvaluateBSDF_Area(LightLoopContext lightLoopContext, //----------------------------------------------------------------------------- // EvaluateBSDF_SSLighting for screen space lighting // ---------------------------------------------------------------------------- +struct LightHierarchyData +{ + float lobeReflectionWeight[TOTAL_NB_LOBES]; +}; IndirectLighting EvaluateBSDF_ScreenSpaceReflection(PositionInputs posInput, PreLightData preLightData, BSDFData bsdfData, - inout float reflectionHierarchyWeight) + inout float reflectionHierarchyWeight, + inout LightHierarchyData lightHierarchyData) { IndirectLighting lighting; ZERO_INITIALIZE(IndirectLighting, lighting); @@ -4209,7 +4214,7 @@ IndirectLighting EvaluateBSDF_ScreenSpaceReflection(PositionInputs posInput, // a boost of sharp reflections from a potentially rough bottom layer. float3 reflectanceFactor = (float3)0.0; - reflectionHierarchyWeight = ssrLighting.a; + reflectionHierarchyWeight = ssrLighting.a; if (IsVLayeredEnabled(bsdfData) && (bsdfData.coatMask > 0)) { @@ -4217,10 +4222,13 @@ IndirectLighting EvaluateBSDF_ScreenSpaceReflection(PositionInputs posInput, // TODOENERGY: If vlayered, should be done in ComputeAdding with FGD formulation for non dirac lights. // Incorrect, but for now: reflectanceFactor *= preLightData.energyCompensationFactor[COAT_LOBE_IDX]; - float coatFGD = reflectanceFactor.r; //Max3(reflectanceFactor.r, reflectanceFactor.g, reflectanceFactor.b), but should be scalar anyway (coat) + //float coatFGD = reflectanceFactor.r; reflectanceFactor *= preLightData.hemiSpecularOcclusion[COAT_LOBE_IDX]; - reflectionHierarchyWeight *= coatFGD; + lightHierarchyData.lobeReflectionWeight[COAT_LOBE_IDX] = reflectionHierarchyWeight; + // Instead of reflectionHierarchyWeight *= coatFGD, + // we return min_of_all(lobeReflectionWeight) == 0, as we didn't provide any light for the bottom layer lobes: + reflectionHierarchyWeight = 0; } else { @@ -4233,6 +4241,9 @@ IndirectLighting EvaluateBSDF_ScreenSpaceReflection(PositionInputs posInput, lobeFactor *= preLightData.energyCompensationFactor[i]; reflectanceFactor += lobeFactor; } + + lightHierarchyData.lobeReflectionWeight[BASE_LOBEA_IDX] = + lightHierarchyData.lobeReflectionWeight[BASE_LOBEB_IDX] = reflectionHierarchyWeight; } // Note: RGB is already premultiplied by A. @@ -4264,7 +4275,7 @@ IndirectLighting EvaluateBSDF_Env( LightLoopContext lightLoopContext, float3 V, PositionInputs posInput, PreLightData preLightData, EnvLightData lightData, BSDFData bsdfData, int influenceShapeType, int GPUImageBasedLightingType, - inout float hierarchyWeight) + inout float hierarchyWeight, inout LightHierarchyData lightHierarchyData) { IndirectLighting lighting; ZERO_INITIALIZE(IndirectLighting, lighting); @@ -4304,6 +4315,7 @@ IndirectLighting EvaluateBSDF_Env( LightLoopContext lightLoopContext, float3 R[TOTAL_NB_LOBES]; float tempWeight[TOTAL_NB_LOBES]; + float smallestHierarchyWeight = 1.0; int i; for (i = 0; i < TOTAL_NB_LOBES; ++i) @@ -4339,54 +4351,62 @@ IndirectLighting EvaluateBSDF_Env( LightLoopContext lightLoopContext, if( (i == (0 IF_FEATURE_COAT(+1))) && _DebugEnvLobeMask.y == 0.0) continue; if( (i == (1 IF_FEATURE_COAT(+1))) && _DebugEnvLobeMask.z == 0.0) continue; #endif - // Compiler will deal with all that: - normal = (NB_NORMALS > 1 && i == COAT_NORMAL_IDX) ? bsdfData.coatNormalWS : bsdfData.normalWS; - - R[i] = preLightData.iblR[i]; - if (!IsEnvIndexTexture2D(lightData.envIndex)) // ENVCACHETYPE_CUBEMAP + // If the lobe already grabbed all light it needed from previous lights (eg coat with SSR), we skip it. + // We also check preLightData.specularFGD[i] to allow the compiler to optimize away when dual specular + // lobe is not used: that way smallestHierarchyWeight can't be updated (uselessly) and more importantly, + // can't influence a possible useless continuation of the lightloop because of consideration of its + // hierarchyWeight + if ((lightHierarchyData.lobeReflectionWeight[i] < 1.0) && any(preLightData.specularFGD[i] > 0)) { - // Correction of reflected direction for better handling of rough material - // - // Notice again that when vlayering, the roughness and iblR properly use the output lobe statistics, but baseLayerNdotV - // is used for the offspecular correction because the true original offspecular tilt is parametrized by - // the angle at the base layer and the correction itself is influenced by that. See comments in GetPreLightData. - float clampedNdotV = (NB_NORMALS > 1 && i == COAT_NORMAL_IDX) ? ClampNdotV(preLightData.NdotV[COAT_NORMAL_IDX]) : preLightData.baseLayerNdotV; // the later is already clamped - - R[i] = GetSpecularDominantDir(normal, preLightData.iblR[i], preLightData.iblPerceptualRoughness[i], clampedNdotV); - // When we are rough, we tend to see outward shifting of the reflection when at the boundary of the projection volume - // Also it appear like more sharp. To avoid these artifact and at the same time get better match to reference we lerp to original unmodified reflection. - // Formula is empirical. - float roughness = PerceptualRoughnessToRoughness(preLightData.iblPerceptualRoughness[i]); - R[i] = lerp(R[i], preLightData.iblR[i], saturate(smoothstep(0, 1, roughness * roughness))); - } + // Compiler will deal with all that: + normal = (NB_NORMALS > 1 && i == COAT_NORMAL_IDX) ? bsdfData.coatNormalWS : bsdfData.normalWS; - float intersectionDistance = EvaluateLight_EnvIntersection(positionWS, normal, lightData, influenceShapeType, R[i], tempWeight[i]); + R[i] = preLightData.iblR[i]; + if (!IsEnvIndexTexture2D(lightData.envIndex)) // ENVCACHETYPE_CUBEMAP + { + // Correction of reflected direction for better handling of rough material + // + // Notice again that when vlayering, the roughness and iblR properly use the output lobe statistics, but baseLayerNdotV + // is used for the offspecular correction because the true original offspecular tilt is parametrized by + // the angle at the base layer and the correction itself is influenced by that. See comments in GetPreLightData. + float clampedNdotV = (NB_NORMALS > 1 && i == COAT_NORMAL_IDX) ? ClampNdotV(preLightData.NdotV[COAT_NORMAL_IDX]) : preLightData.baseLayerNdotV; // the later is already clamped + + R[i] = GetSpecularDominantDir(normal, preLightData.iblR[i], preLightData.iblPerceptualRoughness[i], clampedNdotV); + // When we are rough, we tend to see outward shifting of the reflection when at the boundary of the projection volume + // Also it appear like more sharp. To avoid these artifact and at the same time get better match to reference we lerp to original unmodified reflection. + // Formula is empirical. + float roughness = PerceptualRoughnessToRoughness(preLightData.iblPerceptualRoughness[i]); + R[i] = lerp(R[i], preLightData.iblR[i], saturate(smoothstep(0, 1, roughness * roughness))); + } - float4 preLD = SampleEnvWithDistanceBaseRoughness(lightLoopContext, posInput, lightData, R[i], preLightData.iblPerceptualRoughness[i], intersectionDistance); + float intersectionDistance = EvaluateLight_EnvIntersection(positionWS, normal, lightData, influenceShapeType, R[i], tempWeight[i]); - // Used by planar reflection to discard pixel: - tempWeight[i] *= preLD.a; + float4 preLD = SampleEnvWithDistanceBaseRoughness(lightLoopContext, posInput, lightData, R[i], preLightData.iblPerceptualRoughness[i], intersectionDistance); - L = preLD.rgb * preLightData.specularFGD[i]; - // TODOENERGY: If vlayered, should be done in ComputeAdding with FGD formulation for IBL. Same for LTC actually - // Incorrect, but just for now: - L *= preLightData.energyCompensationFactor[i]; - L *= preLightData.hemiSpecularOcclusion[i]; - envLighting += L; - } + // Used by planar reflection to discard pixel: + tempWeight[i] *= preLD.a; - // TODO: to combine influence weights, mean or max or ... ? - for( i = 0; i < TOTAL_NB_LOBES; ++i) - { - weight += tempWeight[i]; + L = preLD.rgb * preLightData.specularFGD[i]; + // TODOENERGY: If vlayered, should be done in ComputeAdding with FGD formulation for IBL. Same for LTC actually + // Incorrect, but just for now: + L *= preLightData.energyCompensationFactor[i]; + L *= preLightData.hemiSpecularOcclusion[i]; + + UpdateLightingHierarchyWeights(lightHierarchyData.lobeReflectionWeight[i], tempWeight[i]); + smallestHierarchyWeight = min(smallestHierarchyWeight, lightHierarchyData.lobeReflectionWeight[i]); + envLighting += L * tempWeight[i]; + } } - weight /= TOTAL_NB_LOBES; - weight = tempWeight[1]; #endif // STACK_LIT_DISPLAY_REFERENCE_IBL - UpdateLightingHierarchyWeights(hierarchyWeight, weight); - envLighting *= weight * lightData.multiplier; + // The lightloop is aware of only one hierarchyWeight: to process further lighting for lobes not being lit up to + // a full 1.0 of reflection contribution, just return the smallest we have + // (Note we can't use the input hierarchyWeight in the loop above as it is important smallestHierarchyWeight + // is initialized to 1.0 otherwise the lightloop visible weight will obviously never rise above what SSR left it at.) + hierarchyWeight = smallestHierarchyWeight; + + envLighting *= lightData.multiplier; if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION) lighting.specularReflected = envLighting; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLitRayTracing.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLitRayTracing.hlsl index 20d489f2678..28aeefb0beb 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLitRayTracing.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/StackLit/StackLitRayTracing.hlsl @@ -33,7 +33,9 @@ float3 SampleSpecularBRDF(BSDFData bsdfData, float2 theSample, float3 viewWS) IndirectLighting EvaluateBSDF_RaytracedReflection(LightLoopContext lightLoopContext, BSDFData bsdfData, PreLightData preLightData, - float3 reflection) + float3 reflection, + inout float reflectionHierarchyWeight, + inout LightHierarchyData lightHierarchyData) { IndirectLighting lighting; ZERO_INITIALIZE(IndirectLighting, lighting); @@ -43,10 +45,16 @@ IndirectLighting EvaluateBSDF_RaytracedReflection(LightLoopContext lightLoopCont if (IsVLayeredEnabled(bsdfData) && (bsdfData.coatMask > 0)) { reflectanceFactor = preLightData.specularFGD[COAT_LOBE_IDX]; - reflectanceFactor *= preLightData.hemiSpecularOcclusion[COAT_LOBE_IDX]; // TODOENERGY: If vlayered, should be done in ComputeAdding with FGD formulation for non dirac lights. // Incorrect, but for now: reflectanceFactor *= preLightData.energyCompensationFactor[COAT_LOBE_IDX]; + //float coatFGD = reflectanceFactor.r; + reflectanceFactor *= preLightData.hemiSpecularOcclusion[COAT_LOBE_IDX]; + + lightHierarchyData.lobeReflectionWeight[COAT_LOBE_IDX] = reflectionHierarchyWeight; + // Instead of reflectionHierarchyWeight *= coatFGD, + // we return min_of_all(lobeReflectionWeight) == 0, as we didn't provide any light for the bottom layer lobes: + reflectionHierarchyWeight = 0; } else { @@ -59,6 +67,9 @@ IndirectLighting EvaluateBSDF_RaytracedReflection(LightLoopContext lightLoopCont lobeFactor *= preLightData.energyCompensationFactor[i]; reflectanceFactor += lobeFactor; } + + lightHierarchyData.lobeReflectionWeight[BASE_LOBEA_IDX] = + lightHierarchyData.lobeReflectionWeight[BASE_LOBEB_IDX] = reflectionHierarchyWeight; } lighting.specularReflected = reflection.rgb * reflectanceFactor; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingLightLoop.hlsl b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingLightLoop.hlsl index 186e7d47ada..0ee50e9643f 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingLightLoop.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingLightLoop.hlsl @@ -43,6 +43,14 @@ void LightLoop( float3 V, PositionInputs posInput, PreLightData preLightData, BS AggregateLighting aggregateLighting; ZERO_INITIALIZE(AggregateLighting, aggregateLighting); // LightLoop is in charge of initializing the structure + // This struct is defined in the material and is private to it. It can be used for multiple lobe materials when eg directions are different, + // and to avoid double lighting some lobes (eg coat from SSR vs env.) + // The Lightloop does not access it but pass it back for SSR and env evaluation. + // It is pruned out by the compiler if unused by the material. + // Accessed below by EvaluateBSDF_ScreenSpaceReflection and EVALUATE_BSDF_ENV (EvaluateBSDF_Env). + LightHierarchyData lightHierarchyData; + ZERO_INITIALIZE(LightHierarchyData, lightHierarchyData); // LightLoop is in charge of initializing the struct + // Indices of the subranges to process uint lightStart = 0, lightEnd = 0; @@ -79,7 +87,7 @@ void LightLoop( float3 V, PositionInputs posInput, PreLightData preLightData, BS // Add the traced reflection if (reflectionHierarchyWeight == 1.0) { - IndirectLighting lighting = EvaluateBSDF_RaytracedReflection(context, bsdfData, preLightData, reflection); + IndirectLighting lighting = EvaluateBSDF_RaytracedReflection(context, bsdfData, preLightData, reflection, reflectionHierarchyWeight, lightHierarchyData); AccumulateIndirectLighting(lighting, aggregateLighting); } @@ -97,7 +105,7 @@ void LightLoop( float3 V, PositionInputs posInput, PreLightData preLightData, BS // Define macro for a better understanding of the loop // TODO: this code is now much harder to understand... #define EVALUATE_BSDF_ENV_SKY(envLightData, TYPE, type) \ - IndirectLighting lighting = EvaluateBSDF_Env(context, V, posInput, preLightData, envLightData, bsdfData, envLightData.influenceShapeType, MERGE_NAME(GPUIMAGEBASEDLIGHTINGTYPE_, TYPE), MERGE_NAME(type, HierarchyWeight)); \ + IndirectLighting lighting = EvaluateBSDF_Env(context, V, posInput, preLightData, envLightData, bsdfData, envLightData.influenceShapeType, MERGE_NAME(GPUIMAGEBASEDLIGHTINGTYPE_, TYPE), MERGE_NAME(type, HierarchyWeight), lightHierarchyData); \ AccumulateIndirectLighting(lighting, aggregateLighting); // Environment cubemap test lightlayers, sky don't test it From 28b080ccbde6f71ae72b10cf7271e6a7af5af196 Mon Sep 17 00:00:00 2001 From: slunity Date: Fri, 9 Apr 2021 19:47:02 -0400 Subject: [PATCH 07/12] Deferred Raytraced Reflections: Fix deferred lighting half-res intersection position calculations. -In the deferred reflection lighting compute, a subtle issue existed where the depth loaded in half res was not necessarily the same as in every other passes eg for the ray launch contrary to the comments (RaytracingReflections.compute to generate directions, RaytracingGBuffer.raytrace for the raygen, RaytracingReflectionFilter.compute for the light weights and upscale) -Also add defines for magic values in ray intersection distance buffer -Add some notes about early out conditions --- .../Deferred/RaytracingDeferred.compute | 27 ++++++++++++++----- .../Deferred/RaytracingGBuffer.raytrace | 2 +- .../Raytracing/Shaders/RayTracingCommon.hlsl | 20 ++++++++++++++ .../RaytracingReflectionFilter.compute | 20 ++++++++++++++ .../ShaderPassRaytracingGBuffer.hlsl | 3 ++- 5 files changed, 64 insertions(+), 8 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Deferred/RaytracingDeferred.compute b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Deferred/RaytracingDeferred.compute index ab85cd79ffb..8f6a6bea03d 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Deferred/RaytracingDeferred.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Deferred/RaytracingDeferred.compute @@ -30,6 +30,7 @@ #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingLightLoop.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Common/AtmosphericScatteringRayTracing.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/RayTracingFallbackHierarchy.cs.hlsl" +#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingCommon.hlsl" #define RAYTRACING_DEFERRED_TILE_SIZE 8 @@ -47,7 +48,11 @@ void RAYTRACING_DEFERRED(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 gro // Compute the pixel position to process uint2 currentCoord = groupId * RAYTRACING_DEFERRED_TILE_SIZE + groupThreadId; + // Pixel coordinate in full res that we will be using to pick depth, normal or smoothness values. + uint2 primaryGeometryCoords = currentCoord; + #ifdef HALF_RESOLUTION + primaryGeometryCoords = ComputeSourceCoordinates(/*halfres coord:*/currentCoord, _RaytracingFrameIndex); currentCoord *=2; #endif @@ -55,15 +60,19 @@ void RAYTRACING_DEFERRED(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 gro _RaytracingLitBufferRW[COORD_TEXTURE2D_X(currentCoord)] = float4(0.0, 0.0, 0.0, 0.0); // Read the depth value - float depthValue = LOAD_TEXTURE2D_X(_DepthTexture, currentCoord).x; + float depthValue = LOAD_TEXTURE2D_X(_DepthTexture, primaryGeometryCoords).x; + // TODO: depthValue test useful? Same rationale as in RaytracingReflectionFilter.compute, but here we will use the loaded direction data if we continue. // If this is a background pixel or an invalid ray, leave right away if (depthValue == UNITY_RAW_FAR_CLIP_VALUE || LOAD_TEXTURE2D_X(_RaytracingDirectionBuffer, currentCoord).w < 0.0f) return; // First let's compute the position of the pixel from which the ray has been shot - PositionInputs sourcePosInput = GetPositionInput(currentCoord, _ScreenSize.zw, depthValue, UNITY_MATRIX_I_VP, GetWorldToViewMatrix(), 0); + PositionInputs sourcePosInput = GetPositionInput(primaryGeometryCoords, _ScreenSize.zw, depthValue, UNITY_MATRIX_I_VP, GetWorldToViewMatrix(), 0); // Fetch the intersection distance of the ray + // See ClosestHit in ShaderPassRaytracingGBuffer.hlsl or MissShaderGBuffer in RaytracingGBuffer.raytrace: + // We use rayhit distance = -1 to indicate unlit or 0 for probes/sky (miss shader). + // In those cases no lighting (ie lightloop) is needed, but a fallback on probes/sky might need to be sampled. float rayDistance = LOAD_TEXTURE2D_X(_RaytracingDistanceBuffer, currentCoord).x; // Fetch the direction of the ray @@ -71,7 +80,7 @@ void RAYTRACING_DEFERRED(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 gro float3 finalColor = 0.0f; // if the distance is exactly zero, this means we are facing an environement ray that we need to evaluate - if (rayDistance == 0.0f) + if (RayDistanceIndicatesHitSky(rayDistance)) { // Weight value used to do the blending float weight = 0.0; @@ -88,13 +97,14 @@ void RAYTRACING_DEFERRED(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 gro if (weight > 0.0) ApplyFogAttenuation(sourcePosInput.positionWS, rayDirection, finalColor); } - else if (rayDistance < 0.0f) + else if (RayDistanceIndicatesUnlit(rayDistance)) { + // The unlit color result was written to _GBufferTexture3. finalColor = LOAD_TEXTURE2D_X(_GBufferTexture3, currentCoord).rgb; } - // If the distance is negative, this means it is a sky pixel or an unlit material - if (rayDistance <= 0.0f) + // If the distance is negative or zero, this means it is a probe/sky pixel or an unlit material + if (RayDistanceIndicatesUnlitOrSky(rayDistance)) { // Convert to HSV space finalColor = RgbToHsv(finalColor * GetCurrentExposureMultiplier()); @@ -109,6 +119,11 @@ void RAYTRACING_DEFERRED(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 gro // Then compute the pos input of the intersection vertice float3 intersectionPositionWS = sourcePosInput.positionWS + rayDirection * rayDistance; + // Note: Using currentCoord here is not a typo (vs primaryGeometryCoords): the function below will set + // posInput.positionWS = intersectionPositionWS, but we have to have the SS and NDC match those used + // when the data has been written in the gbuffers so that DecodeFromGBuffer() and the lightloop will work correctly. + // ie we match the adressing scheme used when writing to _GBufferTexture*RW + // in the deferred reflections raygen shader RaytracingGBuffer.raytrace. PositionInputs posInput = GetPositionInput(currentCoord, _ScreenSize.zw, intersectionPositionWS); // Read the bsdf data and builtin data from the gbuffer diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Deferred/RaytracingGBuffer.raytrace b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Deferred/RaytracingGBuffer.raytrace index 83e2613c17c..09fd6642cc6 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Deferred/RaytracingGBuffer.raytrace +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Deferred/RaytracingGBuffer.raytrace @@ -56,7 +56,7 @@ int _RayCountType; [shader("miss")] void MissShaderGBuffer(inout RayIntersectionGBuffer rayIntersection : SV_RayPayload) { - rayIntersection.t = 0; + rayIntersection.t = DEFERRED_RAY_DISTANCE_SKY; } struct PixelCoordinates diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingCommon.hlsl b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingCommon.hlsl index 6ae0d642877..7a7cc4e551d 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingCommon.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingCommon.hlsl @@ -57,4 +57,24 @@ uint2 ComputeSourceCoordinates(uint2 halfResCoord, int frameIndex) { return halfResCoord * 2; } + +// These need to be negative for RayDistanceIndicatesHitSkyOrUnlit +#define DEFERRED_RAY_DISTANCE_UNLIT (-1.0) +#define DEFERRED_RAY_DISTANCE_SKY (0.0) + +bool RayDistanceIndicatesUnlit(float rayDistance) +{ + return(rayDistance < 0.0); +} + +bool RayDistanceIndicatesHitSky(float rayDistance) +{ + return(rayDistance == DEFERRED_RAY_DISTANCE_SKY); +} + +bool RayDistanceIndicatesUnlitOrSky(float rayDistance) +{ + return(rayDistance <= 0.0); +} + #endif // RAY_TRACING_COMMON_HLSL diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingReflectionFilter.compute b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingReflectionFilter.compute index 064b143fae9..c759d98c33f 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingReflectionFilter.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingReflectionFilter.compute @@ -55,6 +55,9 @@ void ReflectionRescaleAndAdjustWeight(uint3 dispatchThreadId : SV_DispatchThread // Fetch the depth float depth = LOAD_TEXTURE2D_X(_DepthTexture, centerGeometryCoord).x; + // TODO: Check perf vs removing this and the test on detph. + // Maybe faster to always do small depth load here and then larger directionpdf load? + // See below for rationale (RaytracingReflections.compute, _RaytracingDirectionBuffer.w will be < 0.0f in this case anyway) // Fetch the normal NormalData normalData; @@ -69,6 +72,13 @@ void ReflectionRescaleAndAdjustWeight(uint3 dispatchThreadId : SV_DispatchThread // Duplicating same early out condition we do on reflection dispatchrays as that info is 1/2 res while we need full res granularity here. // Also, this operates on data we fetch anyway, while the _SsrLightingTextureRW at central pixel is needed only if that pixel contributes to filtering below. float perceptualSmoothness = PerceptualRoughnessToPerceptualSmoothness(normalData.perceptualRoughness); + // Note the condition + // (depth[ComputeSourceCoordinates(halfResCoord, _RaytracingFrameIndex)] == UNITY_RAW_FAR_CLIP_VALUE) + // is already included in + // (_DirectionPDFTexture[(halfResCoord * 2)] < 0.0), + // see the deferred reflection direction and PDF generation kernels, RaytracingReflectionsHalfRes and RaytracingReflectionsFullRes. + // (ie even for the half res case not only the condition is included but we also match the source coords for the respective buffers). + // TODO: if (perceptualSmoothness < _RaytracingReflectionMinSmoothness || LOAD_TEXTURE2D_X(_DirectionPDFTexture, fullResCoord).w < 0.0) if (depth == UNITY_RAW_FAR_CLIP_VALUE || perceptualSmoothness < _RaytracingReflectionMinSmoothness || LOAD_TEXTURE2D_X(_DirectionPDFTexture, fullResCoord).w < 0.0) { _RaytracingReflectionTexture[COORD_TEXTURE2D_X(halfResCoord)] = float4(0.0f, 0.0f, 0.0f, 0.0f); @@ -90,6 +100,9 @@ void ReflectionAdjustWeight(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 // Fetch the depth and normal float depth = LOAD_TEXTURE2D_X(_DepthTexture, targetCoord).x; + // TODO: Check perf if removing this and the test on detph. + // Maybe faster to always do small depth load and then directionpdf load? + // See below for rationale (RaytracingReflections.compute, _RaytracingDirectionBuffer.w will be < 0.0f in this case anyway) NormalData normalData; DecodeFromNormalBuffer(targetCoord, normalData); @@ -102,6 +115,13 @@ void ReflectionAdjustWeight(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 // Duplicating same early out condition we do on reflection dispatchrays as that info is 1/2 res while we need full res granularity here. // Also, this operates on data we fetch anyway, while the _SsrLightingTextureRW at central pixel is needed only if that pixel contributes to filtering below. float perceptualSmoothness = PerceptualRoughnessToPerceptualSmoothness(normalData.perceptualRoughness); + // Note the condition + // (depth[targetCoord] == UNITY_RAW_FAR_CLIP_VALUE) + // is already included in + // (_DirectionPDFTexture[targetCoord] < 0.0), + // see the deferred reflection direction and PDF generation kernels, RaytracingReflectionsHalfRes and RaytracingReflectionsFullRes in RaytracingReflections.compute. + // (ie even for the half res case not only the condition is included but we also match the source coords for the respective buffers). + // TODO: if (perceptualSmoothness < _RaytracingReflectionMinSmoothness || LOAD_TEXTURE2D_X(_DirectionPDFTexture, targetCoord).w < 0.0) if (depth == UNITY_RAW_FAR_CLIP_VALUE || perceptualSmoothness < _RaytracingReflectionMinSmoothness || LOAD_TEXTURE2D_X(_DirectionPDFTexture, targetCoord).w < 0.0) { _RaytracingReflectionTexture[COORD_TEXTURE2D_X(targetCoord)] = float4(0.0f, 0.0f, 0.0f, 0.0f); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassRaytracingGBuffer.hlsl b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassRaytracingGBuffer.hlsl index b649a530381..412b6ff66c4 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassRaytracingGBuffer.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassRaytracingGBuffer.hlsl @@ -1,4 +1,5 @@ #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingFragInputs.hlsl" +#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingCommon.hlsl" // Generic function that handles the reflection code [shader("closesthit")] @@ -50,7 +51,7 @@ void ClosestHitGBuffer(inout RayIntersectionGBuffer rayIntersectionGbuffer : SV_ // Then export it to the gbuffer EncodeIntoStandardGBuffer(standardLitData, rayIntersectionGbuffer.gbuffer0, rayIntersectionGbuffer.gbuffer1, rayIntersectionGbuffer.gbuffer2, rayIntersectionGbuffer.gbuffer3); - rayIntersectionGbuffer.t = standardLitData.isUnlit != 0 ? -1 : RayTCurrent(); + rayIntersectionGbuffer.t = standardLitData.isUnlit != 0 ? DEFERRED_RAY_DISTANCE_UNLIT : RayTCurrent(); } // Generic function that handles the reflection code From dada1195aef4f62012b2cd116b4856e78c2adf58 Mon Sep 17 00:00:00 2001 From: slunity Date: Sat, 10 Apr 2021 20:46:39 -0400 Subject: [PATCH 08/12] Raytraced Reflections: Use the correct roughness for coated materials for the denoiser logic. Also fix uninitialized deferred (performance) light reflections adjustweight kernel (it was kernel # 0 so it worked). -The coatmask was ignored in the denoiser, which made the base smoothness affect the denoising of the raytraced coat reflections -fix uninitialized deferred (performance mode) light reflections adjustweight kernel (it was kernel # 0 so it worked). -In quality mode, also add internally an option to consider AffectSmoothSurfaces accumulation flag to escape sampling in the ray dispatch if we're going to use a single sample and skip the temporal accumulation later --- .../Raytracing/HDReflectionDenoiser.cs | 7 +++- .../HDRenderPipeline.RaytracingReflection.cs | 4 ++ .../Shaders/Denoising/BilateralFilter.hlsl | 4 +- .../Denoising/ReflectionDenoiser.compute | 16 ++++++-- .../Shaders/RayTracingReflectionCommon.hlsl | 19 +++++++++ .../RayTracingReflectionCommon.hlsl.meta | 10 +++++ .../RaytracingReflections.raytrace | 39 ++++++++++++++----- 7 files changed, 84 insertions(+), 15 deletions(-) create mode 100644 com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingReflectionCommon.hlsl create mode 100644 com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingReflectionCommon.hlsl.meta diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDReflectionDenoiser.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDReflectionDenoiser.cs index 77b36d08542..b43195e806d 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDReflectionDenoiser.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDReflectionDenoiser.cs @@ -67,6 +67,7 @@ class ReflectionDenoiserPassData public TextureHandle depthBuffer; public TextureHandle historyDepth; public TextureHandle normalBuffer; + public TextureHandle clearCoatMaskBuffer; public TextureHandle motionVectorBuffer; public TextureHandle intermediateBuffer0; public TextureHandle intermediateBuffer1; @@ -75,7 +76,7 @@ class ReflectionDenoiserPassData } public TextureHandle DenoiseRTR(RenderGraph renderGraph, HDCamera hdCamera, float historyValidity, int maxKernelSize, bool fullResolution, bool singleReflectionBounce, bool affectSmoothSurfaces, - TextureHandle depthPyramid, TextureHandle normalBuffer, TextureHandle motionVectorBuffer, TextureHandle clearCoatTexture, TextureHandle lightingTexture, RTHandle historyBuffer) + TextureHandle depthPyramid, TextureHandle normalBuffer, TextureHandle motionVectorBuffer, TextureHandle clearCoatMaskBuffer, TextureHandle lightingTexture, RTHandle historyBuffer) { using (var builder = renderGraph.AddRenderPass("Denoise ray traced reflections", out var passData, ProfilingSampler.Get(HDProfileId.RaytracingReflectionFilter))) { @@ -106,6 +107,7 @@ public TextureHandle DenoiseRTR(RenderGraph renderGraph, HDCamera hdCamera, floa passData.depthBuffer = builder.ReadTexture(depthPyramid); passData.normalBuffer = builder.ReadTexture(normalBuffer); passData.motionVectorBuffer = builder.ReadTexture(motionVectorBuffer); + passData.clearCoatMaskBuffer = builder.ReadTexture(clearCoatMaskBuffer); RTHandle depthT = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.Depth); passData.historyDepth = depthT != null ? renderGraph.ImportTexture(hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.Depth)) : renderGraph.defaultResources.blackTextureXR; @@ -136,6 +138,7 @@ public TextureHandle DenoiseRTR(RenderGraph renderGraph, HDCamera hdCamera, floa ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.temporalAccumulationKernel, HDShaderIDs._NormalBufferTexture, data.normalBuffer); ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.temporalAccumulationKernel, HDShaderIDs._CameraMotionVectorsTexture, data.motionVectorBuffer); ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.temporalAccumulationKernel, HDShaderIDs._HistoryBuffer, data.historySignal); + ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.temporalAccumulationKernel, HDShaderIDs._SsrClearCoatMaskTexture, data.clearCoatMaskBuffer); // Output texture ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.temporalAccumulationKernel, HDShaderIDs._DenoiseOutputTextureRW, data.intermediateBuffer0); @@ -155,6 +158,7 @@ public TextureHandle DenoiseRTR(RenderGraph renderGraph, HDCamera hdCamera, floa ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.bilateralFilterHKernel, HDShaderIDs._DenoiseInputTexture, data.intermediateBuffer0); ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.bilateralFilterHKernel, HDShaderIDs._DepthTexture, data.depthBuffer); ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.bilateralFilterHKernel, HDShaderIDs._NormalBufferTexture, data.normalBuffer); + ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.bilateralFilterHKernel, HDShaderIDs._SsrClearCoatMaskTexture, data.clearCoatMaskBuffer); ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.bilateralFilterHKernel, HDShaderIDs._DenoiseOutputTextureRW, data.intermediateBuffer1); ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.bilateralFilterHKernel, HDShaderIDs._ReflectionFilterMapping, data.reflectionFilterMapping); ctx.cmd.DispatchCompute(data.reflectionDenoiserCS, data.bilateralFilterHKernel, numTilesX, numTilesY, data.viewCount); @@ -164,6 +168,7 @@ public TextureHandle DenoiseRTR(RenderGraph renderGraph, HDCamera hdCamera, floa ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.bilateralFilterVKernel, HDShaderIDs._DenoiseInputTexture, data.intermediateBuffer1); ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.bilateralFilterVKernel, HDShaderIDs._DepthTexture, data.depthBuffer); ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.bilateralFilterVKernel, HDShaderIDs._NormalBufferTexture, data.normalBuffer); + ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.bilateralFilterVKernel, HDShaderIDs._SsrClearCoatMaskTexture, data.clearCoatMaskBuffer); ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.bilateralFilterVKernel, HDShaderIDs._DenoiseOutputTextureRW, data.noisyToOutputSignal); ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.bilateralFilterVKernel, HDShaderIDs._ReflectionFilterMapping, data.reflectionFilterMapping); ctx.cmd.DispatchCompute(data.reflectionDenoiserCS, data.bilateralFilterVKernel, numTilesX, numTilesY, data.viewCount); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDRenderPipeline.RaytracingReflection.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDRenderPipeline.RaytracingReflection.cs index 8b27ed2dfe2..1c70d36bef0 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDRenderPipeline.RaytracingReflection.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDRenderPipeline.RaytracingReflection.cs @@ -32,6 +32,7 @@ void InitRayTracedReflections() m_RaytracingReflectionsTransparentFullResKernel = reflectionShaderCS.FindKernel("RaytracingReflectionsTransparentFullRes"); m_RaytracingReflectionsTransparentHalfResKernel = reflectionShaderCS.FindKernel("RaytracingReflectionsTransparentHalfRes"); m_ReflectionAdjustWeightKernel = reflectionBilateralFilterCS.FindKernel("ReflectionAdjustWeight"); + m_ReflectionRescaleAndAdjustWeightKernel = reflectionBilateralFilterCS.FindKernel("ReflectionRescaleAndAdjustWeight"); m_ReflectionUpscaleKernel = reflectionBilateralFilterCS.FindKernel("ReflectionUpscale"); } @@ -410,6 +411,7 @@ class TraceQualityRTRPassData public float smoothnessFadeStart; public float lodBias; public int fallbackHierarchy; + public int historyAffectSmoothSurfaces; // Other parameters public RayTracingAccelerationStructure accelerationStructure; @@ -450,6 +452,7 @@ TextureHandle QualityRTR(RenderGraph renderGraph, HDCamera hdCamera, ScreenSpace passData.smoothnessFadeStart = settings.smoothnessFadeStart; passData.lodBias = settings.textureLodBias.value; passData.fallbackHierarchy = (int)settings.fallbackHierachy.value; + passData.historyAffectSmoothSurfaces = settings.affectSmoothSurfaces ? 1 : 0; // Other parameters passData.accelerationStructure = RequestAccelerationStructure(); @@ -500,6 +503,7 @@ TextureHandle QualityRTR(RenderGraph renderGraph, HDCamera hdCamera, ScreenSpace ctx.cmd.SetRayTracingTextureParam(data.reflectionShader, HDShaderIDs._NormalBufferTexture, data.normalBuffer); ctx.cmd.SetGlobalTexture(HDShaderIDs._StencilTexture, data.stencilBuffer, RenderTextureSubElement.Stencil); ctx.cmd.SetRayTracingIntParams(data.reflectionShader, HDShaderIDs._SsrStencilBit, (int)StencilUsage.TraceReflectionRay); + ctx.cmd.SetRayTracingIntParams(data.reflectionShader, HDShaderIDs._AffectSmoothSurfaces, data.historyAffectSmoothSurfaces); // Set ray count texture ctx.cmd.SetRayTracingTextureParam(data.reflectionShader, HDShaderIDs._RayCountTexture, data.rayCountTexture); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Denoising/BilateralFilter.hlsl b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Denoising/BilateralFilter.hlsl index 0e00d364410..1222e2a6679 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Denoising/BilateralFilter.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Denoising/BilateralFilter.hlsl @@ -26,7 +26,7 @@ struct BilateralData float z01; float zNF; float3 normal; - #ifdef BILATERAL_ROUGHNESS + #ifdef BILATERAL_ROUGHNESS // in that case, _SsrClearCoatMaskTexture is required float roughness; #endif }; @@ -56,6 +56,8 @@ BilateralData TapBilateralData(uint2 coordSS) DecodeFromNormalBuffer(normalBuffer, normalData); key.normal = normalData.normalWS; #ifdef BILATERAL_ROUGHNESS + const float4 coatMask = LOAD_TEXTURE2D_X(_SsrClearCoatMaskTexture, coordSS); + normalData.perceptualRoughness = HasClearCoatMask(coatMask) ? CLEAR_COAT_PERCEPTUAL_ROUGHNESS : normalData.perceptualRoughness; key.roughness = normalData.perceptualRoughness; #endif } diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Denoising/ReflectionDenoiser.compute b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Denoising/ReflectionDenoiser.compute index 9791e1de7a7..bb0190d7486 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Denoising/ReflectionDenoiser.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Denoising/ReflectionDenoiser.compute @@ -11,11 +11,14 @@ #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/Lighting/ScreenSpaceLighting/ScreenSpaceLighting.hlsl" +#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingReflectionCommon.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingSampling.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Builtin/BuiltinData.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/TemporalAntialiasing.hlsl" #define BILATERAL_ROUGHNESS +TEXTURE2D_X(_SsrClearCoatMaskTexture); #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Denoising/BilateralFilter.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Denoising/DenoisingUtils.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/ShaderVariablesRaytracing.cs.hlsl" @@ -26,9 +29,9 @@ // #pragma enable_d3d11_debug_symbols -// Thereshold at which we decide to reject the reflection history +// Threshold at which we decide to reject the reflection history #define REFLECTION_HISTORY_REJECTION_THRESHOLD 0.75 -// Threshold at which we go from accumulation to clampiong +// Threshold at which we go from accumulation to clamping #define ROUGHNESS_ACCUMULATION_THRESHOLD 0.5 // Input textures @@ -75,9 +78,11 @@ void TEMPORAL_ACCUMULATION(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 g return; } - // Real the normal data for this pixel + // Read and decode the normal data NormalData normalData; DecodeFromNormalBuffer(geometryCoords, normalData); + float4 coatMask = LOAD_TEXTURE2D_X(_SsrClearCoatMaskTexture, geometryCoords); + normalData.perceptualRoughness = HasClearCoatMask(coatMask) ? CLEAR_COAT_PERCEPTUAL_ROUGHNESS : normalData.perceptualRoughness; // Read the depth and velocity vectors float2 velocity; @@ -93,7 +98,10 @@ void TEMPORAL_ACCUMULATION(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 g float4 historyRaw = Fetch4(_HistoryBuffer, historyUV, 0.0, 1.0); float3 history = historyRaw.xyz * GetCurrentExposureMultiplier(); - if (_AffectSmoothSurfaces == 0 && _SingleReflectionBounce == 1 && PerceptualRoughnessToPerceptualSmoothness(normalData.perceptualRoughness) > 0.99) + // If this is close to a perfectly smooth surface, we may not want to use the history (depending on _AffectSmoothSurfaces) + // In thise case, see RaytracingReflections.raytrace: make sure we don't sample otherwise we could have noisy artifacts. + // Keep in sync with the sampling in the raygen program in RaytracingReflections.raytrace (along with _SingleReflectionBounce here vs _RaytracingMaxRecursion in the former) + if (SkipReflectionDenoiserHistoryAccumulation((_AffectSmoothSurfaces == 1), (_SingleReflectionBounce == 1), normalData.perceptualRoughness)) { _DenoiseOutputTextureRW[COORD_TEXTURE2D_X(mainCoord)] = float4(color * GetInverseCurrentExposureMultiplier(), LOAD_TEXTURE2D_X(_DenoiseInputTexture, mainCoord).w); _SampleCountTextureRW[COORD_TEXTURE2D_X(mainCoord)] = 1; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingReflectionCommon.hlsl b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingReflectionCommon.hlsl new file mode 100644 index 00000000000..f0db94b7250 --- /dev/null +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingReflectionCommon.hlsl @@ -0,0 +1,19 @@ +#ifndef RAY_TRACING_REFLECTION_COMMON_HLSL +#define RAY_TRACING_REFLECTION_COMMON_HLSL + +// When doing RTR with one reflection bounce, this defines the max smoothness beyond which we won't sample +// (used in both raygen and the reflection denoiser) +#define REFLECTION_SAMPLING_MAX_ROUGHNESS_THRESHOLD (1.0-0.99) +// TODO note: kept the value as before merge, as a perceptual smoothness value == 0.99, but this means +// that eg with CLEAR_COAT_ROUGHNESS defined for Lit in CommonMaterial to be 0.01, +// perceptualRoughness(CLEAR_COAT_ROUGHNESS) is 0.01^0.5 = 0.1, so perceptualSmoothness is 0.9. +// This means that clear coat wouldn't be considered "smooth" with the threshold above. + +bool SkipReflectionDenoiserHistoryAccumulation(bool affectSmoothSurfaces, bool singleReflectionBounce, float perceptualRoughness) +{ + bool isSmooth = perceptualRoughness < REFLECTION_SAMPLING_MAX_ROUGHNESS_THRESHOLD; + bool dontAllowAccumulation = (!affectSmoothSurfaces && isSmooth && singleReflectionBounce); + return dontAllowAccumulation; +} + +#endif // RAY_TRACING_REFLECTION_COMMON_HLSL diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingReflectionCommon.hlsl.meta b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingReflectionCommon.hlsl.meta new file mode 100644 index 00000000000..790f4759bf3 --- /dev/null +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingReflectionCommon.hlsl.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7669d04a6e4ae17418a6458c842a7e93 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + preprocessorOverride: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Reflections/RaytracingReflections.raytrace b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Reflections/RaytracingReflections.raytrace index a5585200022..147b5296ba3 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Reflections/RaytracingReflections.raytrace +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Reflections/RaytracingReflections.raytrace @@ -1,4 +1,3 @@ -// We need only need one bounce given that we want to see the objects and then direct lighting is not done using raytracing #pragma max_recursion_depth 31 #define HAS_LIGHTLOOP @@ -29,6 +28,7 @@ #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingIntersection.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingSampling.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingCommon.hlsl" +#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingReflectionCommon.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceLighting.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Common/AtmosphericScatteringRayTracing.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/RayCountManager.cs.hlsl" @@ -41,6 +41,7 @@ TEXTURE2D_X(_SsrClearCoatMaskTexture); // Flag value that defines if a given pixel recieves reflections or not TEXTURE2D_X_UINT2(_StencilTexture); int _SsrStencilBit; +int _AffectSmoothSurfaces; // see ReflectionDenoiser.compute: if history accumulation is used for smooth surfaces // Output structure of the reflection raytrace shader RW_TEXTURE2D_X(float4, _SsrLightingTextureRW); @@ -117,14 +118,33 @@ void RayGenIntegration() if (_RaytracingReflectionMinSmoothness > perceptualSmoothness) return; - // Compute the actual roughness - float roughness = PerceptualRoughnessToRoughness(normalData.perceptualRoughness); - - // If we only have one bounce, we don't need more than one ray to evaluate the exact signal. However, if we are going for multiple bounces, we may need more, so we cannot clamp the sample count to 1. - int realSampleCount = _RaytracingMaxRecursion == 1 ? (normalData.perceptualRoughness < 0.01 ? 1 : _RaytracingNumSamples) : _RaytracingNumSamples; + // Mirror what the denoiser will do: if we know it will escape history accumulation, don't sample. + // Keep in sync with the denoiser in ReflectionDenoiser.compute! (along with _RaytracingMaxRecursion here vs _SingleReflectionBounce in the former) + bool allowSampling = !SkipReflectionDenoiserHistoryAccumulation((_AffectSmoothSurfaces == 1), (_RaytracingMaxRecursion == 1), normalData.perceptualRoughness); + allowSampling = true; + // TODO: Subtle, forcing allowSampling = true is the behavior before merge: always allow sampling even if we end up sampling a single sample, + // which could even end up not sampling at all (eg under surface) or being an outlier. + // This will show as sharp "speckles" (because the surface is smooth) when we don't have history accumulation (ie when _AffectSmoothSurfaces == 0) + // + // TODO: In the case we use !SkipReflectionDenoiserHistoryAccumulation to escape sampling, is _AffectSmoothSurfaces even useful then? + // ie if accumulation gave too much ghosting for smooth surfaces, then systematically disable it (_AffectSmoothSurfaces == 0), but dont sample + // here either (ie check allowSampling = !SkipReflectionDenoiserHistoryAccumulation) like done now. + + // If we only have one bounce, we don't need more than one ray to evaluate the exact signal of smooth surfaces. + // However, if we are going for multiple bounces, we may need more, so we cannot clamp the sample count to 1. + int realSampleCount = _RaytracingMaxRecursion == 1 ? (normalData.perceptualRoughness < REFLECTION_SAMPLING_MAX_ROUGHNESS_THRESHOLD ? 1 : _RaytracingNumSamples) + : _RaytracingNumSamples; + // ...note that the compiler will optimize the subexpressions between the above and the SkipReflectionDenoiserHistoryAccumulation() call + // Also note we don't need to further check allowSampling to clamp realSampleCount: + // realSampleCount will always be 1 if we dont allowSampling, which is what we would want in the loop below, + // and even if we allowSampling, realSampleCount could still be clamped to 1. // Variable that accumulate the radiance float3 finalColor = float3(0.0, 0.0, 0.0); + // Ray dir if we escape sampling altogether + float3 defaultSampleDir = reflect(-viewWS, normalData.normalWS); + // Compute the actual roughness + float roughness = PerceptualRoughnessToRoughness(normalData.perceptualRoughness); // Loop through the samples and add their contribution for (int sampleIndex = 0; sampleIndex < realSampleCount; ++sampleIndex) @@ -137,10 +157,11 @@ void RayGenIntegration() theSample.x = GetBNDSequenceSample(currentCoord, globalSampleIndex, 0); theSample.y = GetBNDSequenceSample(currentCoord, globalSampleIndex, 1); - // Importance sample the direction using GGX - float3 sampleDir = float3(0.0, 0.0, 0.0); + float3 sampleDir = defaultSampleDir; float NdotL, NdotH, VdotH; - SampleGGXDir(theSample, viewWS, localToWorld, roughness, sampleDir, NdotL, NdotH, VdotH); + // Importance sample the direction using GGX + if (allowSampling) + SampleGGXDir(theSample, viewWS, localToWorld, roughness, sampleDir, NdotL, NdotH, VdotH); // If the sample is under the surface if (dot(sampleDir, normalData.normalWS) <= 0.0) From 0503d1f59437065f3b57f1c924037225c33e7bdb Mon Sep 17 00:00:00 2001 From: slunity Date: Tue, 13 Apr 2021 16:23:24 -0400 Subject: [PATCH 09/12] Raytraced reflections: Add a raytraced reflection fallback mode to always use the pre-integrated probes or sky even with raytraced reflections. --- .../RenderGraphDefaultResources.cs | 5 + .../Camera/HDCameraFrameHistoryType.cs | 2 + .../RenderPipeline/HDRenderPipeline.cs | 4 +- .../RenderPipeline/HDStringConstants.cs | 2 + .../Raytracing/HDReflectionDenoiser.cs | 56 ++++-- .../HDRenderPipeline.RaytracingReflection.cs | 30 ++- .../Raytracing/RayTracingFallbackHierarchy.cs | 6 + .../RayTracingFallbackHierarchy.cs.hlsl | 1 + .../Deferred/RaytracingDeferred.compute | 10 +- .../Denoising/ReflectionDenoiser.compute | 189 +++++++++++++----- .../RaytracingReflectionFilter.compute | 11 +- .../RaytracingReflections.raytrace | 18 +- 12 files changed, 255 insertions(+), 79 deletions(-) diff --git a/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphDefaultResources.cs b/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphDefaultResources.cs index da84c8468c9..f416ef3026a 100644 --- a/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphDefaultResources.cs +++ b/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphDefaultResources.cs @@ -13,6 +13,8 @@ public class RenderGraphDefaultResources RTHandle m_BlackTexture2D; RTHandle m_WhiteTexture2D; + public RTHandle emptyReadWriteXRRTH { get; private set; } + /// Default black 2D texture. public TextureHandle blackTexture { get; private set; } /// Default white 2D texture. @@ -36,12 +38,15 @@ internal RenderGraphDefaultResources() { m_BlackTexture2D = RTHandles.Alloc(Texture2D.blackTexture); m_WhiteTexture2D = RTHandles.Alloc(Texture2D.whiteTexture); + emptyReadWriteXRRTH = RTHandles.Alloc(Vector2.zero, TextureXR.slices, colorFormat: GraphicsFormat.R8_UNorm, dimension: TextureXR.dimension, + enableRandomWrite: true, useMipMap: false, autoGenerateMips: false, name: "DefaultResource_Dummy_ReadWrite"); } internal void Cleanup() { m_BlackTexture2D.Release(); m_WhiteTexture2D.Release(); + emptyReadWriteXRRTH.Release(); } internal void InitializeForRendering(RenderGraph renderGraph) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs index 12a35dc8f1f..fdfec71653d 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs @@ -49,6 +49,8 @@ public enum HDCameraFrameHistoryType VolumetricClouds1, /// Screen Space Reflection Accumulation. ScreenSpaceReflectionAccumulation, + /// Ray traced reflections sample count buffer (if needed when using ray miss ratio in .w channel of SSR-RTR buffer). + RaytracedReflectionSampleCount, /// Number of history buffers. Count // TODO: Obsolete } diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index db2b781170c..60013eaac04 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -205,7 +205,7 @@ internal int GetMaxScreenSpaceShadows() bool frozenCullingParamAvailable = false; // RENDER GRAPH - RenderGraph m_RenderGraph = new RenderGraph("HDRP"); + RenderGraph m_RenderGraph = null; // MSAA resolve materials Material m_ColorResolveMaterial = null; @@ -323,6 +323,8 @@ public HDRenderPipeline(HDRenderPipelineAsset asset) m_XRSystem = new XRSystem(asset.renderPipelineResources.shaders); + m_RenderGraph = new RenderGraph("HDRP"); + m_MipGenerator = new MipGenerator(defaultResources); m_BlueNoise = new BlueNoise(defaultResources); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs index 1325a9533e7..8b0524202b3 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs @@ -593,6 +593,7 @@ static class HDShaderIDs public static readonly int _ValidationBufferRW = Shader.PropertyToID("_ValidationBufferRW"); public static readonly int _HistoryDepthTexture = Shader.PropertyToID("_HistoryDepthTexture"); public static readonly int _HistoryNormalTexture = Shader.PropertyToID("_HistoryNormalTexture"); + public static readonly int _HistorySampleCountTexture = Shader.PropertyToID("_HistorySampleCountTexture"); public static readonly int _RaytracingDenoiseRadius = Shader.PropertyToID("_RaytracingDenoiseRadius"); public static readonly int _DenoiserFilterRadius = Shader.PropertyToID("_DenoiserFilterRadius"); public static readonly int _NormalHistoryCriterion = Shader.PropertyToID("_NormalHistoryCriterion"); @@ -618,6 +619,7 @@ static class HDShaderIDs public static readonly int _HistoryBufferSize = Shader.PropertyToID("_HistoryBufferSize"); public static readonly int _CurrentEffectResolution = Shader.PropertyToID("_CurrentEffectResolution"); public static readonly int _SampleCountTextureRW = Shader.PropertyToID("_SampleCountTextureRW"); + public static readonly int _HistorySampleCountTextureRW = Shader.PropertyToID("_HistorySampleCountTextureRW"); public static readonly int _AffectSmoothSurfaces = Shader.PropertyToID("_AffectSmoothSurfaces"); public static readonly int _ObjectMotionStencilBit = Shader.PropertyToID("_ObjectMotionStencilBit"); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDReflectionDenoiser.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDReflectionDenoiser.cs index b43195e806d..a3cb156d5ea 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDReflectionDenoiser.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDReflectionDenoiser.cs @@ -9,11 +9,18 @@ class HDReflectionDenoiser Texture2D m_ReflectionFilterMapping; int s_TemporalAccumulationFullResKernel; int s_TemporalAccumulationHalfResKernel; + int s_TemporalAccumulationFullResMissWeightedKernel; + int s_TemporalAccumulationHalfResMissWeightedKernel; int s_CopyHistoryKernel; + int s_CopyHistoryMissWeightedKernel; int s_BilateralFilterH_FRKernel; int s_BilateralFilterV_FRKernel; int s_BilateralFilterH_HRKernel; int s_BilateralFilterV_HRKernel; + int s_BilateralFilterHMissWeighted_FRKernel; + int s_BilateralFilterVMissWeighted_FRKernel; + int s_BilateralFilterHMissWeighted_HRKernel; + int s_BilateralFilterVMissWeighted_HRKernel; public HDReflectionDenoiser() { @@ -27,11 +34,18 @@ public void Init(HDRenderPipelineRayTracingResources rpRTResources) // Fetch all the kernels we shall be using s_TemporalAccumulationFullResKernel = m_ReflectionDenoiserCS.FindKernel("TemporalAccumulationFullRes"); s_TemporalAccumulationHalfResKernel = m_ReflectionDenoiserCS.FindKernel("TemporalAccumulationHalfRes"); + s_TemporalAccumulationFullResMissWeightedKernel = m_ReflectionDenoiserCS.FindKernel("TemporalAccumulationFullResMissWeighted"); + s_TemporalAccumulationHalfResMissWeightedKernel = m_ReflectionDenoiserCS.FindKernel("TemporalAccumulationHalfResMissWeighted"); s_CopyHistoryKernel = m_ReflectionDenoiserCS.FindKernel("CopyHistory"); + s_CopyHistoryMissWeightedKernel = m_ReflectionDenoiserCS.FindKernel("CopyHistoryMissWeighted"); s_BilateralFilterH_FRKernel = m_ReflectionDenoiserCS.FindKernel("BilateralFilterH_FR"); s_BilateralFilterV_FRKernel = m_ReflectionDenoiserCS.FindKernel("BilateralFilterV_FR"); s_BilateralFilterH_HRKernel = m_ReflectionDenoiserCS.FindKernel("BilateralFilterH_HR"); s_BilateralFilterV_HRKernel = m_ReflectionDenoiserCS.FindKernel("BilateralFilterV_HR"); + s_BilateralFilterHMissWeighted_FRKernel = m_ReflectionDenoiserCS.FindKernel("BilateralFilterHMissWeighted_FR"); + s_BilateralFilterVMissWeighted_FRKernel = m_ReflectionDenoiserCS.FindKernel("BilateralFilterVMissWeighted_FR"); + s_BilateralFilterHMissWeighted_HRKernel = m_ReflectionDenoiserCS.FindKernel("BilateralFilterHMissWeighted_HR"); + s_BilateralFilterVMissWeighted_HRKernel = m_ReflectionDenoiserCS.FindKernel("BilateralFilterVMissWeighted_HR"); } public void Release() @@ -72,11 +86,12 @@ class ReflectionDenoiserPassData public TextureHandle intermediateBuffer0; public TextureHandle intermediateBuffer1; public TextureHandle historySignal; + public TextureHandle historySampleCount; public TextureHandle noisyToOutputSignal; } - public TextureHandle DenoiseRTR(RenderGraph renderGraph, HDCamera hdCamera, float historyValidity, int maxKernelSize, bool fullResolution, bool singleReflectionBounce, bool affectSmoothSurfaces, - TextureHandle depthPyramid, TextureHandle normalBuffer, TextureHandle motionVectorBuffer, TextureHandle clearCoatMaskBuffer, TextureHandle lightingTexture, RTHandle historyBuffer) + public TextureHandle DenoiseRTR(RenderGraph renderGraph, HDCamera hdCamera, float historyValidity, int maxKernelSize, bool fullResolution, bool singleReflectionBounce, bool affectSmoothSurfaces, bool zeroWeightRayMiss, + TextureHandle depthPyramid, TextureHandle normalBuffer, TextureHandle motionVectorBuffer, TextureHandle clearCoatMaskBuffer, TextureHandle lightingTexture, RTHandle historyBuffer, RTHandle historySampleCountBuffer) { using (var builder = renderGraph.AddRenderPass("Denoise ray traced reflections", out var passData, ProfilingSampler.Get(HDProfileId.RaytracingReflectionFilter))) { @@ -98,10 +113,15 @@ public TextureHandle DenoiseRTR(RenderGraph renderGraph, HDCamera hdCamera, floa // Other parameters passData.reflectionDenoiserCS = m_ReflectionDenoiserCS; - passData.temporalAccumulationKernel = fullResolution ? s_TemporalAccumulationFullResKernel : s_TemporalAccumulationHalfResKernel; - passData.copyHistoryKernel = s_CopyHistoryKernel; - passData.bilateralFilterHKernel = fullResolution ? s_BilateralFilterH_FRKernel : s_BilateralFilterH_HRKernel; - passData.bilateralFilterVKernel = fullResolution ? s_BilateralFilterV_FRKernel : s_BilateralFilterV_HRKernel; + + passData.temporalAccumulationKernel = fullResolution ? (zeroWeightRayMiss ? s_TemporalAccumulationFullResMissWeightedKernel : s_TemporalAccumulationFullResKernel) + : (zeroWeightRayMiss ? s_TemporalAccumulationHalfResMissWeightedKernel : s_TemporalAccumulationHalfResKernel); + passData.copyHistoryKernel = zeroWeightRayMiss ? s_CopyHistoryMissWeightedKernel : s_CopyHistoryKernel; + passData.bilateralFilterHKernel = fullResolution ? (zeroWeightRayMiss ? s_BilateralFilterHMissWeighted_FRKernel : s_BilateralFilterH_FRKernel) + : (zeroWeightRayMiss ? s_BilateralFilterHMissWeighted_HRKernel : s_BilateralFilterH_HRKernel); + passData.bilateralFilterVKernel = fullResolution ? (zeroWeightRayMiss ? s_BilateralFilterVMissWeighted_FRKernel : s_BilateralFilterV_FRKernel) + : (zeroWeightRayMiss ? s_BilateralFilterVMissWeighted_HRKernel : s_BilateralFilterV_HRKernel); + passData.reflectionFilterMapping = m_ReflectionFilterMapping; passData.depthBuffer = builder.ReadTexture(depthPyramid); @@ -110,16 +130,17 @@ public TextureHandle DenoiseRTR(RenderGraph renderGraph, HDCamera hdCamera, floa passData.clearCoatMaskBuffer = builder.ReadTexture(clearCoatMaskBuffer); RTHandle depthT = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.Depth); passData.historyDepth = depthT != null ? renderGraph.ImportTexture(hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.Depth)) : renderGraph.defaultResources.blackTextureXR; - passData.intermediateBuffer0 = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "IntermediateTexture0" }); passData.intermediateBuffer1 = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "IntermediateTexture1" }); passData.historySignal = builder.ReadWriteTexture(renderGraph.ImportTexture(historyBuffer)); + passData.historySampleCount = builder.ReadWriteTexture(renderGraph.ImportTexture(historySampleCountBuffer)); passData.noisyToOutputSignal = builder.ReadWriteTexture(lightingTexture); builder.SetRenderFunc((ReflectionDenoiserPassData data, RenderGraphContext ctx) => { + bool bypassBilateralFilter = false; // debug // Evaluate the dispatch parameters int tileSize = 8; int numTilesX = (data.texWidth + (tileSize - 1)) / tileSize; @@ -138,18 +159,27 @@ public TextureHandle DenoiseRTR(RenderGraph renderGraph, HDCamera hdCamera, floa ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.temporalAccumulationKernel, HDShaderIDs._NormalBufferTexture, data.normalBuffer); ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.temporalAccumulationKernel, HDShaderIDs._CameraMotionVectorsTexture, data.motionVectorBuffer); ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.temporalAccumulationKernel, HDShaderIDs._HistoryBuffer, data.historySignal); + ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.temporalAccumulationKernel, HDShaderIDs._HistorySampleCountTexture, data.historySampleCount); ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.temporalAccumulationKernel, HDShaderIDs._SsrClearCoatMaskTexture, data.clearCoatMaskBuffer); // Output texture - ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.temporalAccumulationKernel, HDShaderIDs._DenoiseOutputTextureRW, data.intermediateBuffer0); + if (bypassBilateralFilter) + ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.temporalAccumulationKernel, HDShaderIDs._DenoiseOutputTextureRW, data.noisyToOutputSignal); + else + ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.temporalAccumulationKernel, HDShaderIDs._DenoiseOutputTextureRW, data.intermediateBuffer0); ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.temporalAccumulationKernel, HDShaderIDs._SampleCountTextureRW, data.intermediateBuffer1); // Do the temporal accumulation ctx.cmd.DispatchCompute(data.reflectionDenoiserCS, data.temporalAccumulationKernel, numTilesX, numTilesY, data.viewCount); // Copy the accumulated signal into the history buffer - ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.copyHistoryKernel, HDShaderIDs._DenoiseInputTexture, data.intermediateBuffer0); + if (bypassBilateralFilter) + ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.copyHistoryKernel, HDShaderIDs._DenoiseInputTexture, data.noisyToOutputSignal); + else + ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.copyHistoryKernel, HDShaderIDs._DenoiseInputTexture, data.intermediateBuffer0); ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.copyHistoryKernel, HDShaderIDs._DenoiseOutputTextureRW, data.historySignal); + ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.copyHistoryKernel, HDShaderIDs._HistorySampleCountTextureRW, data.historySampleCount); + // ...always set, #if def guards dont seem to work in compute shader ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.copyHistoryKernel, HDShaderIDs._SampleCountTextureRW, data.intermediateBuffer1); ctx.cmd.DispatchCompute(data.reflectionDenoiserCS, data.copyHistoryKernel, numTilesX, numTilesY, data.viewCount); @@ -161,9 +191,10 @@ public TextureHandle DenoiseRTR(RenderGraph renderGraph, HDCamera hdCamera, floa ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.bilateralFilterHKernel, HDShaderIDs._SsrClearCoatMaskTexture, data.clearCoatMaskBuffer); ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.bilateralFilterHKernel, HDShaderIDs._DenoiseOutputTextureRW, data.intermediateBuffer1); ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.bilateralFilterHKernel, HDShaderIDs._ReflectionFilterMapping, data.reflectionFilterMapping); - ctx.cmd.DispatchCompute(data.reflectionDenoiserCS, data.bilateralFilterHKernel, numTilesX, numTilesY, data.viewCount); + if (!bypassBilateralFilter) + ctx.cmd.DispatchCompute(data.reflectionDenoiserCS, data.bilateralFilterHKernel, numTilesX, numTilesY, data.viewCount); - // Horizontal pass of the bilateral filter + // Vertical pass of the bilateral filter ctx.cmd.SetComputeIntParam(data.reflectionDenoiserCS, HDShaderIDs._DenoiserFilterRadius, data.maxKernelSize); ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.bilateralFilterVKernel, HDShaderIDs._DenoiseInputTexture, data.intermediateBuffer1); ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.bilateralFilterVKernel, HDShaderIDs._DepthTexture, data.depthBuffer); @@ -171,7 +202,8 @@ public TextureHandle DenoiseRTR(RenderGraph renderGraph, HDCamera hdCamera, floa ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.bilateralFilterVKernel, HDShaderIDs._SsrClearCoatMaskTexture, data.clearCoatMaskBuffer); ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.bilateralFilterVKernel, HDShaderIDs._DenoiseOutputTextureRW, data.noisyToOutputSignal); ctx.cmd.SetComputeTextureParam(data.reflectionDenoiserCS, data.bilateralFilterVKernel, HDShaderIDs._ReflectionFilterMapping, data.reflectionFilterMapping); - ctx.cmd.DispatchCompute(data.reflectionDenoiserCS, data.bilateralFilterVKernel, numTilesX, numTilesY, data.viewCount); + if (!bypassBilateralFilter) + ctx.cmd.DispatchCompute(data.reflectionDenoiserCS, data.bilateralFilterVKernel, numTilesX, numTilesY, data.viewCount); }); return passData.noisyToOutputSignal; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDRenderPipeline.RaytracingReflection.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDRenderPipeline.RaytracingReflection.cs index 1c70d36bef0..2c7fc637532 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDRenderPipeline.RaytracingReflection.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDRenderPipeline.RaytracingReflection.cs @@ -43,6 +43,13 @@ static RTHandle ReflectionHistoryBufferAllocatorFunction(string viewName, int fr name: string.Format("{0}_ReflectionHistoryBuffer{1}", viewName, frameIndex)); } + static RTHandle ReflectionHistorySampleCountBufferAllocatorFunction(string viewName, int frameIndex, RTHandleSystem rtHandleSystem) + { + return rtHandleSystem.Alloc(Vector2.one, TextureXR.slices, colorFormat: GraphicsFormat.R8_UNorm, dimension: TextureXR.dimension, + enableRandomWrite: true, useMipMap: false, autoGenerateMips: false, + name: string.Format("{0}_ReflectionHistorySampleCountBuffer{1}", viewName, frameIndex)); + } + private float EvaluateRayTracedReflectionHistoryValidity(HDCamera hdCamera, bool fullResolution, bool rayTraced) { // Evaluate the history validity @@ -158,6 +165,7 @@ class AdjustWeightRTRPassData public float minSmoothness; public float smoothnessFadeStart; + public int fallbackHierarchy; // Other parameters public ComputeShader reflectionFilterCS; @@ -186,6 +194,7 @@ TextureHandle AdjustWeightRTR(RenderGraph renderGraph, HDCamera hdCamera, Screen // Requires parameters passData.minSmoothness = settings.minSmoothness; passData.smoothnessFadeStart = settings.smoothnessFadeStart; + passData.fallbackHierarchy = (int)(settings.fallbackHierachy.value); // Other parameters passData.reflectionFilterCS = m_GlobalSettings.renderPipelineRayTracingResources.reflectionBilateralFilterCS; @@ -206,6 +215,7 @@ TextureHandle AdjustWeightRTR(RenderGraph renderGraph, HDCamera hdCamera, Screen // Bind all the required scalars to the CB data.shaderVariablesRayTracingCB._RaytracingReflectionMinSmoothness = data.minSmoothness; data.shaderVariablesRayTracingCB._RaytracingReflectionSmoothnessFadeStart = data.smoothnessFadeStart; + data.shaderVariablesRayTracingCB._RayTracingFallbackHierarchy = data.fallbackHierarchy; ConstantBuffer.PushGlobal(ctx.cmd, data.shaderVariablesRayTracingCB, HDShaderIDs._ShaderVariablesRaytracing); // Source input textures @@ -296,6 +306,13 @@ static RTHandle RequestRayTracedReflectionsHistoryTexture(HDCamera hdCamera) ReflectionHistoryBufferAllocatorFunction, 1); } + static RTHandle RequestRayTracedReflectionsHistorySampleCountTexture(HDCamera hdCamera) + { + return hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RaytracedReflectionSampleCount) + ?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.RaytracedReflectionSampleCount, + ReflectionHistorySampleCountBufferAllocatorFunction, 1); + } + DeferredLightingRTParameters PrepareReflectionDeferredLightingRTParameters(HDCamera hdCamera, bool transparent) { DeferredLightingRTParameters deferredParameters = new DeferredLightingRTParameters(); @@ -379,7 +396,8 @@ TextureHandle RenderReflectionsPerformance(RenderGraph renderGraph, HDCamera hdC // Denoise if required if (settings.denoise && !transparent) { - rtrResult = DenoiseReflection(renderGraph, hdCamera, settings.fullResolution, settings.denoiserRadius, singleReflectionBounce: true, settings.affectSmoothSurfaces, + bool skyHitsHaveZeroWeight = (settings.fallbackHierachy.value == RayTracingFallbackHierachy.NonRaytracedReflectionProbesAndSky); + rtrResult = DenoiseReflection(renderGraph, hdCamera, settings.fullResolution, settings.denoiserRadius, singleReflectionBounce: true, settings.affectSmoothSurfaces, skyHitsHaveZeroWeight, rtrResult, prepassOutput.depthBuffer, prepassOutput.normalBuffer, prepassOutput.motionVectorsBuffer, clearCoatTexture); } @@ -543,7 +561,8 @@ TextureHandle RenderReflectionsQuality(RenderGraph renderGraph, HDCamera hdCamer // Denoise if required if (settings.denoise && !transparent) { - rtrResult = DenoiseReflection(renderGraph, hdCamera, fullResolution: true, settings.denoiserRadius, settings.bounceCount == 1, settings.affectSmoothSurfaces, + bool skyHitsHaveZeroWeight = (settings.fallbackHierachy.value == RayTracingFallbackHierachy.NonRaytracedReflectionProbesAndSky); + rtrResult = DenoiseReflection(renderGraph, hdCamera, fullResolution: true, settings.denoiserRadius, settings.bounceCount == 1, settings.affectSmoothSurfaces, skyHitsHaveZeroWeight, rtrResult, depthPyramid, normalBuffer, motionVectors, clearCoatTexture); } @@ -552,14 +571,17 @@ TextureHandle RenderReflectionsQuality(RenderGraph renderGraph, HDCamera hdCamer #endregion - TextureHandle DenoiseReflection(RenderGraph renderGraph, HDCamera hdCamera, bool fullResolution, int denoiserRadius, bool singleReflectionBounce, bool affectSmoothSurfaces, + TextureHandle DenoiseReflection(RenderGraph renderGraph, HDCamera hdCamera, bool fullResolution, int denoiserRadius, bool singleReflectionBounce, bool affectSmoothSurfaces, bool skyHitsHaveZeroWeight, TextureHandle input, TextureHandle depthPyramid, TextureHandle normalBuffer, TextureHandle motionVectors, TextureHandle clearCoatTexture) { // Prepare the parameters and the resources HDReflectionDenoiser reflectionDenoiser = GetReflectionDenoiser(); float historyValidity = EvaluateRayTracedReflectionHistoryValidity(hdCamera, fullResolution, true); + RTHandle historySignal = RequestRayTracedReflectionsHistoryTexture(hdCamera); - var rtrResult = reflectionDenoiser.DenoiseRTR(renderGraph, hdCamera, historyValidity, denoiserRadius, fullResolution, singleReflectionBounce, affectSmoothSurfaces, depthPyramid, normalBuffer, motionVectors, clearCoatTexture, input, historySignal); + RTHandle historySampleCount = skyHitsHaveZeroWeight ? RequestRayTracedReflectionsHistorySampleCountTexture(hdCamera) : renderGraph.defaultResources.emptyReadWriteXRRTH; + // See DenoiseBuffer in HDReflectionDenoiser.cs : guards in compute dont seem to work so always bind something on the UAV with emptyReadWriteXRRTH. + var rtrResult = reflectionDenoiser.DenoiseRTR(renderGraph, hdCamera, historyValidity, denoiserRadius, fullResolution, singleReflectionBounce, affectSmoothSurfaces, skyHitsHaveZeroWeight, depthPyramid, normalBuffer, motionVectors, clearCoatTexture, input, historySignal, historySampleCount); PropagateRayTracedReflectionsHistoryValidity(hdCamera, fullResolution, true); return rtrResult; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/RayTracingFallbackHierarchy.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/RayTracingFallbackHierarchy.cs index 7f7ae525b50..9e9d12c1da7 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/RayTracingFallbackHierarchy.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/RayTracingFallbackHierarchy.cs @@ -8,6 +8,12 @@ namespace UnityEngine.Rendering.HighDefinition [GenerateHLSL] public enum RayTracingFallbackHierachy { + /// + /// When selected, ray tracing will let the material fall back on the same (pre-integrated probes) + /// reflection hierarchy it uses as with rasterization by setting hierarchy weights to zero on miss. + /// + [InspectorName("Non Raytraced Reflection Probes and Sky")] + NonRaytracedReflectionProbesAndSky = 0x07, // note: we include ReflectionProbesAndSky bits for a better blend (cf vs eg 4) /// /// When selected, ray tracing will fall back on reflection probes (if any) then on the sky. /// diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/RayTracingFallbackHierarchy.cs.hlsl b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/RayTracingFallbackHierarchy.cs.hlsl index 99581eb0fec..aec4cf27b1a 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/RayTracingFallbackHierarchy.cs.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/RayTracingFallbackHierarchy.cs.hlsl @@ -7,6 +7,7 @@ // // UnityEngine.Rendering.HighDefinition.RayTracingFallbackHierachy: static fields // +#define RAYTRACINGFALLBACKHIERACHY_NON_RAYTRACED_REFLECTION_PROBES_AND_SKY (7) #define RAYTRACINGFALLBACKHIERACHY_REFLECTION_PROBES_AND_SKY (3) #define RAYTRACINGFALLBACKHIERACHY_REFLECTION_PROBES (2) #define RAYTRACINGFALLBACKHIERACHY_SKY (1) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Deferred/RaytracingDeferred.compute b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Deferred/RaytracingDeferred.compute index 8f6a6bea03d..8404db6d097 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Deferred/RaytracingDeferred.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Deferred/RaytracingDeferred.compute @@ -78,17 +78,20 @@ void RAYTRACING_DEFERRED(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 gro // Fetch the direction of the ray float3 rayDirection = LOAD_TEXTURE2D_X(_RaytracingDirectionBuffer, currentCoord).xyz; - float3 finalColor = 0.0f; + float3 finalColor = 0.0; + float finalWeight = 1.0; // if the distance is exactly zero, this means we are facing an environement ray that we need to evaluate if (RayDistanceIndicatesHitSky(rayDistance)) { // Weight value used to do the blending float weight = 0.0; + if (RAYTRACINGFALLBACKHIERACHY_NON_RAYTRACED_REFLECTION_PROBES_AND_SKY == _RayTracingFallbackHierarchy) + finalWeight = 0.0; if (RAYTRACINGFALLBACKHIERACHY_REFLECTION_PROBES & _RayTracingFallbackHierarchy) finalColor = RayTraceReflectionProbes(sourcePosInput.positionWS, rayDirection, weight); - if((RAYTRACINGFALLBACKHIERACHY_SKY & _RayTracingFallbackHierarchy) && weight == 0.0f) + if ((RAYTRACINGFALLBACKHIERACHY_SKY & _RayTracingFallbackHierarchy) && weight == 0.0f) { finalColor = SAMPLE_TEXTURECUBE_ARRAY_LOD(_SkyTexture, s_trilinear_clamp_sampler, rayDirection, 0.0, 0).xyz; weight = 1.0; @@ -113,7 +116,8 @@ void RAYTRACING_DEFERRED(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 gro finalColor.z = clamp(finalColor.z, 0.0, _RaytracingIntensityClamp); // Convert back to HSV space - _RaytracingLitBufferRW[COORD_TEXTURE2D_X(currentCoord)] = float4(HsvToRgb(finalColor) * (_RaytracingPreExposition ? 1.0 : GetInverseCurrentExposureMultiplier()), 0.0); + finalColor = HsvToRgb(finalColor) * (_RaytracingPreExposition ? 1.0 : GetInverseCurrentExposureMultiplier()); + _RaytracingLitBufferRW[COORD_TEXTURE2D_X(currentCoord)] = float4(finalColor, finalWeight); return; } diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Denoising/ReflectionDenoiser.compute b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Denoising/ReflectionDenoiser.compute index bb0190d7486..0d28c157f6c 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Denoising/ReflectionDenoiser.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Denoising/ReflectionDenoiser.compute @@ -1,12 +1,21 @@ #pragma only_renderers d3d11 -#pragma kernel TemporalAccumulationFullRes TEMPORAL_ACCUMULATION=TemporalAccumulationFullRes -#pragma kernel TemporalAccumulationHalfRes TEMPORAL_ACCUMULATION=TemporalAccumulationHalfRes HALF_RESOLUTION -#pragma kernel CopyHistory -#pragma kernel BilateralFilterH_FR BILATERAL_FILTER=BilateralFilterH_FR -#pragma kernel BilateralFilterV_FR BILATERAL_FILTER=BilateralFilterV_FR FINAL_PASS -#pragma kernel BilateralFilterH_HR BILATERAL_FILTER=BilateralFilterH_HR HALF_RESOLUTION -#pragma kernel BilateralFilterV_HR BILATERAL_FILTER=BilateralFilterV_HR FINAL_PASS HALF_RESOLUTION +#pragma kernel TemporalAccumulationFullRes TEMPORAL_ACCUMULATION=TemporalAccumulationFullRes MISS_RATIO_IN_WEIGHT=false +#pragma kernel TemporalAccumulationHalfRes TEMPORAL_ACCUMULATION=TemporalAccumulationHalfRes MISS_RATIO_IN_WEIGHT=false HALF_RESOLUTION +#pragma kernel TemporalAccumulationFullResMissWeighted TEMPORAL_ACCUMULATION=TemporalAccumulationFullResMissWeighted MISS_RATIO_IN_WEIGHT=true +#pragma kernel TemporalAccumulationHalfResMissWeighted TEMPORAL_ACCUMULATION=TemporalAccumulationHalfResMissWeighted MISS_RATIO_IN_WEIGHT=true HALF_RESOLUTION + +#pragma kernel CopyHistory COPY_HISTORY=CopyHistory MISS_RATIO_IN_WEIGHT=false +#pragma kernel CopyHistoryMissWeighted COPY_HISTORY=CopyHistoryMissWeighted MISS_RATIO_IN_WEIGHT=true + +#pragma kernel BilateralFilterH_FR BILATERAL_FILTER=BilateralFilterH_FR MISS_RATIO_IN_WEIGHT=false +#pragma kernel BilateralFilterH_HR BILATERAL_FILTER=BilateralFilterH_HR MISS_RATIO_IN_WEIGHT=false HALF_RESOLUTION +#pragma kernel BilateralFilterHMissWeighted_FR BILATERAL_FILTER=BilateralFilterHMissWeighted_FR MISS_RATIO_IN_WEIGHT=true +#pragma kernel BilateralFilterHMissWeighted_HR BILATERAL_FILTER=BilateralFilterHMissWeighted_HR MISS_RATIO_IN_WEIGHT=true HALF_RESOLUTION +#pragma kernel BilateralFilterV_FR BILATERAL_FILTER=BilateralFilterV_FR MISS_RATIO_IN_WEIGHT=false FINAL_PASS +#pragma kernel BilateralFilterV_HR BILATERAL_FILTER=BilateralFilterV_HR MISS_RATIO_IN_WEIGHT=false FINAL_PASS HALF_RESOLUTION +#pragma kernel BilateralFilterVMissWeighted_FR BILATERAL_FILTER=BilateralFilterVMissWeighted_FR MISS_RATIO_IN_WEIGHT=true FINAL_PASS +#pragma kernel BilateralFilterVMissWeighted_HR BILATERAL_FILTER=BilateralFilterVMissWeighted_HR MISS_RATIO_IN_WEIGHT=true FINAL_PASS HALF_RESOLUTION #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl" @@ -27,6 +36,7 @@ TEXTURE2D_X(_SsrClearCoatMaskTexture); // Tile size of this compute #define REFLECTION_FILTER_TILE_SIZE 8 +#define DEBUG_SHOW_WEIGHTS_ONLY false // #pragma enable_d3d11_debug_symbols // Threshold at which we decide to reject the reflection history @@ -37,6 +47,9 @@ TEXTURE2D_X(_SsrClearCoatMaskTexture); // Input textures TEXTURE2D_X(_DenoiseInputTexture); TEXTURE2D_X(_HistoryBuffer); +//#if MISS_RATIO_IN_WEIGHT == true +TEXTURE2D_X(_HistorySampleCountTexture); // TODO! +//#endif TEXTURE2D_X(_HistoryDepthTexture); // Value that tells us if the current history should be discarded based on scene-level data float _HistoryValidity; @@ -50,7 +63,11 @@ int _SingleReflectionBounce; // Output texture RW_TEXTURE2D_X(float4, _DenoiseOutputTextureRW); -RW_TEXTURE2D_X(float, _SampleCountTextureRW); +RW_TEXTURE2D_X(float, _SampleCountTextureRW); // also input in CopyHistory +#if MISS_RATIO_IN_WEIGHT == true +// TODO! these guards dont seem to work. +RW_TEXTURE2D_X(float, _HistorySampleCountTextureRW); +#endif [numthreads(REFLECTION_FILTER_TILE_SIZE, REFLECTION_FILTER_TILE_SIZE, 1)] void TEMPORAL_ACCUMULATION(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 groupThreadId : SV_GroupThreadID, uint2 groupId : SV_GroupID) @@ -93,23 +110,38 @@ void TEMPORAL_ACCUMULATION(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 g float2 historyCoordinate = ((float2)(mainCoord + 0.5f) - velocity * _CurrentEffectResolution.xy); float2 historyUV = clamp(historyCoordinate, 0.0f, _CurrentEffectResolution.xy - 1.0f) * _HistoryBufferSize.xy; - // Fetch the current and history values and apply the exposition to it. - float3 color = Fetch(_DenoiseInputTexture, currentUV, 0.0, _RTHandleScale.xy) * GetCurrentExposureMultiplier(); + // Fetch the current and history values and apply exposure to color components. + float4 colorRaw = MISS_RATIO_IN_WEIGHT ? Fetch4(_DenoiseInputTexture, currentUV, 0.0, _RTHandleScale.xy) : float4(Fetch(_DenoiseInputTexture, currentUV, 0.0, _RTHandleScale.xy), 0); float4 historyRaw = Fetch4(_HistoryBuffer, historyUV, 0.0, 1.0); - float3 history = historyRaw.xyz * GetCurrentExposureMultiplier(); + + float colorW = MISS_RATIO_IN_WEIGHT ? colorRaw.w : 0; + float4 color = float4(colorRaw.xyz * GetCurrentExposureMultiplier(), colorW); + + float historyW = MISS_RATIO_IN_WEIGHT ? historyRaw.w : 0; + float4 history = float4(historyRaw.xyz * GetCurrentExposureMultiplier(), historyW); // If this is close to a perfectly smooth surface, we may not want to use the history (depending on _AffectSmoothSurfaces) // In thise case, see RaytracingReflections.raytrace: make sure we don't sample otherwise we could have noisy artifacts. // Keep in sync with the sampling in the raygen program in RaytracingReflections.raytrace (along with _SingleReflectionBounce here vs _RaytracingMaxRecursion in the former) if (SkipReflectionDenoiserHistoryAccumulation((_AffectSmoothSurfaces == 1), (_SingleReflectionBounce == 1), normalData.perceptualRoughness)) { - _DenoiseOutputTextureRW[COORD_TEXTURE2D_X(mainCoord)] = float4(color * GetInverseCurrentExposureMultiplier(), LOAD_TEXTURE2D_X(_DenoiseInputTexture, mainCoord).w); + colorRaw.w = MISS_RATIO_IN_WEIGHT ? colorRaw.w : LOAD_TEXTURE2D_X(_DenoiseInputTexture, mainCoord).w; + _DenoiseOutputTextureRW[COORD_TEXTURE2D_X(mainCoord)] = float4(color.xyz * GetInverseCurrentExposureMultiplier(), colorRaw.w); _SampleCountTextureRW[COORD_TEXTURE2D_X(mainCoord)] = 1; + if (DEBUG_SHOW_WEIGHTS_ONLY) + _DenoiseOutputTextureRW[COORD_TEXTURE2D_X(mainCoord)] = float4((float3)(colorRaw.w * GetInverseCurrentExposureMultiplier()), colorRaw.w); return; } + //TODO float sampleCount = historyRaw.w; + // When the raytracing shader outputs a ray miss ratio in the w channel, we need to also preserve its history, so the + // sampleCount has its own texture. Otherwise, the history buffer uses the w channel for history sampleCount. float sampleCount = historyRaw.w; - float3 result; + //#if MISS_RATIO_IN_WEIGHT == true + sampleCount = MISS_RATIO_IN_WEIGHT ? Fetch(_HistorySampleCountTexture, historyUV, 0.0, 1.0).x : sampleCount; + //#endif + float4 result; + if (normalData.perceptualRoughness > ROUGHNESS_ACCUMULATION_THRESHOLD) { bool canBeReprojected = true; @@ -157,60 +189,110 @@ void TEMPORAL_ACCUMULATION(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 g } else { - float3 topLeft = Fetch(_DenoiseInputTexture, currentUV, -RADIUS, _RTHandleScale.xy) * GetCurrentExposureMultiplier(); - float3 bottomRight = Fetch(_DenoiseInputTexture, currentUV, RADIUS, _RTHandleScale.xy) * GetCurrentExposureMultiplier(); - - float3 corners = 4.0 * (topLeft + bottomRight) - 2.0 * color; - - color = clamp(color, 0.0, CLAMP_MAX); - - float3 average = FastTonemap((corners + color) / 7.0); - - topLeft = FastTonemap(topLeft); - bottomRight = FastTonemap(bottomRight); - color = FastTonemap(color); - - float colorLuma = Luminance(color); - float averageLuma = Luminance(average); + float4 topLeftRaw = MISS_RATIO_IN_WEIGHT ? Fetch4(_DenoiseInputTexture, currentUV, -RADIUS, _RTHandleScale.xy) + : float4(Fetch(_DenoiseInputTexture, currentUV, -RADIUS, _RTHandleScale.xy),0); + float4 bottomRightRaw = MISS_RATIO_IN_WEIGHT ? Fetch4(_DenoiseInputTexture, currentUV, RADIUS, _RTHandleScale.xy) + : float4(Fetch(_DenoiseInputTexture, currentUV, RADIUS, _RTHandleScale.xy),0); + + float topLeftW = MISS_RATIO_IN_WEIGHT ? topLeftRaw.w : 0; + float bottomRightW = MISS_RATIO_IN_WEIGHT ? bottomRightRaw.w : 0; + float4 topLeft = float4(topLeftRaw.xyz * GetCurrentExposureMultiplier(), topLeftW); + float4 bottomRight = float4(bottomRightRaw.xyz * GetCurrentExposureMultiplier(), bottomRightW); + + // We split up the weight accumulations + // (feedback for weights will be different than for the color) + // We only use the final result if needed (based on MISS_RATIO_IN_WEIGHT) + // so the compiler will prune out the weight accumulation path. + + float4 corners = 4.0 * (topLeft + bottomRight) - 2.0 * color; + + color.xyz = clamp(color.xyz, 0.0, CLAMP_MAX); + + #if 1 + // TODO: Cleanup, remove usage of FastTonemapPerChannel, obviously weights dont + // have the dynamic range of radiance, but this was a test to see if the nonlinear function + // helped or made worse the transition from pre-integrated fallback to raytraced. + #undef FastTonemapPerChannel + #undef FastTonemapPerChannelInvert + #define FastTonemapPerChannel(a) (a) + #define FastTonemapPerChannelInvert(a) (a) + #endif + + float4 average; + average.xyz = FastTonemap((corners.xyz + color.xyz) / 7.0); + average.w = FastTonemapPerChannel((corners.w + color.w) / 7.0); + + topLeft.xyz = FastTonemap(topLeft.xyz); + topLeft.w = FastTonemapPerChannel(topLeft.w); + + bottomRight.xyz = FastTonemap(bottomRight.xyz); + bottomRight.w = FastTonemapPerChannel(bottomRight.w); + + color.xyz = FastTonemap(color.xyz); + color.w = FastTonemapPerChannel(color.w); + + float2 colorLuma = float2(Luminance(color), color.w); + float2 averageLuma = float2(Luminance(average), average.w); float velocityLength = length(velocity); - float nudge = lerp(4.0, 0.25, saturate(velocityLength * 100.0)) * abs(averageLuma - colorLuma); + float2 nudge = lerp(4.0, 0.25, saturate(velocityLength * 100.0)) * abs(averageLuma - colorLuma); - float3 minimum = min(bottomRight, topLeft) - nudge; - float3 maximum = max(topLeft, bottomRight) + nudge; + float4 minimum = min(bottomRight, topLeft) - nudge.xxxy; + float4 maximum = max(topLeft, bottomRight) + nudge.xxxy; - history = FastTonemap(history); + history.xyz = FastTonemap(history.xyz); + history.w = FastTonemapPerChannel(history.w); - // Clip history samples - history = DirectClipToAABB(history, minimum, maximum); + // Clip history samples (compiler will optimize the 2nd) + history.xyz = DirectClipToAABB(history.xyz, minimum.xyz, maximum.xyz); + if (MISS_RATIO_IN_WEIGHT) + history.w = DirectClipToAABB((float3)history.w, (float3)minimum.w, (float3)maximum.w).x; // Blend color & history // Feedback weight from unbiased luminance diff (Timothy Lottes) - float historyLuma = Luminance(history); - float diff = abs(colorLuma - historyLuma) / Max3(colorLuma, historyLuma, 0.2); - float weight = 1.0 - diff; - const float feedbackMin = 0.96; - const float feedbackMax = 0.91; - float feedback = lerp(feedbackMin, feedbackMax, weight * weight); - - color = FastTonemapInvert(lerp(color, history, feedback)); - result = clamp(color, 0.0, CLAMP_MAX); + float2 historyLuma = float2(Luminance(history.xyz), history.w); + float2 diff = abs(colorLuma - historyLuma) / float2(Max3(colorLuma.x, historyLuma.x, 0.2), Max3(colorLuma.y, historyLuma.y, 0.2)); + float2 weight = 1.0 - diff; + const float feedbackMax = 0.96; + const float feedbackMin = 0.91; + float2 feedback = lerp(feedbackMax.xx, feedbackMin.xx, weight * weight); + + color.xyz = lerp(color.xyz, history.xyz, feedback.xxx); + color.w = lerp(color.w, history.w, feedback.y); + + color.xyz = FastTonemapInvert(color.xyz); + color.xyz = clamp(color.xyz, 0.0, CLAMP_MAX); + color.w = FastTonemapPerChannelInvert(color.w); + + result = color; } - _DenoiseOutputTextureRW[COORD_TEXTURE2D_X(mainCoord)] = float4(result * GetInverseCurrentExposureMultiplier(), LOAD_TEXTURE2D_X(_DenoiseInputTexture, mainCoord).w); + float finalColorW = MISS_RATIO_IN_WEIGHT ? result.w : LOAD_TEXTURE2D_X(_DenoiseInputTexture, mainCoord).w; + + _DenoiseOutputTextureRW[COORD_TEXTURE2D_X(mainCoord)] = float4(result.xyz * GetInverseCurrentExposureMultiplier(), finalColorW); + if (DEBUG_SHOW_WEIGHTS_ONLY) + _DenoiseOutputTextureRW[COORD_TEXTURE2D_X(mainCoord)] = float4((float3)(result.w)*GetInverseCurrentExposureMultiplier(), result.w); _SampleCountTextureRW[COORD_TEXTURE2D_X(mainCoord)] = sampleCount; } [numthreads(REFLECTION_FILTER_TILE_SIZE, REFLECTION_FILTER_TILE_SIZE, 1)] -void CopyHistory(uint3 dispatchThreadId : SV_DispatchThreadID) +void COPY_HISTORY(uint3 dispatchThreadId : SV_DispatchThreadID) { UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadId.z); if (any(dispatchThreadId.xy > uint2(_ScreenSize.xy))) return; // Out of bounds, discard + // Note in this kernel _DenoiseOutputTextureRW has the history buffer binded float4 currentColor = LOAD_TEXTURE2D_X(_DenoiseInputTexture, dispatchThreadId.xy); - // We need to apply a step function on the blend factor to evaluate the validity of the history (if it is stricly higher than 0.0 then its valid) - _DenoiseOutputTextureRW[COORD_TEXTURE2D_X(dispatchThreadId.xy)] = float4(currentColor.xyz, _SampleCountTextureRW[COORD_TEXTURE2D_X(dispatchThreadId.xy)].x); + float sampleCount = _SampleCountTextureRW[COORD_TEXTURE2D_X(dispatchThreadId.xy)].x; + + float4 historyOutput = MISS_RATIO_IN_WEIGHT ? currentColor : float4(currentColor.xyz, sampleCount); + + _DenoiseOutputTextureRW[COORD_TEXTURE2D_X(dispatchThreadId.xy)] = historyOutput; + #if MISS_RATIO_IN_WEIGHT == true + // In that case, we need a separate texture tracking sampleCount + _HistorySampleCountTextureRW[COORD_TEXTURE2D_X(dispatchThreadId.xy)] = sampleCount; + #endif } int _DenoiserFilterRadius; @@ -255,13 +337,14 @@ void BILATERAL_FILTER(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 groupT const int effectiveRadius = min(sigma * 2.0, radius); // Store the intermediate result - float3 finalColor = LOAD_TEXTURE2D_X(_DenoiseInputTexture, centerCoord).xyz; + float4 finalColor = MISS_RATIO_IN_WEIGHT ? LOAD_TEXTURE2D_X(_DenoiseInputTexture, centerCoord).xyzw + : float4(LOAD_TEXTURE2D_X(_DenoiseInputTexture, centerCoord).xyz, 0); // If this pixels does not have ray traced reflections anyway, just skip it. if (_RaytracingReflectionMinSmoothness <= PerceptualRoughnessToPerceptualSmoothness(center.roughness)) { // Initialize variables for accumulation - float3 colorSum = float3(0.0, 0.0, 0.0); + float4 colorSum = float4(0.0, 0.0, 0.0, 0.0); float wSum = 0.0; int2 tapCoord = centerCoord - effectiveRadius * passIncr; @@ -280,12 +363,14 @@ void BILATERAL_FILTER(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 groupT const BilateralData tapData = TapBilateralData(tapGeometryCoords); float w = r ? gaussian(r, sigma) * ComputeBilateralWeight(center, tapData) : 1.0; w = _RaytracingReflectionMinSmoothness > PerceptualRoughnessToPerceptualSmoothness(tapData.roughness) ? 0.0 : w; - colorSum += LOAD_TEXTURE2D_X(_DenoiseInputTexture, tapCoord).xyz * w; + colorSum += LOAD_TEXTURE2D_X(_DenoiseInputTexture, tapCoord).xyzw * w; wSum += w; } // Normalize the result - finalColor = colorSum / wSum; + finalColor.xyz = colorSum.xyz / wSum; + finalColor.w = MISS_RATIO_IN_WEIGHT ? (colorSum.w / wSum) : finalColor.w; } - _DenoiseOutputTextureRW[COORD_TEXTURE2D_X(centerCoord)] = float4(finalColor, LOAD_TEXTURE2D_X(_DenoiseInputTexture, centerCoord).w); + finalColor = MISS_RATIO_IN_WEIGHT ? finalColor : float4(finalColor.xyz, LOAD_TEXTURE2D_X(_DenoiseInputTexture, centerCoord).w); + _DenoiseOutputTextureRW[COORD_TEXTURE2D_X(centerCoord)] = finalColor; } diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingReflectionFilter.compute b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingReflectionFilter.compute index c759d98c33f..b920cc11d20 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingReflectionFilter.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingReflectionFilter.compute @@ -18,6 +18,7 @@ #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/OnlineVariance.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingCommon.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/ShaderVariablesRaytracing.hlsl" +#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/RayTracingFallbackHierarchy.cs.hlsl" // Tile size of this compute #define RAYTRACING_REFLECTION_TILE_SIZE 8 @@ -87,7 +88,10 @@ void ReflectionRescaleAndAdjustWeight(uint3 dispatchThreadId : SV_DispatchThread // We also need to compute the fade factor for this sample float weight = ComputeWeightValue(perceptualSmoothness); - _RaytracingReflectionTexture[COORD_TEXTURE2D_X(halfResCoord)] = float4(LOAD_TEXTURE2D_X(_SsrLightingTextureRW, fullResCoord).xyz, weight); + float4 lightingTexture = LOAD_TEXTURE2D_X(_SsrLightingTextureRW, fullResCoord); + + weight = (_RayTracingFallbackHierarchy == RAYTRACINGFALLBACKHIERACHY_NON_RAYTRACED_REFLECTION_PROBES_AND_SKY) ? lightingTexture.w * weight : weight; + _RaytracingReflectionTexture[COORD_TEXTURE2D_X(halfResCoord)] = float4(lightingTexture.xyz, weight); } [numthreads(RAYTRACING_REFLECTION_TILE_SIZE, RAYTRACING_REFLECTION_TILE_SIZE, 1)] @@ -129,11 +133,12 @@ void ReflectionAdjustWeight(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 } // Fetch the lighting and compute the weight - float3 lighting = LOAD_TEXTURE2D_X(_SsrLightingTextureRW, targetCoord).rgb; + float4 lighting = LOAD_TEXTURE2D_X(_SsrLightingTextureRW, targetCoord); float weight = ComputeWeightValue(perceptualSmoothness); + weight = (_RayTracingFallbackHierarchy == RAYTRACINGFALLBACKHIERACHY_NON_RAYTRACED_REFLECTION_PROBES_AND_SKY) ? lighting.w * weight : weight; // Output the result to the half resolution part of the texture - _RaytracingReflectionTexture[COORD_TEXTURE2D_X(targetCoord)] = float4(lighting, weight); + _RaytracingReflectionTexture[COORD_TEXTURE2D_X(targetCoord)] = float4(lighting.xyz, weight); } [numthreads(RAYTRACING_REFLECTION_TILE_SIZE, RAYTRACING_REFLECTION_TILE_SIZE, 1)] diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Reflections/RaytracingReflections.raytrace b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Reflections/RaytracingReflections.raytrace index 147b5296ba3..da420e5f266 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Reflections/RaytracingReflections.raytrace +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Reflections/RaytracingReflections.raytrace @@ -58,7 +58,7 @@ void MissShaderReflections(inout RayIntersection rayIntersection : SV_RayPayload if (RAYTRACINGFALLBACKHIERACHY_REFLECTION_PROBES & _RayTracingFallbackHierarchy) rayIntersection.color = RayTraceReflectionProbes(rayOrigin, rayDirection, weight); - if((RAYTRACINGFALLBACKHIERACHY_SKY & _RayTracingFallbackHierarchy) && weight < 1.0) + if ((RAYTRACINGFALLBACKHIERACHY_SKY & _RayTracingFallbackHierarchy) && weight < 1.0) { rayIntersection.color += SAMPLE_TEXTURECUBE_ARRAY_LOD(_SkyTexture, s_trilinear_clamp_sampler, rayDirection, 0.0, 0).xyz * (1.0 - weight); weight = 1.0f; @@ -145,6 +145,8 @@ void RayGenIntegration() float3 defaultSampleDir = reflect(-viewWS, normalData.normalWS); // Compute the actual roughness float roughness = PerceptualRoughnessToRoughness(normalData.perceptualRoughness); + // Accumulates 1 each time we reach the miss program: + float finalRayHitSky = 0.0; // Loop through the samples and add their contribution for (int sampleIndex = 0; sampleIndex < realSampleCount; ++sampleIndex) @@ -221,15 +223,23 @@ void RayGenIntegration() // Contribute to the pixel finalColor += sampleColor; + // Track number of ray misses + if (_RayTracingFallbackHierarchy == RAYTRACINGFALLBACKHIERACHY_NON_RAYTRACED_REFLECTION_PROBES_AND_SKY) + finalRayHitSky += step(_RaytracingRayMaxLength, rayIntersection.t); } // Normalize the value finalColor *= 1.0 / realSampleCount; + finalRayHitSky *= 1.0 / realSampleCount; // We also need to compute the fade factor for this sample float weightValue = _RaytracingReflectionSmoothnessFadeStart == _RaytracingReflectionMinSmoothness ? 1.0 : saturate((perceptualSmoothness - _RaytracingReflectionMinSmoothness) / (_RaytracingReflectionSmoothnessFadeStart -_RaytracingReflectionMinSmoothness)); + if (_RayTracingFallbackHierarchy == RAYTRACINGFALLBACKHIERACHY_NON_RAYTRACED_REFLECTION_PROBES_AND_SKY) + { + weightValue = weightValue * saturate(1.0-finalRayHitSky); + } - // We store the sampled color and the weight that shall be used for it (1.0) + // We store the sampled color and the weight that shall be used for it _SsrLightingTextureRW[COORD_TEXTURE2D_X(currentCoord)] = float4(finalColor, weightValue); } @@ -340,6 +350,6 @@ void RayGenIntegrationTransparent() [shader("closesthit")] void ClosestHitMain(inout RayIntersection rayIntersection : SV_RayPayload, AttributeData attributeData : SV_IntersectionAttributes) { - // When we do not hit any known closest hit, that means that no shader was specified for the target object meaning either it has nothing to do in the acceleration structure or we need to add raytracing subshaders to it - rayIntersection.color = float3(1.0, 0.0, 0.5); + // When we do not hit any known closest hit, that means that no shader was specified for the target object meaning either it has nothing to do in the acceleration structure or we need to add raytracing subshaders to it + rayIntersection.color = float3(1.0, 0.0, 0.5); } From 1375ac75a877b567336baea07b09705df33b99e3 Mon Sep 17 00:00:00 2001 From: slunity Date: Fri, 18 Jun 2021 00:13:00 -0400 Subject: [PATCH 10/12] Add DXR test for pre-integrated probes SSR-RTR fallback. --- ...09_ReflectionFallbackBothPreIntegrated.png | 3 + ...flectionFallbackBothPreIntegrated.png.meta | 98 + ...bal Volume Profile_BothPreIntegrated.asset | 279 +++ ...olume Profile_BothPreIntegrated.asset.meta | 8 + ..._ReflectionFallbackBothPreIntegrated.unity | 1600 +++++++++++++++++ ...ectionFallbackBothPreIntegrated.unity.meta | 7 + .../M_ReflectiveRough.mat | 298 +++ .../M_ReflectiveRough.mat.meta | 8 + .../ProjectSettings/EditorBuildSettings.asset | 3 + 9 files changed, 2304 insertions(+) create mode 100644 TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/109_ReflectionFallbackBothPreIntegrated.png create mode 100644 TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/109_ReflectionFallbackBothPreIntegrated.png.meta create mode 100644 TestProjects/HDRP_DXR_Tests/Assets/Scenes/109_ReflectionFallbackBoth/Global Volume Profile_BothPreIntegrated.asset create mode 100644 TestProjects/HDRP_DXR_Tests/Assets/Scenes/109_ReflectionFallbackBoth/Global Volume Profile_BothPreIntegrated.asset.meta create mode 100644 TestProjects/HDRP_DXR_Tests/Assets/Scenes/109_ReflectionFallbackBothPreIntegrated.unity create mode 100644 TestProjects/HDRP_DXR_Tests/Assets/Scenes/109_ReflectionFallbackBothPreIntegrated.unity.meta create mode 100644 TestProjects/HDRP_DXR_Tests/Assets/Scenes/RayTracedReflectionsData/M_ReflectiveRough.mat create mode 100644 TestProjects/HDRP_DXR_Tests/Assets/Scenes/RayTracedReflectionsData/M_ReflectiveRough.mat.meta diff --git a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/109_ReflectionFallbackBothPreIntegrated.png b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/109_ReflectionFallbackBothPreIntegrated.png new file mode 100644 index 00000000000..2beffe666a5 --- /dev/null +++ b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/109_ReflectionFallbackBothPreIntegrated.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d51472970427b74a331439b5ffb2452752b1fd24abe61a2f56d1d607bbc81f2 +size 184849 diff --git a/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/109_ReflectionFallbackBothPreIntegrated.png.meta b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/109_ReflectionFallbackBothPreIntegrated.png.meta new file mode 100644 index 00000000000..4ddc917c78e --- /dev/null +++ b/TestProjects/HDRP_DXR_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/109_ReflectionFallbackBothPreIntegrated.png.meta @@ -0,0 +1,98 @@ +fileFormatVersion: 2 +guid: 15956c76f5169684884b730885e3a9fe +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 1 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/TestProjects/HDRP_DXR_Tests/Assets/Scenes/109_ReflectionFallbackBoth/Global Volume Profile_BothPreIntegrated.asset b/TestProjects/HDRP_DXR_Tests/Assets/Scenes/109_ReflectionFallbackBoth/Global Volume Profile_BothPreIntegrated.asset new file mode 100644 index 00000000000..2e739d5bb98 --- /dev/null +++ b/TestProjects/HDRP_DXR_Tests/Assets/Scenes/109_ReflectionFallbackBoth/Global Volume Profile_BothPreIntegrated.asset @@ -0,0 +1,279 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-5490847147131661617 +MonoBehaviour: + m_ObjectHideFlags: 3 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59b6606ef2548734bb6d11b9d160bc7e, type: 3} + m_Name: HDRISky + m_EditorClassIdentifier: + active: 1 + rotation: + m_OverrideState: 0 + m_Value: 0 + skyIntensityMode: + m_OverrideState: 0 + m_Value: 0 + exposure: + m_OverrideState: 0 + m_Value: 0 + multiplier: + m_OverrideState: 0 + m_Value: 1 + upperHemisphereLuxValue: + m_OverrideState: 0 + m_Value: 4.1871386 + upperHemisphereLuxColor: + m_OverrideState: 0 + m_Value: {x: 0.44071853, y: 0.45464578, z: 0.5} + desiredLuxValue: + m_OverrideState: 0 + m_Value: 20000 + updateMode: + m_OverrideState: 0 + m_Value: 0 + updatePeriod: + m_OverrideState: 0 + m_Value: 0 + includeSunInBaking: + m_OverrideState: 0 + m_Value: 0 + hdriSky: + m_OverrideState: 1 + m_Value: {fileID: 8900000, guid: ec03f1d4a2587b749bc197def8c88c8e, type: 3} + enableDistortion: + m_OverrideState: 0 + m_Value: 0 + procedural: + m_OverrideState: 0 + m_Value: 1 + flowmap: + m_OverrideState: 0 + m_Value: {fileID: 0} + upperHemisphereOnly: + m_OverrideState: 0 + m_Value: 1 + scrollDirection: + m_OverrideState: 0 + m_Value: 0 + scrollSpeed: + m_OverrideState: 0 + m_Value: 2 + enableBackplate: + m_OverrideState: 0 + m_Value: 0 + backplateType: + m_OverrideState: 0 + m_Value: 0 + groundLevel: + m_OverrideState: 0 + m_Value: 0 + scale: + m_OverrideState: 0 + m_Value: {x: 32, y: 32} + projectionDistance: + m_OverrideState: 0 + m_Value: 16 + plateRotation: + m_OverrideState: 0 + m_Value: 0 + plateTexRotation: + m_OverrideState: 0 + m_Value: 0 + plateTexOffset: + m_OverrideState: 0 + m_Value: {x: 0, y: 0} + blendAmount: + m_OverrideState: 0 + m_Value: 0 + shadowTint: + m_OverrideState: 0 + m_Value: {r: 0.5, g: 0.5, b: 0.5, a: 1} + pointLightShadow: + m_OverrideState: 0 + m_Value: 0 + dirLightShadow: + m_OverrideState: 0 + m_Value: 0 + rectLightShadow: + m_OverrideState: 0 + m_Value: 0 +--- !u!114 &-1756342479024897208 +MonoBehaviour: + m_ObjectHideFlags: 3 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 384c4d03a551c44448145f4093304119, type: 3} + m_Name: ScreenSpaceReflection + m_EditorClassIdentifier: + active: 1 + quality: + m_OverrideState: 1 + m_Value: 3 + enabled: + m_OverrideState: 1 + m_Value: 1 + tracing: + m_OverrideState: 1 + m_Value: 2 + m_MinSmoothness: + m_OverrideState: 1 + m_Value: 0.7 + m_SmoothnessFadeStart: + m_OverrideState: 1 + m_Value: 0.8 + reflectSky: + m_OverrideState: 0 + m_Value: 1 + usedAlgorithm: + m_OverrideState: 0 + m_Value: 0 + depthBufferThickness: + m_OverrideState: 0 + m_Value: 0.01 + screenFadeDistance: + m_OverrideState: 0 + m_Value: 0.1 + accumulationFactor: + m_OverrideState: 0 + m_Value: 0.75 + m_RayMaxIterations: + m_OverrideState: 0 + m_Value: 32 + fallbackHierachy: + m_OverrideState: 1 + m_Value: 7 + layerMask: + m_OverrideState: 1 + m_Value: + serializedVersion: 2 + m_Bits: 2147483647 + textureLodBias: + m_OverrideState: 1 + m_Value: 1 + m_RayLength: + m_OverrideState: 1 + m_Value: 3 + m_ClampValue: + m_OverrideState: 0 + m_Value: 1 + m_Denoise: + m_OverrideState: 1 + m_Value: 1 + m_DenoiserRadius: + m_OverrideState: 1 + m_Value: 10 + m_AffectSmoothSurfaces: + m_OverrideState: 0 + m_Value: 0 + mode: + m_OverrideState: 1 + m_Value: 2 + m_FullResolution: + m_OverrideState: 1 + m_Value: 0 + sampleCount: + m_OverrideState: 0 + m_Value: 1 + bounceCount: + m_OverrideState: 0 + m_Value: 1 + m_RayMaxIterationsRT: + m_OverrideState: 0 + m_Value: 48 +--- !u!114 &-789598458994953367 +MonoBehaviour: + m_ObjectHideFlags: 3 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0d7593b3a9277ac4696b20006c21dde2, type: 3} + m_Name: VisualEnvironment + m_EditorClassIdentifier: + active: 1 + skyType: + m_OverrideState: 1 + m_Value: 1 + cloudType: + m_OverrideState: 0 + m_Value: 0 + skyAmbientMode: + m_OverrideState: 0 + m_Value: 0 + fogType: + m_OverrideState: 0 + m_Value: 0 +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d7fd9488000d3734a9e00ee676215985, type: 3} + m_Name: Global Volume Profile_BothPreIntegrated + m_EditorClassIdentifier: + components: + - {fileID: -789598458994953367} + - {fileID: -5490847147131661617} + - {fileID: -1756342479024897208} + - {fileID: 2202121449804899189} + - {fileID: 5010985332367251263} +--- !u!114 &2202121449804899189 +MonoBehaviour: + m_ObjectHideFlags: 3 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2f1984a7ac01bf84b86559f7595cdc68, type: 3} + m_Name: LightCluster + m_EditorClassIdentifier: + active: 1 + cameraClusterRange: + m_OverrideState: 1 + m_Value: 50 +--- !u!114 &5010985332367251263 +MonoBehaviour: + m_ObjectHideFlags: 3 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d877a03bef431a847adca8ab343db3e1, type: 3} + m_Name: RayTracingSettings + m_EditorClassIdentifier: + active: 1 + rayBias: + m_OverrideState: 0 + m_Value: 0.001 + extendShadowCulling: + m_OverrideState: 1 + m_Value: 1 + extendCameraCulling: + m_OverrideState: 0 + m_Value: 0 + directionalShadowRayLength: + m_OverrideState: 0 + m_Value: 1000 + directionalShadowFallbackIntensity: + m_OverrideState: 0 + m_Value: 1 diff --git a/TestProjects/HDRP_DXR_Tests/Assets/Scenes/109_ReflectionFallbackBoth/Global Volume Profile_BothPreIntegrated.asset.meta b/TestProjects/HDRP_DXR_Tests/Assets/Scenes/109_ReflectionFallbackBoth/Global Volume Profile_BothPreIntegrated.asset.meta new file mode 100644 index 00000000000..565868e2438 --- /dev/null +++ b/TestProjects/HDRP_DXR_Tests/Assets/Scenes/109_ReflectionFallbackBoth/Global Volume Profile_BothPreIntegrated.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8c48ee0e53c5d5748955d2880a18294d +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/TestProjects/HDRP_DXR_Tests/Assets/Scenes/109_ReflectionFallbackBothPreIntegrated.unity b/TestProjects/HDRP_DXR_Tests/Assets/Scenes/109_ReflectionFallbackBothPreIntegrated.unity new file mode 100644 index 00000000000..82b135e4474 --- /dev/null +++ b/TestProjects/HDRP_DXR_Tests/Assets/Scenes/109_ReflectionFallbackBothPreIntegrated.unity @@ -0,0 +1,1600 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 256 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 1 + m_PVRDenoiserTypeDirect: 1 + m_PVRDenoiserTypeIndirect: 1 + m_PVRDenoiserTypeAO: 1 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_LightingSettings: {fileID: 0} +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &44363433 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 44363434} + m_Layer: 0 + m_Name: Walls + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 2147483647 + m_IsActive: 1 +--- !u!4 &44363434 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 44363433} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 505289216} + - {fileID: 45408303} + - {fileID: 2139628073} + - {fileID: 1526488697} + - {fileID: 2093752153} + m_Father: {fileID: 0} + m_RootOrder: 4 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &45408302 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 45408303} + - component: {fileID: 45408306} + - component: {fileID: 45408305} + - component: {fileID: 45408304} + m_Layer: 0 + m_Name: Cube (2) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 2147483647 + m_IsActive: 1 +--- !u!4 &45408303 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 45408302} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 5, y: 5, z: 0} + m_LocalScale: {x: 0.1, y: 10, z: 10} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 44363434} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!65 &45408304 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 45408302} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &45408305 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 45408302} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 257 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 076820d3621542a4caf12c44f5bb4450, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &45408306 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 45408302} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!115 &411984965 +MonoScript: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + serializedVersion: 5 + m_Script: + m_DefaultReferences: {} + m_Icon: {fileID: 0} + m_ExecutionOrder: 0 + m_ClassName: SceneObjectIDMapSceneAsset + m_Namespace: UnityEngine.Rendering.HighDefinition +--- !u!1 &505289215 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 505289216} + - component: {fileID: 505289219} + - component: {fileID: 505289218} + - component: {fileID: 505289217} + m_Layer: 0 + m_Name: Cube + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 2147483647 + m_IsActive: 1 +--- !u!4 &505289216 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 505289215} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 10, y: 0.1, z: 10} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 44363434} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!65 &505289217 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 505289215} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &505289218 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 505289215} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 257 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: b8ce17e5403a4964ab17fc31bcfc8cc7, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &505289219 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 505289215} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &648645594 +GameObject: + m_ObjectHideFlags: 19 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 648645596} + - component: {fileID: 648645595} + m_Layer: 0 + m_Name: SceneIDMap + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &648645595 +MonoBehaviour: + m_ObjectHideFlags: 19 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 648645594} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 411984965} + m_Name: + m_EditorClassIdentifier: + m_Entries: + - id: 1 + category: 0 + gameObject: {fileID: 819575859} +--- !u!4 &648645596 +Transform: + m_ObjectHideFlags: 19 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 648645594} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &819575859 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 819575862} + - component: {fileID: 819575861} + - component: {fileID: 819575860} + m_Layer: 0 + m_Name: Reflection Probe (1) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &819575860 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 819575859} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d0ef8dc2c2eabfa4e8cb77be57a837c0, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ProbeSettings: + frustum: + fieldOfViewMode: 1 + fixedValue: 90 + automaticScale: 1 + viewerScale: 1 + type: 0 + mode: 0 + realtimeMode: 0 + lighting: + multiplier: 1 + weight: 1 + lightLayer: 1 + fadeDistance: 10000 + rangeCompressionFactor: 1 + influence: + m_Shape: 0 + m_BoxSize: {x: 10, y: 5, z: 10} + m_BoxBlendDistancePositive: {x: 0, y: 0, z: 0} + m_BoxBlendDistanceNegative: {x: 0, y: 0, z: 0} + m_BoxBlendNormalDistancePositive: {x: 0, y: 0, z: 0} + m_BoxBlendNormalDistanceNegative: {x: 0, y: 0, z: 0} + m_BoxSideFadePositive: {x: 1, y: 1, z: 1} + m_BoxSideFadeNegative: {x: 1, y: 1, z: 1} + m_SphereRadius: 3 + m_SphereBlendDistance: 0 + m_SphereBlendNormalDistance: 0 + m_EditorAdvancedModeBlendDistancePositive: {x: 1, y: 1, z: 1} + m_EditorAdvancedModeBlendDistanceNegative: {x: 1, y: 1, z: 1} + m_EditorSimplifiedModeBlendDistance: 0 + m_EditorAdvancedModeBlendNormalDistancePositive: {x: 0, y: 0, z: 0} + m_EditorAdvancedModeBlendNormalDistanceNegative: {x: 0, y: 0, z: 0} + m_EditorSimplifiedModeBlendNormalDistance: 0 + m_EditorAdvancedModeEnabled: 0 + m_EditorAdvancedModeFaceFadePositive: {x: 1, y: 1, z: 1} + m_EditorAdvancedModeFaceFadeNegative: {x: 1, y: 1, z: 1} + m_Version: 1 + m_ObsoleteSphereBaseOffset: {x: 0, y: 0, z: 0} + m_ObsoleteOffset: {x: 0, y: 0, z: 0} + proxy: + m_Shape: 0 + m_BoxSize: {x: 1, y: 1, z: 1} + m_SphereRadius: 1 + m_CSVersion: 1 + m_ObsoleteSphereInfiniteProjection: 0 + m_ObsoleteBoxInfiniteProjection: 0 + proxySettings: + useInfluenceVolumeAsProxyVolume: 1 + capturePositionProxySpace: {x: 0, y: 0, z: 0} + captureRotationProxySpace: {x: 0, y: 0, z: 0, w: 1} + mirrorPositionProxySpace: {x: 0, y: 0, z: 0} + mirrorRotationProxySpace: {x: 0, y: 0, z: 0, w: 0} + resolutionScalable: + m_Override: 512 + m_UseOverride: 0 + m_Level: 0 + resolution: 0 + cameraSettings: + customRenderingSettings: 0 + renderingPathCustomFrameSettings: + bitDatas: + data1: 72198260625768269 + data2: 13763000477350297624 + lodBias: 1 + lodBiasMode: 0 + lodBiasQualityLevel: 0 + maximumLODLevel: 0 + maximumLODLevelMode: 0 + maximumLODLevelQualityLevel: 0 + sssQualityMode: 0 + sssQualityLevel: 0 + sssCustomSampleBudget: 20 + msaaMode: 1 + materialQuality: 0 + renderingPathCustomFrameSettingsOverrideMask: + mask: + data1: 0 + data2: 0 + bufferClearing: + clearColorMode: 0 + backgroundColorHDR: {r: 0.023529412, g: 0.07058824, b: 0.1882353, a: 0} + clearDepth: 1 + volumes: + layerMask: + serializedVersion: 2 + m_Bits: 1 + anchorOverride: {fileID: 0} + frustum: + mode: 0 + aspect: 1 + farClipPlaneRaw: 1000 + nearClipPlaneRaw: 0.3 + fieldOfView: 90 + projectionMatrix: + e00: 1 + e01: 0 + e02: 0 + e03: 0 + e10: 0 + e11: 1 + e12: 0 + e13: 0 + e20: 0 + e21: 0 + e22: 1 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 1 + culling: + useOcclusionCulling: 1 + cullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + sceneCullingMaskOverride: 0 + invertFaceCulling: 0 + flipYMode: 0 + probeLayerMask: + serializedVersion: 2 + m_Bits: 4294967295 + defaultFrameSettings: 0 + m_ObsoleteRenderingPath: 0 + m_ObsoleteFrameSettings: + overrides: 0 + enableShadow: 0 + enableContactShadows: 0 + enableShadowMask: 0 + enableSSR: 0 + enableSSAO: 0 + enableSubsurfaceScattering: 0 + enableTransmission: 0 + enableAtmosphericScattering: 0 + enableVolumetrics: 0 + enableReprojectionForVolumetrics: 0 + enableLightLayers: 0 + enableExposureControl: 1 + diffuseGlobalDimmer: 0 + specularGlobalDimmer: 0 + shaderLitMode: 0 + enableDepthPrepassWithDeferredRendering: 0 + enableTransparentPrepass: 0 + enableMotionVectors: 0 + enableObjectMotionVectors: 0 + enableDecals: 0 + enableRoughRefraction: 0 + enableTransparentPostpass: 0 + enableDistortion: 0 + enablePostprocess: 0 + enableOpaqueObjects: 0 + enableTransparentObjects: 0 + enableRealtimePlanarReflection: 0 + enableMSAA: 0 + enableAsyncCompute: 0 + runLightListAsync: 0 + runSSRAsync: 0 + runSSAOAsync: 0 + runContactShadowsAsync: 0 + runVolumeVoxelizationAsync: 0 + lightLoopSettings: + overrides: 0 + enableDeferredTileAndCluster: 0 + enableComputeLightEvaluation: 0 + enableComputeLightVariants: 0 + enableComputeMaterialVariants: 0 + enableFptlForForwardOpaque: 0 + enableBigTilePrepass: 0 + isFptlEnabled: 0 + roughReflections: 1 + distanceBasedRoughness: 0 + m_ProbeSettingsOverride: + probe: 0 + camera: + camera: 0 + m_ProxyVolume: {fileID: 0} + m_BakedTexture: {fileID: 8900000, guid: abd4dbdebbf56464b870d545473516b8, type: 3} + m_CustomTexture: {fileID: 0} + m_BakedRenderData: + m_WorldToCameraRHS: + e00: 0 + e01: 0 + e02: 0 + e03: 0 + e10: 0 + e11: 0 + e12: 0 + e13: 0 + e20: 0 + e21: 0 + e22: 0 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 0 + m_ProjectionMatrix: + e00: 0 + e01: 0 + e02: 0 + e03: 0 + e10: 0 + e11: 0 + e12: 0 + e13: 0 + e20: 0 + e21: 0 + e22: 0 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 0 + m_CapturePosition: {x: 0, y: 0, z: 0} + m_CaptureRotation: {x: 0, y: 0, z: 0, w: 0} + m_FieldOfView: 0 + m_Aspect: 0 + m_CustomRenderData: + m_WorldToCameraRHS: + e00: 0 + e01: 0 + e02: 0 + e03: 0 + e10: 0 + e11: 0 + e12: 0 + e13: 0 + e20: 0 + e21: 0 + e22: 0 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 0 + m_ProjectionMatrix: + e00: 0 + e01: 0 + e02: 0 + e03: 0 + e10: 0 + e11: 0 + e12: 0 + e13: 0 + e20: 0 + e21: 0 + e22: 0 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 0 + m_CapturePosition: {x: 0, y: 0, z: 0} + m_CaptureRotation: {x: 0, y: 0, z: 0, w: 0} + m_FieldOfView: 0 + m_Aspect: 0 + m_HDProbeVersion: 3 + m_ObsoleteInfiniteProjection: 1 + m_ObsoleteInfluenceVolume: + m_Shape: 0 + m_BoxSize: {x: 10, y: 10, z: 10} + m_BoxBlendDistancePositive: {x: 1, y: 1, z: 1} + m_BoxBlendDistanceNegative: {x: 1, y: 1, z: 1} + m_BoxBlendNormalDistancePositive: {x: 0, y: 0, z: 0} + m_BoxBlendNormalDistanceNegative: {x: 0, y: 0, z: 0} + m_BoxSideFadePositive: {x: 1, y: 1, z: 1} + m_BoxSideFadeNegative: {x: 1, y: 1, z: 1} + m_SphereRadius: 3 + m_SphereBlendDistance: 0 + m_SphereBlendNormalDistance: 0 + m_EditorAdvancedModeBlendDistancePositive: {x: 0, y: 0, z: 0} + m_EditorAdvancedModeBlendDistanceNegative: {x: 0, y: 0, z: 0} + m_EditorSimplifiedModeBlendDistance: 0 + m_EditorAdvancedModeBlendNormalDistancePositive: {x: 0, y: 0, z: 0} + m_EditorAdvancedModeBlendNormalDistanceNegative: {x: 0, y: 0, z: 0} + m_EditorSimplifiedModeBlendNormalDistance: 0 + m_EditorAdvancedModeEnabled: 0 + m_EditorAdvancedModeFaceFadePositive: {x: 1, y: 1, z: 1} + m_EditorAdvancedModeFaceFadeNegative: {x: 1, y: 1, z: 1} + m_Version: 1 + m_ObsoleteSphereBaseOffset: {x: 0, y: 0, z: 0} + m_ObsoleteOffset: {x: 0, y: 0, z: 0} + m_ObsoleteFrameSettings: + overrides: 0 + enableShadow: 0 + enableContactShadows: 0 + enableShadowMask: 0 + enableSSR: 0 + enableSSAO: 0 + enableSubsurfaceScattering: 0 + enableTransmission: 0 + enableAtmosphericScattering: 0 + enableVolumetrics: 0 + enableReprojectionForVolumetrics: 0 + enableLightLayers: 0 + enableExposureControl: 1 + diffuseGlobalDimmer: 0 + specularGlobalDimmer: 0 + shaderLitMode: 0 + enableDepthPrepassWithDeferredRendering: 0 + enableTransparentPrepass: 0 + enableMotionVectors: 0 + enableObjectMotionVectors: 0 + enableDecals: 0 + enableRoughRefraction: 0 + enableTransparentPostpass: 0 + enableDistortion: 0 + enablePostprocess: 0 + enableOpaqueObjects: 0 + enableTransparentObjects: 0 + enableRealtimePlanarReflection: 0 + enableMSAA: 0 + enableAsyncCompute: 0 + runLightListAsync: 0 + runSSRAsync: 0 + runSSAOAsync: 0 + runContactShadowsAsync: 0 + runVolumeVoxelizationAsync: 0 + lightLoopSettings: + overrides: 0 + enableDeferredTileAndCluster: 0 + enableComputeLightEvaluation: 0 + enableComputeLightVariants: 0 + enableComputeMaterialVariants: 0 + enableFptlForForwardOpaque: 0 + enableBigTilePrepass: 0 + isFptlEnabled: 0 + m_ObsoleteMultiplier: 1 + m_ObsoleteWeight: 1 + m_ObsoleteMode: 0 + m_ObsoleteLightLayers: 1 + m_ObsoleteCaptureSettings: + overrides: 0 + clearColorMode: 0 + backgroundColorHDR: {r: 0.023529412, g: 0.07058824, b: 0.1882353, a: 0} + clearDepth: 1 + cullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + useOcclusionCulling: 1 + volumeLayerMask: + serializedVersion: 2 + m_Bits: 1 + volumeAnchorOverride: {fileID: 0} + projection: 0 + nearClipPlane: 0.3 + farClipPlane: 1000 + fieldOfView: 90 + orthographicSize: 5 + renderingPath: 0 + shadowDistance: 100 + m_ReflectionProbeVersion: 9 + m_ObsoleteInfluenceShape: 0 + m_ObsoleteInfluenceSphereRadius: 3 + m_ObsoleteBlendDistancePositive: {x: 1, y: 1, z: 1} + m_ObsoleteBlendDistanceNegative: {x: 1, y: 1, z: 1} + m_ObsoleteBlendNormalDistancePositive: {x: 0, y: 0, z: 0} + m_ObsoleteBlendNormalDistanceNegative: {x: 0, y: 0, z: 0} + m_ObsoleteBoxSideFadePositive: {x: 1, y: 1, z: 1} + m_ObsoleteBoxSideFadeNegative: {x: 1, y: 1, z: 1} +--- !u!215 &819575861 +ReflectionProbe: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 819575859} + m_Enabled: 1 + serializedVersion: 2 + m_Type: 0 + m_Mode: 2 + m_RefreshMode: 2 + m_TimeSlicingMode: 0 + m_Resolution: 128 + m_UpdateFrequency: 0 + m_BoxSize: {x: 10, y: 5, z: 10} + m_BoxOffset: {x: 0, y: 0, z: 0} + m_NearClip: 0.3 + m_FarClip: 1000 + m_ShadowDistance: 100 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_IntensityMultiplier: 1 + m_BlendDistance: 0 + m_HDR: 1 + m_BoxProjection: 0 + m_RenderDynamicObjects: 1 + m_UseOcclusionCulling: 1 + m_Importance: 1 + m_CustomBakedTexture: {fileID: 0} +--- !u!4 &819575862 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 819575859} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 2.5, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1001 &1003513217 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 1132393308280272, guid: c07ace9ab142ca9469fa377877c2f1e7, type: 3} + propertyPath: m_Name + value: HDRP_Test_Camera + objectReference: {fileID: 0} + - target: {fileID: 1132393308280272, guid: c07ace9ab142ca9469fa377877c2f1e7, type: 3} + propertyPath: m_IsActive + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 4209882255362944, guid: c07ace9ab142ca9469fa377877c2f1e7, type: 3} + propertyPath: m_RootOrder + value: 6 + objectReference: {fileID: 0} + - target: {fileID: 4209882255362944, guid: c07ace9ab142ca9469fa377877c2f1e7, type: 3} + propertyPath: m_LocalPosition.x + value: -3 + objectReference: {fileID: 0} + - target: {fileID: 4209882255362944, guid: c07ace9ab142ca9469fa377877c2f1e7, type: 3} + propertyPath: m_LocalPosition.y + value: 2.5 + objectReference: {fileID: 0} + - target: {fileID: 4209882255362944, guid: c07ace9ab142ca9469fa377877c2f1e7, type: 3} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4209882255362944, guid: c07ace9ab142ca9469fa377877c2f1e7, type: 3} + propertyPath: m_LocalRotation.w + value: 0.7071068 + objectReference: {fileID: 0} + - target: {fileID: 4209882255362944, guid: c07ace9ab142ca9469fa377877c2f1e7, type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4209882255362944, guid: c07ace9ab142ca9469fa377877c2f1e7, type: 3} + propertyPath: m_LocalRotation.y + value: 0.7071068 + objectReference: {fileID: 0} + - target: {fileID: 4209882255362944, guid: c07ace9ab142ca9469fa377877c2f1e7, type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4209882255362944, guid: c07ace9ab142ca9469fa377877c2f1e7, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 4209882255362944, guid: c07ace9ab142ca9469fa377877c2f1e7, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 90 + objectReference: {fileID: 0} + - target: {fileID: 4209882255362944, guid: c07ace9ab142ca9469fa377877c2f1e7, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 20109210616973140, guid: c07ace9ab142ca9469fa377877c2f1e7, + type: 3} + propertyPath: m_Enabled + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 114777190906822814, guid: c07ace9ab142ca9469fa377877c2f1e7, + type: 3} + propertyPath: m_Version + value: 8 + objectReference: {fileID: 0} + - target: {fileID: 114995348509370400, guid: c07ace9ab142ca9469fa377877c2f1e7, + type: 3} + propertyPath: waitFrames + value: 10 + objectReference: {fileID: 0} + - target: {fileID: 114995348509370400, guid: c07ace9ab142ca9469fa377877c2f1e7, + type: 3} + propertyPath: xrCompatible + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 114995348509370400, guid: c07ace9ab142ca9469fa377877c2f1e7, + type: 3} + propertyPath: renderPipelineAsset + value: + objectReference: {fileID: 11400000, guid: 14a0f3aaa5e78a3439ec76d270471ebe, + type: 2} + - target: {fileID: 114995348509370400, guid: c07ace9ab142ca9469fa377877c2f1e7, + type: 3} + propertyPath: checkMemoryAllocation + value: 0 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: c07ace9ab142ca9469fa377877c2f1e7, type: 3} +--- !u!1 &1394701655 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1394701657} + - component: {fileID: 1394701656} + m_Layer: 0 + m_Name: Global Volume + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1394701656 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1394701655} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 172515602e62fb746b5d573b38a5fe58, type: 3} + m_Name: + m_EditorClassIdentifier: + isGlobal: 1 + priority: 0 + blendDistance: 0 + weight: 1 + sharedProfile: {fileID: 11400000, guid: 8c48ee0e53c5d5748955d2880a18294d, type: 2} +--- !u!4 &1394701657 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1394701655} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0.16200088, y: -0.583568, z: 13.533585} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1526488696 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1526488697} + - component: {fileID: 1526488700} + - component: {fileID: 1526488699} + - component: {fileID: 1526488698} + m_Layer: 0 + m_Name: Cube (4) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 2147483647 + m_IsActive: 1 +--- !u!4 &1526488697 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1526488696} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 5, z: 5} + m_LocalScale: {x: 10, y: 10, z: 0.1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 44363434} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!65 &1526488698 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1526488696} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &1526488699 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1526488696} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 257 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: b8ce17e5403a4964ab17fc31bcfc8cc7, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &1526488700 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1526488696} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &1801634923 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1801634924} + - component: {fileID: 1801634927} + - component: {fileID: 1801634926} + - component: {fileID: 1801634925} + m_Layer: 10 + m_Name: Cube (1) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1801634924 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1801634923} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 2.966, y: 0.5, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!65 &1801634925 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1801634923} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &1801634926 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1801634923} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 257 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 73c176f402d2c2f4d929aa5da7585d17, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &1801634927 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1801634923} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &1881085960 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1881085963} + - component: {fileID: 1881085962} + - component: {fileID: 1881085961} + m_Layer: 0 + m_Name: Point Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1881085961 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1881085960} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7a68c43fe1f2a47cfa234b5eeaa98012, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Intensity: 226.8765 + m_EnableSpotReflector: 1 + m_LuxAtDistance: 1 + m_InnerSpotPercent: 0 + m_SpotIESCutoffPercent: 100 + m_LightDimmer: 1 + m_VolumetricDimmer: 1 + m_LightUnit: 0 + m_FadeDistance: 10000 + m_VolumetricFadeDistance: 10000 + m_AffectDiffuse: 1 + m_AffectSpecular: 1 + m_NonLightmappedOnly: 0 + m_ShapeWidth: 0.5 + m_ShapeHeight: 0.5 + m_AspectRatio: 1 + m_ShapeRadius: 0.025 + m_SoftnessScale: 1 + m_UseCustomSpotLightShadowCone: 0 + m_CustomSpotLightShadowCone: 30 + m_MaxSmoothness: 0.99 + m_ApplyRangeAttenuation: 1 + m_DisplayAreaLightEmissiveMesh: 0 + m_AreaLightCookie: {fileID: 0} + m_IESPoint: {fileID: 0} + m_IESSpot: {fileID: 0} + m_IncludeForRayTracing: 1 + m_AreaLightShadowCone: 120 + m_UseScreenSpaceShadows: 0 + m_InteractsWithSky: 1 + m_AngularDiameter: 0.5 + m_FlareSize: 2 + m_FlareTint: {r: 1, g: 1, b: 1, a: 1} + m_FlareFalloff: 4 + m_SurfaceTexture: {fileID: 0} + m_SurfaceTint: {r: 1, g: 1, b: 1, a: 1} + m_Distance: 1.5e+11 + m_UseRayTracedShadows: 0 + m_NumRayTracingSamples: 4 + m_FilterTracedShadow: 1 + m_FilterSizeTraced: 16 + m_SunLightConeAngle: 0.5 + m_LightShadowRadius: 0.5 + m_SemiTransparentShadow: 0 + m_ColorShadow: 1 + m_DistanceBasedFiltering: 0 + m_EvsmExponent: 15 + m_EvsmLightLeakBias: 0 + m_EvsmVarianceBias: 0.00001 + m_EvsmBlurPasses: 0 + m_LightlayersMask: 1 + m_LinkShadowLayers: 1 + m_ShadowNearPlane: 0.1 + m_BlockerSampleCount: 24 + m_FilterSampleCount: 16 + m_MinFilterSize: 0.1 + m_KernelSize: 5 + m_LightAngle: 1 + m_MaxDepthBias: 0.001 + m_ShadowResolution: + m_Override: 512 + m_UseOverride: 1 + m_Level: 0 + m_ShadowDimmer: 1 + m_VolumetricShadowDimmer: 1 + m_ShadowFadeDistance: 10000 + m_UseContactShadow: + m_Override: 0 + m_UseOverride: 1 + m_Level: 0 + m_RayTracedContactShadow: 0 + m_ShadowTint: {r: 0, g: 0, b: 0, a: 1} + m_PenumbraTint: 0 + m_NormalBias: 0.75 + m_SlopeBias: 0.5 + m_ShadowUpdateMode: 0 + m_AlwaysDrawDynamicShadows: 0 + m_UpdateShadowOnLightMovement: 0 + m_CachedShadowTranslationThreshold: 0.01 + m_CachedShadowAngularThreshold: 0.5 + m_BarnDoorAngle: 90 + m_BarnDoorLength: 0.05 + m_preserveCachedShadow: 0 + m_OnDemandShadowRenderOnPlacement: 1 + m_ShadowCascadeRatios: + - 0.05 + - 0.2 + - 0.3 + m_ShadowCascadeBorders: + - 0.2 + - 0.2 + - 0.2 + - 0.2 + m_ShadowAlgorithm: 0 + m_ShadowVariant: 0 + m_ShadowPrecision: 0 + useOldInspector: 0 + useVolumetric: 1 + featuresFoldout: 1 + m_AreaLightEmissiveMeshShadowCastingMode: 0 + m_AreaLightEmissiveMeshMotionVectorGenerationMode: 0 + m_AreaLightEmissiveMeshLayer: -1 + m_Version: 11 + m_ObsoleteShadowResolutionTier: 1 + m_ObsoleteUseShadowQualitySettings: 0 + m_ObsoleteCustomShadowResolution: 512 + m_ObsoleteContactShadows: 0 + m_PointlightHDType: 0 + m_SpotLightShape: 0 + m_AreaLightShape: 0 +--- !u!108 &1881085962 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1881085960} + m_Enabled: 1 + serializedVersion: 10 + m_Type: 2 + m_Shape: 0 + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_Intensity: 18.054256 + m_Range: 10 + m_SpotAngle: 30 + m_InnerSpotAngle: 21.80208 + m_CookieSize: 10 + m_Shadows: + m_Type: 1 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_CullingMatrixOverride: + e00: 1 + e01: 0 + e02: 0 + e03: 0 + e10: 0 + e11: 1 + e12: 0 + e13: 0 + e20: 0 + e21: 0 + e22: 1 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 1 + m_UseCullingMatrixOverride: 0 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingLayerMask: 1 + m_Lightmapping: 4 + m_LightShadowCasterMode: 2 + m_AreaSize: {x: 0.5, y: 0.5} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 1 + m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} + m_UseBoundingSphereOverride: 0 + m_UseViewFrustumForShadowCasterCull: 1 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &1881085963 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1881085960} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 3.13, z: 0.066} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 5 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &2093752152 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2093752153} + - component: {fileID: 2093752156} + - component: {fileID: 2093752155} + - component: {fileID: 2093752154} + m_Layer: 0 + m_Name: Cube (5) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 2147483647 + m_IsActive: 1 +--- !u!4 &2093752153 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2093752152} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 5, z: -5} + m_LocalScale: {x: 10, y: 10, z: 0.1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 44363434} + m_RootOrder: 4 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!65 &2093752154 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2093752152} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &2093752155 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2093752152} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 257 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: b8ce17e5403a4964ab17fc31bcfc8cc7, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &2093752156 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2093752152} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &2139628072 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2139628073} + - component: {fileID: 2139628076} + - component: {fileID: 2139628075} + - component: {fileID: 2139628074} + m_Layer: 0 + m_Name: Cube (3) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 2147483647 + m_IsActive: 1 +--- !u!4 &2139628073 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2139628072} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: -5, y: 5, z: 0} + m_LocalScale: {x: 0.1, y: 10, z: 10} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 44363434} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!65 &2139628074 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2139628072} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &2139628075 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2139628072} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 257 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 2ddf5fb9ceb11f64ca9dbf65ee33f74c, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &2139628076 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2139628072} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} diff --git a/TestProjects/HDRP_DXR_Tests/Assets/Scenes/109_ReflectionFallbackBothPreIntegrated.unity.meta b/TestProjects/HDRP_DXR_Tests/Assets/Scenes/109_ReflectionFallbackBothPreIntegrated.unity.meta new file mode 100644 index 00000000000..abcce8c6450 --- /dev/null +++ b/TestProjects/HDRP_DXR_Tests/Assets/Scenes/109_ReflectionFallbackBothPreIntegrated.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 888f6168a31b68646b8cbb7caccee97b +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/TestProjects/HDRP_DXR_Tests/Assets/Scenes/RayTracedReflectionsData/M_ReflectiveRough.mat b/TestProjects/HDRP_DXR_Tests/Assets/Scenes/RayTracedReflectionsData/M_ReflectiveRough.mat new file mode 100644 index 00000000000..adc454492a2 --- /dev/null +++ b/TestProjects/HDRP_DXR_Tests/Assets/Scenes/RayTracedReflectionsData/M_ReflectiveRough.mat @@ -0,0 +1,298 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-1395542822595540692 +MonoBehaviour: + m_ObjectHideFlags: 11 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 12 + hdPluginSubTargetMaterialVersions: + m_Keys: [] + m_Values: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: M_ReflectiveRough + m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3} + m_ShaderKeywords: _DISABLE_SSR_TRANSPARENT _NORMALMAP_TANGENT_SPACE + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2225 + stringTagMap: {} + disabledShaderPasses: + - DistortionVectors + - MOTIONVECTORS + - TransparentDepthPrepass + - TransparentDepthPostpass + - TransparentBackface + - RayTracingPrepass + - ForwardEmissiveForDeferred + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _AnisotropyMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseColorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BentNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BentNormalMapOS: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _CoatMaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DistortionVectorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissiveColorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _HeightMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _IridescenceMaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _IridescenceThicknessMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMapOS: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecularColorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SubsurfaceMaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TangentMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TangentMapOS: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ThicknessMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TransmittanceColorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AORemapMax: 1 + - _AORemapMin: 0 + - _ATDistance: 1 + - _AddPrecomputedVelocity: 0 + - _AlbedoAffectEmissive: 0 + - _AlphaCutoff: 0.5 + - _AlphaCutoffEnable: 0 + - _AlphaCutoffPostpass: 0.5 + - _AlphaCutoffPrepass: 0.5 + - _AlphaCutoffShadow: 0.5 + - _AlphaDstBlend: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _Anisotropy: 0 + - _BlendMode: 0 + - _CoatMask: 0 + - _CullMode: 2 + - _CullModeForward: 2 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailAlbedoScale: 1 + - _DetailNormalScale: 1 + - _DetailSmoothnessScale: 1 + - _DiffusionProfile: 0 + - _DiffusionProfileHash: 0 + - _DisplacementLockObjectScale: 1 + - _DisplacementLockTilingScale: 1 + - _DisplacementMode: 0 + - _DistortionBlendMode: 0 + - _DistortionBlurBlendMode: 0 + - _DistortionBlurDstBlend: 1 + - _DistortionBlurRemapMax: 1 + - _DistortionBlurRemapMin: 0 + - _DistortionBlurScale: 1 + - _DistortionBlurSrcBlend: 1 + - _DistortionDepthTest: 1 + - _DistortionDstBlend: 1 + - _DistortionEnable: 0 + - _DistortionScale: 1 + - _DistortionSrcBlend: 1 + - _DistortionVectorBias: -1 + - _DistortionVectorScale: 2 + - _DoubleSidedEnable: 0 + - _DoubleSidedGIMode: 0 + - _DoubleSidedNormalMode: 1 + - _Drag: 1 + - _DstBlend: 0 + - _EmissiveColorMode: 1 + - _EmissiveExposureWeight: 1 + - _EmissiveIntensity: 1 + - _EmissiveIntensityUnit: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _EnableGeometricSpecularAA: 0 + - _EnableMotionVectorForVertexAnimation: 0 + - _EnableSpecularOcclusion: 0 + - _EnableWind: 0 + - _EnergyConservingSpecularColor: 1 + - _ForceForwardEmissive: 0 + - _HdrpVersion: 2 + - _HeightAmplitude: 0.02 + - _HeightCenter: 0.5 + - _HeightMapParametrization: 0 + - _HeightMax: 1 + - _HeightMin: -1 + - _HeightOffset: 0 + - _HeightPoMAmplitude: 2 + - _HeightTessAmplitude: 2 + - _HeightTessCenter: 0.5 + - _InitialBend: 1 + - _InvTilingScale: 1 + - _Ior: 1 + - _IridescenceMask: 1 + - _IridescenceThickness: 1 + - _LinkDetailsWithBase: 1 + - _MaterialID: 1 + - _Metallic: 1 + - _MetallicRemapMax: 1 + - _MetallicRemapMin: 0 + - _NormalMapSpace: 0 + - _NormalScale: 1 + - _OpaqueCullMode: 2 + - _PPDLodThreshold: 5 + - _PPDMaxSamples: 15 + - _PPDMinSamples: 5 + - _PPDPrimitiveLength: 1 + - _PPDPrimitiveWidth: 1 + - _RayTracing: 0 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _SSRefractionProjectionModel: 0 + - _ShiverDirectionality: 0.5 + - _ShiverDrag: 0.2 + - _Smoothness: 0.8 + - _SmoothnessRemapMax: 1 + - _SmoothnessRemapMin: 0 + - _SpecularAAScreenSpaceVariance: 0.1 + - _SpecularAAThreshold: 0.2 + - _SpecularOcclusionMode: 1 + - _SrcBlend: 1 + - _StencilRef: 0 + - _StencilRefDepth: 8 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 10 + - _StencilRefMV: 40 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 8 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 14 + - _StencilWriteMaskMV: 40 + - _Stiffness: 1 + - _SubsurfaceMask: 1 + - _SupportDecals: 1 + - _SurfaceType: 0 + - _TexWorldScale: 1 + - _TexWorldScaleEmissive: 1 + - _Thickness: 1 + - _ThicknessMultiplier: 1 + - _TransmissionEnable: 1 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 0 + - _UVBase: 0 + - _UVDetail: 0 + - _UVEmissive: 0 + - _UseEmissiveIntensity: 0 + - _UseShadowThreshold: 0 + - _ZTestDepthEqualForOpaque: 3 + - _ZTestGBuffer: 4 + - _ZTestModeDistortion: 4 + - _ZTestTransparent: 4 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _BaseColorMap_MipInfo: {r: 0, g: 0, b: 0, a: 0} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _DiffusionProfileAsset: {r: 0, g: 0, b: 0, a: 0} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _EmissiveColor: {r: 0, g: 0, b: 0, a: 1} + - _EmissiveColorLDR: {r: 0, g: 0, b: 0, a: 1} + - _InvPrimScale: {r: 1, g: 1, b: 0, a: 0} + - _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0} + - _SpecularColor: {r: 1, g: 1, b: 1, a: 1} + - _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0} + - _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1} + - _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0} + - _UVMappingMask: {r: 1, g: 0, b: 0, a: 0} + - _UVMappingMaskEmissive: {r: 1, g: 0, b: 0, a: 0} + m_BuildTextureStacks: [] diff --git a/TestProjects/HDRP_DXR_Tests/Assets/Scenes/RayTracedReflectionsData/M_ReflectiveRough.mat.meta b/TestProjects/HDRP_DXR_Tests/Assets/Scenes/RayTracedReflectionsData/M_ReflectiveRough.mat.meta new file mode 100644 index 00000000000..627294a4582 --- /dev/null +++ b/TestProjects/HDRP_DXR_Tests/Assets/Scenes/RayTracedReflectionsData/M_ReflectiveRough.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 076820d3621542a4caf12c44f5bb4450 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/TestProjects/HDRP_DXR_Tests/ProjectSettings/EditorBuildSettings.asset b/TestProjects/HDRP_DXR_Tests/ProjectSettings/EditorBuildSettings.asset index af3aeb69a15..e8329e4fd54 100644 --- a/TestProjects/HDRP_DXR_Tests/ProjectSettings/EditorBuildSettings.asset +++ b/TestProjects/HDRP_DXR_Tests/ProjectSettings/EditorBuildSettings.asset @@ -53,6 +53,9 @@ EditorBuildSettings: - enabled: 1 path: Assets/Scenes/109_ReflectionFallbackBoth.unity guid: 7dd9ef30d1f9f704a9dbcc3e68cc4475 + - enabled: 1 + path: Assets/Scenes/109_ReflectionFallbackBothPreIntegrated.unity + guid: 888f6168a31b68646b8cbb7caccee97b - enabled: 1 path: Assets/Scenes/109_ReflectionFallbackNone.unity guid: 05a8727ee9005474faced212351902f4 From 617b71872ecd2a2c6c8d4afcee55fa003f2bb798 Mon Sep 17 00:00:00 2001 From: slunity Date: Fri, 18 Jun 2021 02:22:44 -0400 Subject: [PATCH 11/12] AxF Raytracing: fix performance mode distillation that was removed in 9d6db83478c213bc066e5f728d94b7faa6662543 --- .../Runtime/Material/AxF/AxF.cs | 6 ++ .../Runtime/Material/AxF/AxF.cs.hlsl | 5 ++ .../Runtime/Material/AxF/AxF.hlsl | 81 ++++++++++++++++--- .../Runtime/Material/AxF/AxFRayTracing.hlsl | 28 +++++-- 4 files changed, 104 insertions(+), 16 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.cs index 489c371127a..7b5fb33c106 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.cs @@ -187,6 +187,12 @@ public struct BSDFData [SurfaceDataAttributes(new string[] { "Geometric Normal", "Geometric Normal View Space" }, true, checkIsNormalized = true)] public Vector3 geomNormalWS; + + // Needed for raytracing. + // TODO: should just modify FitToStandardLit in ShaderPassRaytracingGBuffer.hlsl and callee + // to have "V" (from -incidentDir) + [SurfaceDataAttributes("View Direction", true)] + public Vector3 viewWS; }; //----------------------------------------------------------------------------- diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.cs.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.cs.hlsl index 1a096ef4d06..b15b95ff80f 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.cs.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.cs.hlsl @@ -84,6 +84,7 @@ #define DEBUGVIEW_AXF_BSDFDATA_CLEARCOAT_IOR (1277) #define DEBUGVIEW_AXF_BSDFDATA_GEOMETRIC_NORMAL (1278) #define DEBUGVIEW_AXF_BSDFDATA_GEOMETRIC_NORMAL_VIEW_SPACE (1279) +#define DEBUGVIEW_AXF_BSDFDATA_VIEW_DIRECTION (1280) // Generated from UnityEngine.Rendering.HighDefinition.AxF+SurfaceData // PackingRules = Exact @@ -152,6 +153,7 @@ struct BSDFData float3 clearcoatNormalWS; float clearcoatIOR; float3 geomNormalWS; + float3 viewWS; }; // @@ -356,6 +358,9 @@ void GetGeneratedBSDFDataDebug(uint paramId, BSDFData bsdfdata, inout float3 res case DEBUGVIEW_AXF_BSDFDATA_GEOMETRIC_NORMAL_VIEW_SPACE: result = IsNormalized(bsdfdata.geomNormalWS)? bsdfdata.geomNormalWS * 0.5 + 0.5 : float3(1.0, 0.0, 0.0); break; + case DEBUGVIEW_AXF_BSDFDATA_VIEW_DIRECTION: + result = bsdfdata.viewWS * 0.5 + 0.5; + break; } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.hlsl index d6d90a4571c..f6a4ef6deaf 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.hlsl @@ -885,7 +885,7 @@ float3 GetColorBaseFresnelF0(BSDFData bsdfData) // For raytracing fit to standard Lit: // Giving V will use a codepath where V is used, otherwise, the ortho direction is used -void GetCarPaintSpecularColorAndFlakesComponent(SurfaceData surfaceData, out float3 singleBRDFColor, out float3 singleFlakesComponent, out float coatFGD, float3 V = 0) +void GetCarPaintSpecularColorAndFlakesComponent(BSDFData bsdfData, out float3 singleBRDFColor, out float3 singleFlakesComponent, out float coatFGD, float3 V = 0) { //TODO: use approximated top lobe dir (if refractive coat) to have more appropriate and consistent base dirs @@ -894,38 +894,95 @@ void GetCarPaintSpecularColorAndFlakesComponent(SurfaceData surfaceData, out flo if (useViewDir) { - float3 coatNormalWS = HasClearcoat() ? surfaceData.clearcoatNormalWS : surfaceData.normalWS; + float3 coatNormalWS = HasClearcoat() ? bsdfData.clearcoatNormalWS : bsdfData.normalWS; float coatNdotV = dot(coatNormalWS, V); - coatFGD = HasClearcoat() ? F_FresnelDieletricSafe(surfaceData.clearcoatIOR, coatNdotV) : 0; + coatFGD = HasClearcoat() ? F_FresnelDieletricSafe(bsdfData.clearcoatIOR, coatNdotV) : 0; float3 refractedViewWS = V; float thetaHForBRDFColor = FixedBRDFColorThetaHForIndirectLight; float thetaHForFlakes = FixedFlakesThetaHForIndirectLight; if (HasClearcoatAndRefraction()) { - refractedViewWS = -Refract(V, coatNormalWS, 1.0 / surfaceData.clearcoatIOR); - thetaHForBRDFColor = Refract(thetaHForBRDFColor, 1.0 / surfaceData.clearcoatIOR); - thetaHForFlakes = Refract(thetaHForFlakes, 1.0 / surfaceData.clearcoatIOR); + refractedViewWS = -Refract(V, coatNormalWS, 1.0 / bsdfData.clearcoatIOR); + thetaHForBRDFColor = Refract(thetaHForBRDFColor, 1.0 / bsdfData.clearcoatIOR); + thetaHForFlakes = Refract(thetaHForFlakes, 1.0 / bsdfData.clearcoatIOR); } - float NdotV = dot(surfaceData.normalWS, refractedViewWS); + float NdotV = dot(bsdfData.normalWS, refractedViewWS); float thetaH = 0; //FastACosPos(clamp(NdotH, 0, 1)); float thetaD = FastACosPos(clamp(NdotV, 0, 1)); singleBRDFColor = GetBRDFColor(thetaHForBRDFColor, thetaD); - singleFlakesComponent = CarPaint_BTF(thetaHForFlakes, thetaD, surfaceData, (BSDFData)0, /*useBSDFData:*/false); + singleFlakesComponent = CarPaint_BTF(thetaHForFlakes, thetaD, (SurfaceData)0, bsdfData, /*useBSDFData:*/true); } else { //coatFGD = HasClearcoat() ? F_FresnelDieletricSafe(surfaceData.clearcoatIOR, 1) : 0; // ...this is just F0 of coat, so we do the equivalent: - coatFGD = HasClearcoat() ? IorToFresnel0(surfaceData.clearcoatIOR) : 0; + coatFGD = HasClearcoat() ? IorToFresnel0(bsdfData.clearcoatIOR) : 0; singleBRDFColor = GetBRDFColor(0,0); - singleFlakesComponent = CarPaint_BTF(0, 0, surfaceData, (BSDFData)0, /*useBSDFData:*/false); + singleFlakesComponent = CarPaint_BTF(0, 0,(SurfaceData)0, bsdfData, /*useBSDFData:*/true); } } +// For raytracing fit to standard Lit: +// Giving V will use a codepath where V is used, this is relevant only for carpaint model +// (cf GetColorBaseDiffuse() and GetColorBaseFresnelF0()) +void GetBaseSurfaceColorAndF0(BSDFData bsdfData, out float3 diffuseColor, out float3 fresnel0, out float3 specBRDFColor, out float3 singleFlakesComponent, out float coatFGD, float3 V = 0, bool mixFlakes = false) +{ + coatFGD = 0; + singleFlakesComponent = (float3)0; + fresnel0 = (float3)0; + float3 specularColor = (float3)0; + specBRDFColor = float3(1,1,1); // only used for carpaint + diffuseColor = bsdfData.diffuseColor; + +#ifdef _AXF_BRDF_TYPE_SVBRDF + + specularColor = bsdfData.specularColor; + fresnel0 = bsdfData.fresnel0; // See AxfData.hlsl: the actual sampled texture is always 1 channel, if we ever find otherwise, we will use the others. + fresnel0 = HasFresnelTerm() ? fresnel0.r * specularColor : specularColor; + +#elif defined(_AXF_BRDF_TYPE_CAR_PAINT) + + GetCarPaintSpecularColorAndFlakesComponent(bsdfData, /*out*/specBRDFColor, /*out*/singleFlakesComponent, /*out*/coatFGD, V); + + // For carpaint, diffuseColor is not chromatic. + // A chromatic diffuse albedo is the result of a scalar diffuse coefficient multiplied by the brdf color table value. + specularColor = specBRDFColor; + diffuseColor *= specBRDFColor; + fresnel0 = saturate(3*bsdfData.fresnel0);//GetCarPaintFresnel0() TODO: presumably better fit using V, see also GetCarPaintSpecularColor that uses V + fresnel0 = fresnel0.r * specularColor; + + if (mixFlakes) + { + float maxf0 = Max3(fresnel0.r, fresnel0.g, fresnel0.b); + fresnel0 = saturate(singleFlakesComponent + fresnel0); + } + +#endif + + float baseEnergy = (1-coatFGD); // should be Sq but at this point we eyeball anyway, + //specularColor *= baseEnergy; + //diffuseColor *= baseEnergy; + //...commented, seems better without it. +} + +void GetRoughnessNormalCoatMaskForFitToStandardLit(BSDFData bsdfData, float coatFGD, out float3 normalWS, out float roughness, out float coatMask) +{ + normalWS = bsdfData.normalWS; // todo: "refract back" hack + // Try to simulate apparent roughness increase when he have refraction as we can't store refracted V in the GBUFFER, + // we could try another hack and modify the normal too. + roughness = GetScalarRoughness(bsdfData.roughness); + roughness = saturate(roughness * (HasClearcoatAndRefraction() ? (max(1, bsdfData.clearcoatIOR)) : 1) ); + coatMask = HasClearcoat()? Sq(coatFGD) * Max3(bsdfData.clearcoatColor.r, bsdfData.clearcoatColor.g, bsdfData.clearcoatColor.b) : 0; + // Sq(coatFGD) is a hack to better fit what AxF shows vs the usage of the coatmask with Lit + coatMask = 0; + //...disable for now coat reduces too much visibility of primary surface and in any case in performance mode where we use FitToStandardLit, + //we will not get another reflection bounce so the coat reflection will be a fallback probe +} + float3 GetColorBaseDiffuse(BSDFData bsdfData) { float3 diffuseColor = 0; @@ -1212,6 +1269,10 @@ BSDFData ConvertSurfaceDataToBSDFData(uint2 positionSS, SurfaceData surfaceData) bsdfData.ambientOcclusion = surfaceData.ambientOcclusion; bsdfData.specularOcclusion = surfaceData.specularOcclusion; + // V is needed for raytracing performance fit to lit: + // TODO: should just modify FitToStandardLit in ShaderPassRaytracingGBuffer.hlsl and callee + // to have "V" (from -incidentDir) + bsdfData.viewWS = surfaceData.viewWS; bsdfData.normalWS = surfaceData.normalWS; bsdfData.tangentWS = surfaceData.tangentWS; bsdfData.bitangentWS = cross(bsdfData.normalWS, bsdfData.tangentWS); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxFRayTracing.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxFRayTracing.hlsl index 26ef939d9c1..d3713a66551 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxFRayTracing.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxFRayTracing.hlsl @@ -86,13 +86,29 @@ void FitToStandardLit( BSDFData bsdfData , uint2 positionSS , out StandardBSDFData outStandardlit) { + float3 specBRDFColor; // for carpaint, will be white otherwise + float3 singleFlakesComponent; + float scalarRoughness; + float coatFGD; + + // We can fake flakes by mixing a component in the diffuse color + // or the F0, with the later maybe averaging the f0 according to roughness and V + GetBaseSurfaceColorAndF0(bsdfData, + /*out*/ outStandardlit.baseColor, + /*out*/ outStandardlit.fresnel0, + /*out*/specBRDFColor, + /*out*/singleFlakesComponent, + /*out*/coatFGD, + bsdfData.viewWS, + /*mixFlakes:*/ true); + outStandardlit.specularOcclusion = bsdfData.specularOcclusion; - outStandardlit.normalWS = bsdfData.normalWS; - outStandardlit.baseColor = bsdfData.diffuseColor; - outStandardlit.fresnel0 = bsdfData.specularColor; - outStandardlit.perceptualRoughness = bsdfData.perceptualRoughness; - outStandardlit.coatMask = 0; - outStandardlit.emissiveAndBaked = builtinData.bakeDiffuseLighting * bsdfData.specularColor * bsdfData.ambientOcclusion + builtinData.emissiveColor; + + GetRoughnessNormalCoatMaskForFitToStandardLit(bsdfData, coatFGD, /*out*/ outStandardlit.normalWS, /*out*/ scalarRoughness, /*out*/ outStandardlit.coatMask); + outStandardlit.perceptualRoughness = RoughnessToPerceptualRoughness(scalarRoughness); + + // diffuseFGD is one (from Lambert), but carpaint have a tint on diffuse, try to fit that here: + outStandardlit.emissiveAndBaked = builtinData.bakeDiffuseLighting * specBRDFColor * bsdfData.ambientOcclusion + builtinData.emissiveColor; outStandardlit.isUnlit = 0; } #endif From 260d08d5dc62de03e1fcfb2785c5638ca7a861ec Mon Sep 17 00:00:00 2001 From: slunity Date: Fri, 18 Jun 2021 12:08:51 -0400 Subject: [PATCH 12/12] Add debug code for a potential issue where some RT constant buffer variables are corrupted (eg _RayTracingFallbackHierarchy). Seems to happen under certain scene config (seems more repeatable with 0503d1f59437065f3b57f1c924037225c33e7bdb) --- .../RaytracingReflectionFilter.compute | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingReflectionFilter.compute b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingReflectionFilter.compute index b920cc11d20..da58bd4ae87 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingReflectionFilter.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingReflectionFilter.compute @@ -136,7 +136,24 @@ void ReflectionAdjustWeight(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 float4 lighting = LOAD_TEXTURE2D_X(_SsrLightingTextureRW, targetCoord); float weight = ComputeWeightValue(perceptualSmoothness); - weight = (_RayTracingFallbackHierarchy == RAYTRACINGFALLBACKHIERACHY_NON_RAYTRACED_REFLECTION_PROBES_AND_SKY) ? lighting.w * weight : weight; + bool nonRaytracedProbesFallback = (_RayTracingFallbackHierarchy == RAYTRACINGFALLBACKHIERACHY_NON_RAYTRACED_REFLECTION_PROBES_AND_SKY); + #ifdef DEMO_BUG_CB_FIXME + // Use the following code in fullres mode, under certain scene config, you will get flashing between cyan and black. + // ie the int _RayTracingFallbackHierarchy is sometimes corrupted with 0. + if (nonRaytracedProbesFallback) + { + weight = 1; + lighting.xyz = float3(0.0, 1.0, 1.0) * GetInverseCurrentExposureMultiplier() * _RayTracingFallbackHierarchy; + } + else + { + weight = 1; + lighting.xyz = float3(1.0, 0.0, 0.0) * GetInverseCurrentExposureMultiplier() * _RayTracingFallbackHierarchy; + } + #else + weight = nonRaytracedProbesFallback ? lighting.w * weight : weight; + #endif + // Output the result to the half resolution part of the texture _RaytracingReflectionTexture[COORD_TEXTURE2D_X(targetCoord)] = float4(lighting.xyz, weight); }