From fa1f5e86d1b70c634fa99db759669db2d7589b9e Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Tue, 18 Feb 2020 17:38:41 -0800 Subject: [PATCH 01/63] Adaptive sampling works --- .../ShaderLibrary/Sampling/Sampling.hlsl | 14 ++++++++ .../SubsurfaceScattering.compute | 32 ++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.core/ShaderLibrary/Sampling/Sampling.hlsl b/com.unity.render-pipelines.core/ShaderLibrary/Sampling/Sampling.hlsl index 6c68e750ff7..3215064dc45 100644 --- a/com.unity.render-pipelines.core/ShaderLibrary/Sampling/Sampling.hlsl +++ b/com.unity.render-pipelines.core/ShaderLibrary/Sampling/Sampling.hlsl @@ -290,4 +290,18 @@ void SampleCone(real2 u, real cosHalfAngle, rcpPdf = TWO_PI * (1 - cosHalfAngle); } +// https://zero-radiance.github.io/post/sampling-diffusion/ +real SampleBurleyDiffusionProfile(real u, real rcpShapeParam) +{ + u = 1 - u; // Convert cCDF to CDF s.t. (x(0) = 0) and (x(1) = Inf) + + real g = 1 + (4 * u) * (2 * u + sqrt(1 + (4 * u) * u)); + real n = pow(g, -1.0/3.0); // g^(-1/3) + real p = g * (n * n); // g^(+1/3) = g^1 * (g^(-1/3) * g^(-1/3)) + real x = 3 * log(0.25 * (1 + p + n) * rcp(u)); // (u != 0) + real r = x * rcpShapeParam; + + return r; +} + #endif // UNITY_SAMPLING_INCLUDED diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute index 7118884ad0e..d68d6ebf60a 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute @@ -31,6 +31,7 @@ #define TEXTURE_CACHE_BORDER 2 #define TEXTURE_CACHE_SIZE_1D (GROUP_SIZE_1D + 2 * TEXTURE_CACHE_BORDER) #define TEXTURE_CACHE_SIZE_2D (TEXTURE_CACHE_SIZE_1D * TEXTURE_CACHE_SIZE_1D) +#define ADAPTIVE_SAMPLING 1 // Check for support of typed UAV loads from FORMAT_R16G16B16A16_FLOAT. // TODO: query the format support more precisely. @@ -51,7 +52,6 @@ #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStencilUsage.cs.hlsl" - //-------------------------------------------------------------------------------------------------- // Inputs & outputs //-------------------------------------------------------------------------------------------------- @@ -165,7 +165,21 @@ void EvaluateSample(uint i, uint n, uint profileID, uint iR, uint iP, float2 cen inout float3 totalIrradiance, inout float3 totalWeight) { // The relative sample position is known at the compile time. +#if ADAPTIVE_SAMPLING + // Undo premultiplication... + const float log2e = 1.44269504088896340736f; + const float k = (-1.0f / 3.0f) * log2e; + float3 S = shapeParam / k; + // ShapeParam = 1 / ScatteringDistance. + // We importance sample the color channel with the widest scattering distance. + float rcpPar = rcp(max(FLT_EPS, Min3(S.x, S.y, S.z))); + float scale = rcp(n); + float offset = 0.5 * rcp(n); + // Precompute all of the above... + float r = SampleBurleyDiffusionProfile(i * scale + offset, rcpPar); +#else float r = _FilterKernels[profileID][i][iR]; +#endif float phi = SampleDiskFibonacci(i, n).y; // The angle 'psi' is loop-invariant. @@ -443,7 +457,23 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, uint iP = useNearFieldKernel ? 1 : 3; // rcp(pdf) uint n = useNearFieldKernel ? SSS_N_SAMPLES_NEAR_FIELD : SSS_N_SAMPLES_FAR_FIELD; + +#if ADAPTIVE_SAMPLING + // Undo premultiplication... + const float log2e = 1.44269504088896340736f; + const float k = (-1.0f / 3.0f) * log2e; + float3 S = shapeParam / k; + // ShapeParam = 1 / ScatteringDistance. + // We importance sample the color channel with the widest scattering distance. + float rcpPar = rcp(max(FLT_EPS, Min3(S.x, S.y, S.z))); + float scale = rcp(n); + float offset = 0.5 * rcp(n); + // Precompute all of the above... + float centerRadius = SampleBurleyDiffusionProfile(0 * scale + offset, rcpPar); +#else float centerRadius = _FilterKernels[profileID][0][iR]; +#endif + float centerRcpPdf = _FilterKernels[profileID][0][iP]; float3 centerWeight = DisneyProfilePolar(centerRadius, shapeParam) * centerRcpPdf; From d4aaf3d27c885df855c042ad2be2a3e6bc864dd3 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Wed, 19 Feb 2020 17:00:24 -0800 Subject: [PATCH 02/63] Compute the PDF --- .../ShaderLibrary/Sampling/Sampling.hlsl | 14 ---- .../DiffusionProfile/DiffusionProfile.hlsl | 69 ++++++++++++++----- .../SubsurfaceScattering.compute | 69 ++++++------------- 3 files changed, 73 insertions(+), 79 deletions(-) diff --git a/com.unity.render-pipelines.core/ShaderLibrary/Sampling/Sampling.hlsl b/com.unity.render-pipelines.core/ShaderLibrary/Sampling/Sampling.hlsl index 3215064dc45..6c68e750ff7 100644 --- a/com.unity.render-pipelines.core/ShaderLibrary/Sampling/Sampling.hlsl +++ b/com.unity.render-pipelines.core/ShaderLibrary/Sampling/Sampling.hlsl @@ -290,18 +290,4 @@ void SampleCone(real2 u, real cosHalfAngle, rcpPdf = TWO_PI * (1 - cosHalfAngle); } -// https://zero-radiance.github.io/post/sampling-diffusion/ -real SampleBurleyDiffusionProfile(real u, real rcpShapeParam) -{ - u = 1 - u; // Convert cCDF to CDF s.t. (x(0) = 0) and (x(1) = Inf) - - real g = 1 + (4 * u) * (2 * u + sqrt(1 + (4 * u) * u)); - real n = pow(g, -1.0/3.0); // g^(-1/3) - real p = g * (n * n); // g^(+1/3) = g^1 * (g^(-1/3) * g^(-1/3)) - real x = 3 * log(0.25 * (1 + p + n) * rcp(u)); // (u != 0) - real r = x * rcpShapeParam; - - return r; -} - #endif // UNITY_SAMPLING_INCLUDED diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfile.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfile.hlsl index c286ba8e1f0..2c909c56162 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfile.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfile.hlsl @@ -2,21 +2,6 @@ // SSS/Transmittance helper // ---------------------------------------------------------------------------- -// Computes the value of the integrand in polar coordinates: f(r, s) = r * R(r, s). -// f(r, s) = (Exp[-r * s] + Exp[-r * s / 3]) * (s / (8 * Pi)) -// We can drop the constant (s / (8 * Pi)) due to the subsequent weight renormalization. -float3 DisneyProfilePolar(float r, float3 S) -{ -#if 0 - float3 expOneThird = exp((-1.0 / 3.0) * r * S); -#else - // Help the compiler. S is premultiplied by ((-1.0 / 3.0) * LOG2_E) on the CPU. - float3 p = r * S; - float3 expOneThird = exp2(p); -#endif - return expOneThird + expOneThird * expOneThird * expOneThird; -} - // Computes the fraction of light passing through the object. // Evaluate Int{0, inf}{2 * Pi * r * R(sqrt(r^2 + d^2))}, where R is the diffusion profile. // Note: 'volumeAlbedo' should be premultiplied by 0.25. @@ -28,13 +13,61 @@ float3 ComputeTransmittanceDisney(float3 S, float3 volumeAlbedo, float thickness // thickness /= subsurfaceMask; #if 0 - float3 expOneThird = exp(((-1.0 / 3.0) * thickness) * S); + float3 exp_13 = exp(((-1.0 / 3.0) * thickness) * S); #else // Help the compiler. S is premultiplied by ((-1.0 / 3.0) * LOG2_E) on the CPU. float3 p = thickness * S; - float3 expOneThird = exp2(p); + float3 exp_13 = exp2(p); #endif // Premultiply & optimize: T = (1/4 * A) * (e^(-t * S) + 3 * e^(-1/3 * t * S)) - return volumeAlbedo * (expOneThird * expOneThird * expOneThird + 3 * expOneThird); + return volumeAlbedo * (exp_13 * (3 + exp_13 * exp_13)); +} + +// Performs sampling of the Normalized Burley diffusion profile in polar coordinates. +// The result must be multiplied by the albedo. +float3 EvalBurleyDiffusionProfile(float r, float3 S) +{ + float3 exp_13 = exp2(((LOG2_E * (-1.0/3.0)) * r) * S); // Exp[-S * r / 3] + float3 expSum = exp_13 * (1 + exp_13 + exp_13); // Exp[-S * r / 3] + Exp[-S * r] + +#if SSS_ELIMINATE_CONSTANTS + return expSum; +#else + return (S * rcp(8 * PI)) * expSum; // S / (8 * Pi) * (Exp[-S * r / 3] + Exp[-S * r]) +#endif +} + +// Performs sampling of a Normalized Burley diffusion profile in polar coordinates. +// 'u' is the random number: [0, 1). +// rcp(S) = 1 / ShapeParam = ScatteringDistance. +// 'r' is the sampled radial distance. +// rcp(Pdf) is the reciprocal of the corresponding PDF value. +void SampleBurleyDiffusionProfile(float u, float rcpS, out float r, out float rcpPdf) +{ + u = 1 - u; // Convert cCDF to CDF s.t. (r(0) = 0) and (r(1) = Inf) + + // assert(0 <= u && u < 1); + + float g = 1 + (4 * u) * (2 * u + sqrt(1 + (4 * u) * u)); + float n = exp2(log2(g) * (-1.0/3.0)); // g^(-1/3) + float p = (g * n) * n; // g^(+1/3) + float c = 1 + p + n; // 1 + g^(+1/3) + g^(-1/3) + float d = (3 / LOG2_E * 2) + (3 / LOG2_E) * log2(u); // 3 * Log[4 * u] + float x = (3 / LOG2_E) * log2(c) - d; // 3 * Log[c / (4 * u)] + + // x = S * r + // exp_13 = Exp[-x/3] = Exp[-1/3 * 3 * Log[c / (4 * u)]] + // exp_13 = Exp[-Log[c / (4 * u)]] = (4 * u) / c + // exp_1 = Exp[-x] = exp_13 * exp_13 * exp_13 + // expSum = exp_1 + exp_13 = exp_13 * (1 + exp_13 + exp_13) + // rcpExp = rcp(expSum) = c^3 / ((4 * u) * (c^2 + 16 * u^2)) + float rcpExp = ((c * c) * c) * rcp((4 * u) * ((c * c) + (4 * u) * (4 * u))); + + r = x * rcpS; +#if SSS_ELIMINATE_CONSTANTS + rcpPdf = rcpExp; +#else + rcpPdf = (8 * PI * rcpS) * rcpExp; // (8 * Pi) / S / (Exp[-S * r / 3] + Exp[-S * r]) +#endif } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute index d68d6ebf60a..e5d61901b85 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute @@ -15,13 +15,15 @@ // TODO: use sharp load hoisting on PS4. // Tweak parameters. -#define SSS_BILATERAL_FILTER 1 -#define SSS_USE_LDS_CACHE 1 -#define SSS_RANDOM_ROTATION 1 // Hides undersampling artifacts with high-frequency noise. TAA blurs the noise. -#define SSS_USE_TANGENT_PLANE 0 // Improves the accuracy of the approximation(0 -> 1st order). High cost. Does not work with back-facing normals. -#define SSS_CLAMP_ARTIFACT 0 // Reduces bleeding. Use with SSS_USE_TANGENT_PLANE. -#define SSS_DEBUG_LOD 0 -#define SSS_DEBUG_NORMAL_VS 0 +#define SSS_BILATERAL_FILTER 1 +#define SSS_USE_LDS_CACHE 1 +#define SSS_RANDOM_ROTATION 1 // Hides undersampling artifacts with high-frequency noise. TAA blurs the noise. +#define SSS_USE_TANGENT_PLANE 0 // Improves the accuracy of the approximation(0 -> 1st order). High cost. Does not work with back-facing normals. +#define SSS_CLAMP_ARTIFACT 0 // Reduces bleeding. Use with SSS_USE_TANGENT_PLANE. +#define SSS_DEBUG_LOD 0 +#define SSS_DEBUG_NORMAL_VS 0 +#define SSS_ELIMINATE_CONSTANTS 1 // Help the compiler remove redundant operations +#define SSS_SSS_ADAPTIVE_SAMPLING 1 // Do not modify these. #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl" @@ -31,7 +33,6 @@ #define TEXTURE_CACHE_BORDER 2 #define TEXTURE_CACHE_SIZE_1D (GROUP_SIZE_1D + 2 * TEXTURE_CACHE_BORDER) #define TEXTURE_CACHE_SIZE_2D (TEXTURE_CACHE_SIZE_1D * TEXTURE_CACHE_SIZE_1D) -#define ADAPTIVE_SAMPLING 1 // Check for support of typed UAV loads from FORMAT_R16G16B16A16_FLOAT. // TODO: query the format support more precisely. @@ -153,9 +154,9 @@ float3 ComputeBilateralWeight(float xy2, float z, float mmPerUnit, float3 S, flo #endif #if SSS_CLAMP_ARTIFACT - return saturate(DisneyProfilePolar(r, S) * area); + return saturate(EvalBurleyDiffusionProfile(r, S) * area); #else - return DisneyProfilePolar(r, S) * area; + return EvalBurleyDiffusionProfile(r, S) * area; #endif } @@ -164,21 +165,21 @@ void EvaluateSample(uint i, uint n, uint profileID, uint iR, uint iP, float2 cen float startAngle, float3 tangentX, float3 tangentY, float4x4 projMatrix, inout float3 totalIrradiance, inout float3 totalWeight) { - // The relative sample position is known at the compile time. -#if ADAPTIVE_SAMPLING + float r, rcpPdf; +#if SSS_SSS_ADAPTIVE_SAMPLING // Undo premultiplication... - const float log2e = 1.44269504088896340736f; - const float k = (-1.0f / 3.0f) * log2e; + float k = (-1.0f / 3.0f) * LOG2_E; float3 S = shapeParam / k; // ShapeParam = 1 / ScatteringDistance. // We importance sample the color channel with the widest scattering distance. - float rcpPar = rcp(max(FLT_EPS, Min3(S.x, S.y, S.z))); + float rcpS = rcp(max(FLT_EPS, Min3(S.x, S.y, S.z))); float scale = rcp(n); float offset = 0.5 * rcp(n); // Precompute all of the above... - float r = SampleBurleyDiffusionProfile(i * scale + offset, rcpPar); + SampleBurleyDiffusionProfile(i * scale + offset, rcpS, r, rcpPdf); #else - float r = _FilterKernels[profileID][i][iR]; + r = _FilterKernels[profileID][i][iR]; + rcpPdf = _FilterKernels[profileID][i][iP]; #endif float phi = SampleDiskFibonacci(i, n).y; @@ -217,8 +218,7 @@ void EvaluateSample(uint i, uint n, uint profileID, uint iR, uint iP, float2 cen // Apply bilateral weighting. float viewZ = textureSample.a; float relZ = viewZ - centerPosVS.z; - float rcpPdf = _FilterKernels[profileID][i][iP]; - float3 weight = ComputeBilateralWeight(xy2, relZ, mmPerUnit, shapeParam, rcpPdf); + float3 weight = ComputeBilateralWeight(xy2, relZ, mmPerUnit, S, rcpPdf); // Note: if the texture sample if off-screen, (z = 0) -> (viewZ = far) -> (weight ≈ 0). totalIrradiance += weight * irradiance; @@ -457,35 +457,10 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, uint iP = useNearFieldKernel ? 1 : 3; // rcp(pdf) uint n = useNearFieldKernel ? SSS_N_SAMPLES_NEAR_FIELD : SSS_N_SAMPLES_FAR_FIELD; - -#if ADAPTIVE_SAMPLING - // Undo premultiplication... - const float log2e = 1.44269504088896340736f; - const float k = (-1.0f / 3.0f) * log2e; - float3 S = shapeParam / k; - // ShapeParam = 1 / ScatteringDistance. - // We importance sample the color channel with the widest scattering distance. - float rcpPar = rcp(max(FLT_EPS, Min3(S.x, S.y, S.z))); - float scale = rcp(n); - float offset = 0.5 * rcp(n); - // Precompute all of the above... - float centerRadius = SampleBurleyDiffusionProfile(0 * scale + offset, rcpPar); -#else - float centerRadius = _FilterKernels[profileID][0][iR]; -#endif - - float centerRcpPdf = _FilterKernels[profileID][0][iP]; - float3 centerWeight = DisneyProfilePolar(centerRadius, shapeParam) * centerRcpPdf; - - // If the shape parameter is 0, the weight is be 0. - // This is desirable for all but the central sample. - // We make sure that if the shape parameter is 0, the weight is non-zero. - // Weight normalization will ensure that the result is correct. - centerWeight = max(centerWeight, FLT_EPS); - // Accumulate filtered irradiance and bilateral weights (for renormalization). - float3 totalIrradiance = centerWeight * centerIrradiance; - float3 totalWeight = centerWeight; + float3 centerWeight = 1; // (value / pdf) = albedo + float3 totalIrradiance = centerIrradiance; + float3 totalWeight = 1; uint i; // Declare once to avoid the warning from the Unity shader compiler. From a94f3763ef8c3907def44b75b3aacb117a08cc3e Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Wed, 19 Feb 2020 17:06:45 -0800 Subject: [PATCH 03/63] URL --- .../DiffusionProfile/DiffusionProfile.hlsl | 12 +++--- .../DiffusionProfileSettings.cs | 18 +++++++++ .../SubsurfaceScattering.compute | 39 ++++++++++--------- 3 files changed, 44 insertions(+), 25 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfile.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfile.hlsl index 2c909c56162..0a1fe35f8d2 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfile.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfile.hlsl @@ -40,14 +40,12 @@ float3 EvalBurleyDiffusionProfile(float r, float3 S) // Performs sampling of a Normalized Burley diffusion profile in polar coordinates. // 'u' is the random number: [0, 1). -// rcp(S) = 1 / ShapeParam = ScatteringDistance. -// 'r' is the sampled radial distance. +// rcp(s) = 1 / ShapeParam = ScatteringDistance. +// 'r' is the sampled radial distance, s.t. (u = 0 -> r = 0) and (u = 1 -> r = Inf). // rcp(Pdf) is the reciprocal of the corresponding PDF value. void SampleBurleyDiffusionProfile(float u, float rcpS, out float r, out float rcpPdf) { - u = 1 - u; // Convert cCDF to CDF s.t. (r(0) = 0) and (r(1) = Inf) - - // assert(0 <= u && u < 1); + u = 1 - u; // Convert CDF to CCDF float g = 1 + (4 * u) * (2 * u + sqrt(1 + (4 * u) * u)); float n = exp2(log2(g) * (-1.0/3.0)); // g^(-1/3) @@ -56,7 +54,7 @@ void SampleBurleyDiffusionProfile(float u, float rcpS, out float r, out float rc float d = (3 / LOG2_E * 2) + (3 / LOG2_E) * log2(u); // 3 * Log[4 * u] float x = (3 / LOG2_E) * log2(c) - d; // 3 * Log[c / (4 * u)] - // x = S * r + // x = s * r // exp_13 = Exp[-x/3] = Exp[-1/3 * 3 * Log[c / (4 * u)]] // exp_13 = Exp[-Log[c / (4 * u)]] = (4 * u) / c // exp_1 = Exp[-x] = exp_13 * exp_13 * exp_13 @@ -68,6 +66,6 @@ void SampleBurleyDiffusionProfile(float u, float rcpS, out float r, out float rc #if SSS_ELIMINATE_CONSTANTS rcpPdf = rcpExp; #else - rcpPdf = (8 * PI * rcpS) * rcpExp; // (8 * Pi) / S / (Exp[-S * r / 3] + Exp[-S * r]) + rcpPdf = (8 * PI * rcpS) * rcpExp; // (8 * Pi) / s / (Exp[-s * r / 3] + Exp[-s * r]) #endif } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs index 11257072709..8eb70684887 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs @@ -177,6 +177,24 @@ static float DisneyProfileCdfInverse(float p, float s) return r; } + // https://zero-radiance.github.io/post/sampling-diffusion/ + // Performs sampling of a Normalized Burley diffusion profile in polar coordinates. + // 'u' is the random number: [0, 1). + // rcp(s) = 1 / ShapeParam = ScatteringDistance. + // Returns the sampled radial distance, s.t. (u = 0 -> r = 0) and (u = 1 -> r = Inf). + static float SampleBurleyDiffusionProfile(float u, float rcpS) + { + u = 1 - u; // Convert CDF to CCDF + + float g = 1 + (4 * u) * (2 * u + Mathf.Sqrt(1 + (4 * u) * u)); + float n = Mathf.Pow(g, -1.0f/3.0f); // g^(-1/3) + float p = (g * n) * n; // g^(+1/3) + float c = 1 + p + n; // 1 + g^(+1/3) + g^(-1/3) + float x = 3 * Mathf.Log(c / (4 * u)); + + return x * rcpS; + } + public bool Equals(DiffusionProfile other) { if (other == null) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute index e5d61901b85..2a3cf6a0294 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute @@ -135,6 +135,8 @@ float3 ComputeBilateralWeight(float xy2, float z, float mmPerUnit, float3 S, flo z = 0; #endif + // Note: we perform all computation in millimeters. + // So we must convert from world units (using 'mmPerUnit') to millimeters. #if SSS_USE_TANGENT_PLANE // Both 'xy2' and 'z' require conversion to millimeters. float r = sqrt(xy2 + z * z) * mmPerUnit; @@ -445,7 +447,7 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, #endif // Use more samples for SS regions larger than 5x5 pixels (rotated by 45 degrees). - bool useNearFieldKernel = SSS_ENABLE_NEAR_FIELD && maxDistInPixels > SSS_LOD_THRESHOLD; + bool useNearFieldKernel = SSS_ENABLE_NEAR_FIELD && maxDistInPixels > SSS_PIXELS_PER_SAMPLE; #if SSS_DEBUG_LOD StoreResult(pixelCoord, useNearFieldKernel ? float3(1, 0, 0) : float3(0.5, 0.5, 0)); @@ -455,7 +457,8 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, // Compute the indices used to access the individual components of the float4 of the kernel. uint iR = useNearFieldKernel ? 0 : 2; // radius uint iP = useNearFieldKernel ? 1 : 3; // rcp(pdf) - uint n = useNearFieldKernel ? SSS_N_SAMPLES_NEAR_FIELD : SSS_N_SAMPLES_FAR_FIELD; + // uint n = useNearFieldKernel ? SSS_N_SAMPLES_NEAR_FIELD : SSS_N_SAMPLES_FAR_FIELD; + uint n = 144; // Accumulate filtered irradiance and bilateral weights (for renormalization). float3 centerWeight = 1; // (value / pdf) = albedo @@ -465,7 +468,7 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, uint i; // Declare once to avoid the warning from the Unity shader compiler. UNITY_UNROLL - for (i = 1; i < SSS_N_SAMPLES_FAR_FIELD; i++) + for (i = 1; i < n; i++) { // Integrate over the image or tangent plane in the view space. EvaluateSample(i, n, profileID, iR, iP, pixelCoord + 0.5, cacheOffset, @@ -474,21 +477,21 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, totalIrradiance, totalWeight); } - UNITY_BRANCH if (!useNearFieldKernel) - { - StoreResult(pixelCoord, albedo * totalIrradiance / totalWeight); - return; - } - - UNITY_UNROLL - for (i = SSS_N_SAMPLES_FAR_FIELD; i < SSS_N_SAMPLES_NEAR_FIELD; i++) - { - // Integrate over the image or tangent plane in the view space. - EvaluateSample(i, n, profileID, iR, iP, pixelCoord + 0.5, cacheOffset, - shapeParam, centerPosVS, mmPerUnit, pixelsPerMm, - startAngle, tangentX, tangentY, projMatrix, - totalIrradiance, totalWeight); - } + // UNITY_BRANCH if (!useNearFieldKernel) + // { + // StoreResult(pixelCoord, albedo * totalIrradiance / totalWeight); + // return; + // } + + // UNITY_UNROLL + // for (i = SSS_N_SAMPLES_FAR_FIELD; i < SSS_N_SAMPLES_NEAR_FIELD; i++) + // { + // // Integrate over the image or tangent plane in the view space. + // EvaluateSample(i, n, profileID, iR, iP, pixelCoord + 0.5, cacheOffset, + // shapeParam, centerPosVS, mmPerUnit, pixelsPerMm, + // startAngle, tangentX, tangentY, projMatrix, + // totalIrradiance, totalWeight); + // } StoreResult(pixelCoord, albedo * totalIrradiance / totalWeight); } From 30e21ad23c56005e0f4412271614c9fcd5ca057a Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Thu, 20 Feb 2020 15:03:57 -0800 Subject: [PATCH 04/63] Fix stuff up (except for profile preview) --- .../DiffusionProfileSettingsEditor.cs | 4 +- .../Runtime/Lighting/SurfaceShading.hlsl | 5 +- .../DiffusionProfile/DiffusionProfile.hlsl | 21 +-- .../DiffusionProfileSettings.cs | 122 +++++------------- .../DiffusionProfileSettings.cs.hlsl | 2 +- .../ShaderVariablesSubsurfaceScattering.cs | 6 +- ...haderVariablesSubsurfaceScattering.cs.hlsl | 4 +- .../SubsurfaceScattering.compute | 74 +++++------ .../SubsurfaceScattering.hlsl | 6 +- .../SubsurfaceScatteringManager.cs | 52 +++----- .../RenderPipeline/HDStringConstants.cs | 9 +- .../Shaders/RayTracingSubSurface.raytrace | 6 +- 12 files changed, 100 insertions(+), 211 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DiffusionProfileSettingsEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DiffusionProfileSettingsEditor.cs index 13a74a6bd0c..3451cd5ddbf 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DiffusionProfileSettingsEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DiffusionProfileSettingsEditor.cs @@ -101,7 +101,7 @@ public override void OnInspectorGUI() EditorGUILayout.PropertyField(profile.scatteringDistance, s_Styles.profileScatteringDistance); using (new EditorGUI.DisabledScope(true)) - EditorGUILayout.FloatField(s_Styles.profileMaxRadius, profile.objReference.maxRadius); + EditorGUILayout.FloatField(s_Styles.profileMaxRadius, profile.objReference.filterRadius); EditorGUILayout.Slider(profile.ior, 1.0f, 2.0f, s_Styles.profileIor); EditorGUILayout.PropertyField(profile.worldScale, s_Styles.profileWorldScale); @@ -150,7 +150,7 @@ public override void OnInspectorGUI() void RenderPreview(Profile profile) { var obj = profile.objReference; - float r = obj.maxRadius; + float r = obj.filterRadius; var S = obj.shapeParam; var T = (Vector4)profile.transmissionTint.colorValue; var R = profile.thicknessRemap.vector2Value; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/SurfaceShading.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Lighting/SurfaceShading.hlsl index f59b27c5cee..e32773fbf5b 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/SurfaceShading.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/SurfaceShading.hlsl @@ -132,13 +132,14 @@ float3 EvaluateTransmittance_Punctual(LightLoopContext lightLoopContext, // Note: based on the artist's input, dependence on the NdotL has been disabled. float distFrontFaceToLight = distances.x; float thicknessInUnits = (distFrontFaceToLight - distBackFaceToLight) /* * -NdotL */; - float thicknessInMeters = thicknessInUnits * _WorldScales[bsdfData.diffusionProfileIndex].x; + float metersPerUnit = _WorldScalesAndFilterRadii[bsdfData.diffusionProfileIndex].x; + float thicknessInMeters = thicknessInUnits * metersPerUnit; float thicknessInMillimeters = thicknessInMeters * MILLIMETERS_PER_METER; // We need to make sure it's not less than the baked thickness to minimize light leaking. float thicknessDelta = max(0, thicknessInMillimeters - bsdfData.thickness); - float3 S = _ShapeParams[bsdfData.diffusionProfileIndex].rgb; + float3 S = _ShapeParamsAndMaxScatterDists[bsdfData.diffusionProfileIndex].rgb; #if 0 float3 expOneThird = exp(((-1.0 / 3.0) * thicknessDelta) * S); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfile.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfile.hlsl index 0a1fe35f8d2..d3dcc574ef8 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfile.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfile.hlsl @@ -12,16 +12,10 @@ float3 ComputeTransmittanceDisney(float3 S, float3 volumeAlbedo, float thickness // In theory, we should modify the thickness by the inverse of the mask scale of the profile. // thickness /= subsurfaceMask; -#if 0 - float3 exp_13 = exp(((-1.0 / 3.0) * thickness) * S); -#else - // Help the compiler. S is premultiplied by ((-1.0 / 3.0) * LOG2_E) on the CPU. - float3 p = thickness * S; - float3 exp_13 = exp2(p); -#endif + float3 exp_13 = exp2(((LOG2_E * (-1.0/3.0)) * thickness) * S); // Exp[-S * t / 3] - // Premultiply & optimize: T = (1/4 * A) * (e^(-t * S) + 3 * e^(-1/3 * t * S)) - return volumeAlbedo * (exp_13 * (3 + exp_13 * exp_13)); + // Premultiply & optimize: T = (1/4 * A) * (e^(-S * t) + 3 * e^(-S * t / 3)) + return volumeAlbedo * (exp_13 * (exp_13 * exp_13 + 3)); } // Performs sampling of the Normalized Burley diffusion profile in polar coordinates. @@ -31,13 +25,10 @@ float3 EvalBurleyDiffusionProfile(float r, float3 S) float3 exp_13 = exp2(((LOG2_E * (-1.0/3.0)) * r) * S); // Exp[-S * r / 3] float3 expSum = exp_13 * (1 + exp_13 + exp_13); // Exp[-S * r / 3] + Exp[-S * r] -#if SSS_ELIMINATE_CONSTANTS - return expSum; -#else return (S * rcp(8 * PI)) * expSum; // S / (8 * Pi) * (Exp[-S * r / 3] + Exp[-S * r]) -#endif } +// https://zero-radiance.github.io/post/sampling-diffusion/ // Performs sampling of a Normalized Burley diffusion profile in polar coordinates. // 'u' is the random number: [0, 1). // rcp(s) = 1 / ShapeParam = ScatteringDistance. @@ -63,9 +54,5 @@ void SampleBurleyDiffusionProfile(float u, float rcpS, out float r, out float rc float rcpExp = ((c * c) * c) * rcp((4 * u) * ((c * c) + (4 * u) * (4 * u))); r = x * rcpS; -#if SSS_ELIMINATE_CONSTANTS - rcpPdf = rcpExp; -#else rcpPdf = (8 * PI * rcpS) * rcpExp; // (8 * Pi) / s / (Exp[-s * r / 3] + Exp[-s * r]) -#endif } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs index 8eb70684887..1c5416f9231 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs @@ -9,7 +9,7 @@ class DiffusionProfileConstants public const int DIFFUSION_PROFILE_NEUTRAL_ID = 0; // Does not result in blurring public const int SSS_N_SAMPLES_NEAR_FIELD = 55; // Used for extreme close ups; must be a Fibonacci number public const int SSS_N_SAMPLES_FAR_FIELD = 21; // Used at a regular distance; must be a Fibonacci number - public const int SSS_LOD_THRESHOLD = 4; // The LoD threshold of the near-field kernel (in pixels) + public const int SSS_PIXELS_PER_SAMPLE = 4; } [Serializable] @@ -37,12 +37,9 @@ public enum TransmissionMode : uint public float worldScale; // Size of the world unit in meters public float ior; // 1.4 for skin (mean ~0.028) - public Vector3 shapeParam { get; private set; } // RGB = shape parameter: S = 1 / D - public float maxRadius { get; private set; } // In millimeters - public Vector2[] filterKernelNearField { get; private set; } // X = radius, Y = reciprocal of the PDF - public Vector2[] filterKernelFarField { get; private set; } // X = radius, Y = reciprocal of the PDF - public Vector4 halfRcpWeightedVariances { get; private set; } - public Vector4[] filterKernelBasic { get; private set; } + public Vector3 shapeParam { get; private set; } // RGB = shape parameter: S = 1 / D + public float filterRadius { get; private set; } // In millimeters + public float maxScatteringDistance { get; private set; } // No meaningful units // Unique hash used in shaders to identify the index in the diffusion profile array public uint hash = 0; @@ -72,21 +69,15 @@ internal void Validate() // Ref: Approximate Reflectance Profiles for Efficient Subsurface Scattering by Pixar. void UpdateKernel() { - if (filterKernelNearField == null || filterKernelNearField.Length != DiffusionProfileConstants.SSS_N_SAMPLES_NEAR_FIELD) - filterKernelNearField = new Vector2[DiffusionProfileConstants.SSS_N_SAMPLES_NEAR_FIELD]; + Vector3 sd = (Vector3)(Vector4)scatteringDistance; - if (filterKernelFarField == null || filterKernelFarField.Length != DiffusionProfileConstants.SSS_N_SAMPLES_FAR_FIELD) - filterKernelFarField = new Vector2[DiffusionProfileConstants.SSS_N_SAMPLES_FAR_FIELD]; + // Rather inconvenient to support (S = Inf). + shapeParam = new Vector3(Mathf.Min(16777215, 1.0f / sd.x), + Mathf.Min(16777215, 1.0f / sd.y), + Mathf.Min(16777215, 1.0f / sd.z)); - shapeParam = new Vector3(1.0f / scatteringDistance.r, - 1.0f / scatteringDistance.g, - 1.0f / scatteringDistance.b); - - // Limit the value so it does not goes to infinity (preventing NaNs to be generated by ComputeTransmittanceDisney()) - shapeParam = Vector3.Min(shapeParam, Single.MaxValue * Vector3.one); - - // We importance sample the color channel with the widest scattering distance. - float s = Mathf.Min(shapeParam.x, shapeParam.y, shapeParam.z); + int n = DiffusionProfileConstants.SSS_N_SAMPLES_NEAR_FIELD; // TODO + float p = ((n - 1) + 0.5f) * (1.0f / n); // Last sample // Importance sample the normalized diffuse reflectance profile for the computed value of 's'. // ------------------------------------------------------------------------------------ @@ -94,32 +85,10 @@ void UpdateKernel() // PDF[r, phi, s] = r * R[r, phi, s] // CDF[r, s] = 1 - 1/4 * Exp[-r * s] - 3/4 * Exp[-r * s / 3] // ------------------------------------------------------------------------------------ + // We importance sample the color channel with the widest scattering distance. + maxScatteringDistance = Mathf.Max(sd.x, sd.y, sd.z); - // Importance sample the near field kernel. - for (int i = 0, n = DiffusionProfileConstants.SSS_N_SAMPLES_NEAR_FIELD; i < n; i++) - { - float p = (i + 0.5f) * (1.0f / n); - float r = DisneyProfileCdfInverse(p, s); - - // N.b.: computation of normalized weights, and multiplication by the surface albedo - // of the actual geometry is performed at runtime (in the shader). - filterKernelNearField[i].x = r; - filterKernelNearField[i].y = 1f / DisneyProfilePdf(r, s); - } - - // Importance sample the far field kernel. - for (int i = 0, n = DiffusionProfileConstants.SSS_N_SAMPLES_FAR_FIELD; i < n; i++) - { - float p = (i + 0.5f) * (1.0f / n); - float r = DisneyProfileCdfInverse(p, s); - - // N.b.: computation of normalized weights, and multiplication by the surface albedo - // of the actual geometry is performed at runtime (in the shader). - filterKernelFarField[i].x = r; - filterKernelFarField[i].y = 1f / DisneyProfilePdf(r, s); - } - - maxRadius = filterKernelFarField[DiffusionProfileConstants.SSS_N_SAMPLES_FAR_FIELD - 1].x; + filterRadius = SampleBurleyDiffusionProfile(p, maxScatteringDistance); } static float DisneyProfile(float r, float s) @@ -206,13 +175,7 @@ public bool Equals(DiffusionProfile other) transmissionMode == other.transmissionMode && thicknessRemap == other.thicknessRemap && worldScale == other.worldScale && - ior == other.ior && - shapeParam == other.shapeParam && - maxRadius == other.maxRadius && - filterKernelNearField == other.filterKernelNearField && - filterKernelFarField == other.filterKernelFarField && - halfRcpWeightedVariances == other.halfRcpWeightedVariances && - filterKernelBasic == other.filterKernelBasic; + ior == other.ior; } } @@ -222,12 +185,11 @@ internal partial class DiffusionProfileSettings : ScriptableObject [SerializeField] internal DiffusionProfile profile; - [NonSerialized] internal Vector4 thicknessRemaps; // Remap: 0 = start, 1 = end - start - [NonSerialized] internal Vector4 worldScales; // X = meters per world unit; Y = world units per meter - [NonSerialized] internal Vector4 shapeParams; // RGB = S = 1 / D, A = filter radius - [NonSerialized] internal Vector4 transmissionTintsAndFresnel0; // RGB = color, A = fresnel0 - [NonSerialized] internal Vector4 disabledTransmissionTintsAndFresnel0; // RGB = black, A = fresnel0 - For debug to remove the transmission - [NonSerialized] internal Vector4[] filterKernels; // XY = near field, ZW = far field; 0 = radius, 1 = reciprocal of the PDF + [NonSerialized] internal Vector4 thicknessRemap; // Remap: 0 = start, 1 = end - start + [NonSerialized] internal Vector4 worldScalesAndFilterRadii; // X = meters per world unit, Y = filter radius (in mm), Z = 1/X, W = 1/Y + [NonSerialized] internal Vector4 shapeParamAndMaxScatterDist; // RGB = S = 1 / D, A = d = RgbMax(D) + [NonSerialized] internal Vector4 transmissionTintAndFresnel0; // RGB = color, A = fresnel0 + [NonSerialized] internal Vector4 disabledTransmissionTintAndFresnel0; // RGB = black, A = fresnel0 - For debug to remove the transmission [NonSerialized] internal int updateCount; void OnEnable() @@ -254,35 +216,17 @@ void OnEnable() internal void UpdateCache() { - if (filterKernels == null) - filterKernels = new Vector4[DiffusionProfileConstants.SSS_N_SAMPLES_NEAR_FIELD]; - - thicknessRemaps = new Vector4(profile.thicknessRemap.x, profile.thicknessRemap.y - profile.thicknessRemap.x, 0f, 0f); - worldScales = new Vector4(profile.worldScale, 1.0f / profile.worldScale, 0f, 0f); - - // Premultiply S by ((-1.0 / 3.0) * LOG2_E) on the CPU. - const float log2e = 1.44269504088896340736f; - const float k = (-1.0f / 3.0f) * log2e; + thicknessRemap = new Vector4(profile.thicknessRemap.x, profile.thicknessRemap.y - profile.thicknessRemap.x, 0, 0); + worldScalesAndFilterRadii = new Vector4(profile.worldScale, profile.filterRadius, 1.0f / profile.worldScale, 1.0f / profile.filterRadius); - shapeParams = profile.shapeParam * k; - shapeParams.w = profile.maxRadius; + shapeParamAndMaxScatterDist = profile.shapeParam; + shapeParamAndMaxScatterDist.w = profile.maxScatteringDistance; // Convert ior to fresnel0 float fresnel0 = (profile.ior - 1.0f) / (profile.ior + 1.0f); fresnel0 *= fresnel0; // square - transmissionTintsAndFresnel0 = new Vector4(profile.transmissionTint.r * 0.25f, profile.transmissionTint.g * 0.25f, profile.transmissionTint.b * 0.25f, fresnel0); // Premultiplied - disabledTransmissionTintsAndFresnel0 = new Vector4(0.0f, 0.0f, 0.0f, fresnel0); + transmissionTintAndFresnel0 = new Vector4(profile.transmissionTint.r * 0.25f, profile.transmissionTint.g * 0.25f, profile.transmissionTint.b * 0.25f, fresnel0); // Premultiplied + disabledTransmissionTintAndFresnel0 = new Vector4(0.0f, 0.0f, 0.0f, fresnel0); - for (int n = 0; n < DiffusionProfileConstants.SSS_N_SAMPLES_NEAR_FIELD; n++) - { - filterKernels[n].x = profile.filterKernelNearField[n].x; - filterKernels[n].y = profile.filterKernelNearField[n].y; - - if (n < DiffusionProfileConstants.SSS_N_SAMPLES_FAR_FIELD) - { - filterKernels[n].z = profile.filterKernelFarField[n].x; - filterKernels[n].w = profile.filterKernelFarField[n].y; - } - } updateCount++; } @@ -296,17 +240,9 @@ internal bool HasChanged(int update) /// public void SetDefaultParams() { - worldScales = Vector4.one; - shapeParams = Vector4.zero; - transmissionTintsAndFresnel0.w = 0.04f; // Match DEFAULT_SPECULAR_VALUE defined in Lit.hlsl - - for (int n = 0; n < DiffusionProfileConstants.SSS_N_SAMPLES_NEAR_FIELD; n++) - { - filterKernels[n].x = 0f; - filterKernels[n].y = 1f; - filterKernels[n].z = 0f; - filterKernels[n].w = 1f; - } + worldScalesAndFilterRadii = new Vector4(1, 1, 0, 0); + shapeParamAndMaxScatterDist = new Vector4(Mathf.Infinity, Mathf.Infinity, Mathf.Infinity, 0); + transmissionTintAndFresnel0.w = 0.04f; // Match DEFAULT_SPECULAR_VALUE defined in Lit.hlsl } } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs.hlsl index 0c6925079ff..2b411fed5d0 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs.hlsl @@ -11,7 +11,7 @@ #define DIFFUSION_PROFILE_NEUTRAL_ID (0) #define SSS_N_SAMPLES_NEAR_FIELD (55) #define SSS_N_SAMPLES_FAR_FIELD (21) -#define SSS_LOD_THRESHOLD (4) +#define SSS_PIXELS_PER_SAMPLE (4) #endif diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs index a94d61ea808..3584ab0a6bf 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs @@ -5,13 +5,13 @@ unsafe struct ShaderVariablesSubsurfaceScattering { // Use float4 to avoid any packing issue between compute and pixel shaders [HLSLArray(DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT, typeof(Vector4))] - public fixed float _ThicknessRemaps[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT * 4]; // R: start, G = end - start, BA unused + public fixed float _ThicknessRemaps[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT * 4]; // Remap: X = start, Y = end - start [HLSLArray(DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT, typeof(Vector4))] - public fixed float _ShapeParams[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT * 4]; // RGB = S = 1 / D, A = filter radius + public fixed float _ShapeParamsAndMaxScatterDists[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT * 4]; // RGB = S = 1 / D, A = d = RgbMax(D) [HLSLArray(DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT, typeof(Vector4))] public fixed float _TransmissionTintsAndFresnel0[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT * 4]; // RGB = 1/4 * color, A = fresnel0 [HLSLArray(DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT, typeof(Vector4))] - public fixed float _WorldScales[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT * 4]; // X = meters per world unit; Y = world units per meter + public fixed float _WorldScalesAndFilterRadii[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT * 4]; // X = meters per world unit, Y = filter radius (in mm), Z = 1/X, W = 1/Y [HLSLArray(DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT, typeof(float))] public fixed uint _DiffusionProfileHashTable[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; // TODO: constant diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs.hlsl index 572d6d58162..78f66ef71ae 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs.hlsl @@ -7,9 +7,9 @@ // Generated from UnityEngine.Rendering.HighDefinition.ShaderVariablesSubsurfaceScattering // PackingRules = Exact float4 _ThicknessRemaps[16]; - float4 _ShapeParams[16]; + float4 _ShapeParamsAndMaxScatterDists[16]; float4 _TransmissionTintsAndFresnel0[16]; - float4 _WorldScales[16]; + float4 _WorldScalesAndFilterRadii[16]; float _DiffusionProfileHashTable[16]; uint _EnableSubsurfaceScattering; float _TexturingModeFlags; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute index 2a3cf6a0294..527c2050a76 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute @@ -22,7 +22,6 @@ #define SSS_CLAMP_ARTIFACT 0 // Reduces bleeding. Use with SSS_USE_TANGENT_PLANE. #define SSS_DEBUG_LOD 0 #define SSS_DEBUG_NORMAL_VS 0 -#define SSS_ELIMINATE_CONSTANTS 1 // Help the compiler remove redundant operations #define SSS_SSS_ADAPTIVE_SAMPLING 1 // Do not modify these. @@ -162,26 +161,20 @@ float3 ComputeBilateralWeight(float xy2, float z, float mmPerUnit, float3 S, flo #endif } -void EvaluateSample(uint i, uint n, uint profileID, uint iR, uint iP, float2 centerCoord, int2 cacheOffset, - float3 shapeParam, float3 centerPosVS, float mmPerUnit, float2 pixelsPerMm, +void EvaluateSample(uint i, uint n, uint profileIndex, uint iR, uint iP, float2 centerCoord, int2 cacheOffset, + float3 S, float d, float3 centerPosVS, float mmPerUnit, float2 pixelsPerMm, float startAngle, float3 tangentX, float3 tangentY, float4x4 projMatrix, inout float3 totalIrradiance, inout float3 totalWeight) { + const float scale = rcp(n); + const float offset = 0.5 * rcp(n); + float r, rcpPdf; #if SSS_SSS_ADAPTIVE_SAMPLING - // Undo premultiplication... - float k = (-1.0f / 3.0f) * LOG2_E; - float3 S = shapeParam / k; - // ShapeParam = 1 / ScatteringDistance. - // We importance sample the color channel with the widest scattering distance. - float rcpS = rcp(max(FLT_EPS, Min3(S.x, S.y, S.z))); - float scale = rcp(n); - float offset = 0.5 * rcp(n); - // Precompute all of the above... - SampleBurleyDiffusionProfile(i * scale + offset, rcpS, r, rcpPdf); + SampleBurleyDiffusionProfile(i * scale + offset, d, r, rcpPdf); #else - r = _FilterKernels[profileID][i][iR]; - rcpPdf = _FilterKernels[profileID][i][iP]; + r = _FilterKernels[profileIndex][i][iR]; + rcpPdf = _FilterKernels[profileIndex][i][iP]; #endif float phi = SampleDiskFibonacci(i, n).y; @@ -368,10 +361,12 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, SSSData sssData; DECODE_FROM_SSSBUFFER(posInput.positionSS, sssData); - int profileID = sssData.diffusionProfileIndex; - float distScale = sssData.subsurfaceMask; - float3 shapeParam = _ShapeParams[profileID].rgb; - float maxDistance = _ShapeParams[profileID].a; + int profileIndex = sssData.diffusionProfileIndex; + float distScale = sssData.subsurfaceMask; + float3 S = _ShapeParamsAndMaxScatterDists[profileIndex].rgb; + float d = _ShapeParamsAndMaxScatterDists[profileIndex].a; + float metersPerUnit = _WorldScalesAndFilterRadii[profileIndex].x; + float filterRadius = _WorldScalesAndFilterRadii[profileIndex].y; // In millimeters // Reconstruct the view-space position corresponding to the central sample. float2 centerPosNDC = posInput.positionNDC; @@ -380,7 +375,7 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, float3 cornerPosVS = ComputeViewSpacePosition(cornerPosNDC, centerDepth, UNITY_MATRIX_I_P); // Rescaling the filter is equivalent to inversely scaling the world. - float mmPerUnit = MILLIMETERS_PER_METER * (_WorldScales[profileID].x / distScale); + float mmPerUnit = MILLIMETERS_PER_METER * (metersPerUnit * rcp(distScale)); float unitsPerMm = rcp(mmPerUnit); // Compute the view-space dimensions of the pixel as a quad projected onto geometry. @@ -394,9 +389,9 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, // whether we integrate over the tangent plane or not, since we // don't want the orientation of the tangent plane to create // divergence of execution across the warp. - float maxDistInPixels = maxDistance * max(pixelsPerMm.x, pixelsPerMm.y); + float maxDistInPixels = filterRadius * max(pixelsPerMm.x, pixelsPerMm.y); - uint texturingMode = GetSubsurfaceScatteringTexturingMode(profileID); + uint texturingMode = GetSubsurfaceScatteringTexturingMode(profileIndex); float3 albedo = ApplySubsurfaceScatteringTexturingMode(texturingMode, sssData.diffuseColor); UNITY_BRANCH if (distScale == 0 || maxDistInPixels < 1) @@ -457,13 +452,18 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, // Compute the indices used to access the individual components of the float4 of the kernel. uint iR = useNearFieldKernel ? 0 : 2; // radius uint iP = useNearFieldKernel ? 1 : 3; // rcp(pdf) - // uint n = useNearFieldKernel ? SSS_N_SAMPLES_NEAR_FIELD : SSS_N_SAMPLES_FAR_FIELD; - uint n = 144; + uint n = SSS_N_SAMPLES_NEAR_FIELD; + + const float scale = rcp(n); + const float offset = 0.5 * rcp(n); + + float r, rcpPdf; + SampleBurleyDiffusionProfile(0 * scale + offset, d, r, rcpPdf); // Accumulate filtered irradiance and bilateral weights (for renormalization). - float3 centerWeight = 1; // (value / pdf) = albedo - float3 totalIrradiance = centerIrradiance; - float3 totalWeight = 1; + float3 centerWeight = EvalBurleyDiffusionProfile(r, S) * rcpPdf; // Defer (* albedo) + float3 totalIrradiance = centerWeight * centerIrradiance; + float3 totalWeight = centerWeight; uint i; // Declare once to avoid the warning from the Unity shader compiler. @@ -471,27 +471,11 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, for (i = 1; i < n; i++) { // Integrate over the image or tangent plane in the view space. - EvaluateSample(i, n, profileID, iR, iP, pixelCoord + 0.5, cacheOffset, - shapeParam, centerPosVS, mmPerUnit, pixelsPerMm, + EvaluateSample(i, n, profileIndex, iR, iP, pixelCoord + 0.5, cacheOffset, + S, d, centerPosVS, mmPerUnit, pixelsPerMm, startAngle, tangentX, tangentY, projMatrix, totalIrradiance, totalWeight); } - // UNITY_BRANCH if (!useNearFieldKernel) - // { - // StoreResult(pixelCoord, albedo * totalIrradiance / totalWeight); - // return; - // } - - // UNITY_UNROLL - // for (i = SSS_N_SAMPLES_FAR_FIELD; i < SSS_N_SAMPLES_NEAR_FIELD; i++) - // { - // // Integrate over the image or tangent plane in the view space. - // EvaluateSample(i, n, profileID, iR, iP, pixelCoord + 0.5, cacheOffset, - // shapeParam, centerPosVS, mmPerUnit, pixelsPerMm, - // startAngle, tangentX, tangentY, projMatrix, - // totalIrradiance, totalWeight); - // } - StoreResult(pixelCoord, albedo * totalIrradiance / totalWeight); } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.hlsl index 86c3f476025..36357878d96 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.hlsl @@ -211,7 +211,7 @@ void FillMaterialTransmission(uint diffusionProfileIndex, float thickness, inout // Compute transmittance using baked thickness here. It may be overridden for direct lighting // in the auto-thickness mode (but is always used for indirect lighting). - bsdfData.transmittance = ComputeTransmittanceDisney(_ShapeParams[diffusionProfileIndex].rgb, + bsdfData.transmittance = ComputeTransmittanceDisney(_ShapeParamsAndMaxScatterDists[diffusionProfileIndex].rgb, _TransmissionTintsAndFresnel0[diffusionProfileIndex].rgb, bsdfData.thickness); } @@ -224,10 +224,10 @@ uint FindDiffusionProfileIndex(uint diffusionProfileHash) { if (diffusionProfileHash == 0) return 0; - + uint diffusionProfileIndex = 0; uint i = 0; - + // Fetch the 4 bit index number by looking for the diffusion profile unique ID: for (i = 0; i < _DiffusionProfileCount; i++) { diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs index c03b6f85431..05d85475728 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs @@ -24,11 +24,10 @@ public partial class HDRenderPipeline // List of every diffusion profile data we need Vector4[] m_SSSThicknessRemaps; - Vector4[] m_SSSShapeParams; + Vector4[] m_SSSShapeParamsAndMaxScatterDists; Vector4[] m_SSSTransmissionTintsAndFresnel0; Vector4[] m_SSSDisabledTransmissionTintsAndFresnel0; - Vector4[] m_SSSWorldScales; - Vector4[] m_SSSFilterKernels; + Vector4[] m_SSSWorldScalesAndFilterRadii; float[] m_SSSDiffusionProfileHashes; int[] m_SSSDiffusionProfileUpdate; DiffusionProfileSettings[] m_SSSSetDiffusionProfiles; @@ -74,11 +73,10 @@ void InitSSSBuffers() // fill the list with the max number of diffusion profile so we dont have // the error: exceeds previous array size (5 vs 3). Cap to previous size. m_SSSThicknessRemaps = new Vector4[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; - m_SSSShapeParams = new Vector4[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; + m_SSSShapeParamsAndMaxScatterDists = new Vector4[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; m_SSSTransmissionTintsAndFresnel0 = new Vector4[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; m_SSSDisabledTransmissionTintsAndFresnel0 = new Vector4[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; - m_SSSWorldScales = new Vector4[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; - m_SSSFilterKernels = new Vector4[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT * DiffusionProfileConstants.SSS_N_SAMPLES_NEAR_FIELD]; + m_SSSWorldScalesAndFilterRadii = new Vector4[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; m_SSSDiffusionProfileHashes = new float[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; m_SSSDiffusionProfileUpdate = new int[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; m_SSSSetDiffusionProfiles = new DiffusionProfileSettings[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; @@ -159,26 +157,15 @@ void SetDiffusionProfileAtIndex(DiffusionProfileSettings settings, int index) return; // if the settings have not yet been initialized - if (settings.profile.filterKernelNearField == null) + if (settings.profile.hash == 0) return; - m_SSSThicknessRemaps[index] = settings.thicknessRemaps; - m_SSSShapeParams[index] = settings.shapeParams; - m_SSSTransmissionTintsAndFresnel0[index] = settings.transmissionTintsAndFresnel0; - m_SSSDisabledTransmissionTintsAndFresnel0[index] = settings.disabledTransmissionTintsAndFresnel0; - m_SSSWorldScales[index] = settings.worldScales; - for (int j = 0, n = DiffusionProfileConstants.SSS_N_SAMPLES_NEAR_FIELD; j < n; j++) - { - m_SSSFilterKernels[n * index + j].x = settings.profile.filterKernelNearField[j].x; - m_SSSFilterKernels[n * index + j].y = settings.profile.filterKernelNearField[j].y; - - if (j < DiffusionProfileConstants.SSS_N_SAMPLES_FAR_FIELD) - { - m_SSSFilterKernels[n * index + j].z = settings.profile.filterKernelFarField[j].x; - m_SSSFilterKernels[n * index + j].w = settings.profile.filterKernelFarField[j].y; - } - } - m_SSSDiffusionProfileHashes[index] = HDShadowUtils.Asfloat(settings.profile.hash); + m_SSSThicknessRemaps[index] = settings.thicknessRemap; + m_SSSShapeParamsAndMaxScatterDists[index] = settings.shapeParamAndMaxScatterDist; + m_SSSTransmissionTintsAndFresnel0[index] = settings.transmissionTintAndFresnel0; + m_SSSDisabledTransmissionTintsAndFresnel0[index] = settings.disabledTransmissionTintAndFresnel0; + m_SSSWorldScalesAndFilterRadii[index] = settings.worldScalesAndFilterRadii; + m_SSSDiffusionProfileHashes[index] = HDShadowUtils.Asfloat(settings.profile.hash); // HDShadowUtils ?.. // Erase previous value (This need to be done here individually as in the SSS editor we edit individual component) uint mask = 1u << index; @@ -213,10 +200,10 @@ void PushSubsurfaceScatteringGlobalParams(HDCamera hdCamera, CommandBuffer cmd) cmd.SetGlobalFloat(HDShaderIDs._TransmissionFlags, *(float*)&transmissionFlags); } cmd.SetGlobalVectorArray(HDShaderIDs._ThicknessRemaps, m_SSSThicknessRemaps); - cmd.SetGlobalVectorArray(HDShaderIDs._ShapeParams, m_SSSShapeParams); + cmd.SetGlobalVectorArray(HDShaderIDs._ShapeParamsAndMaxScatterDists, m_SSSShapeParamsAndMaxScatterDists); // To disable transmission, we simply nullify the transmissionTint cmd.SetGlobalVectorArray(HDShaderIDs._TransmissionTintsAndFresnel0, hdCamera.frameSettings.IsEnabled(FrameSettingsField.Transmission) ? m_SSSTransmissionTintsAndFresnel0 : m_SSSDisabledTransmissionTintsAndFresnel0); - cmd.SetGlobalVectorArray(HDShaderIDs._WorldScales, m_SSSWorldScales); + cmd.SetGlobalVectorArray(HDShaderIDs._WorldScalesAndFilterRadii, m_SSSWorldScalesAndFilterRadii); cmd.SetGlobalFloatArray(HDShaderIDs._DiffusionProfileHashTable, m_SSSDiffusionProfileHashes); } @@ -243,7 +230,6 @@ struct SubsurfaceScatteringParameters public int numTilesY; public int numTilesZ; public Vector4[] worldScales; - public Vector4[] filterKernels; public Vector4[] shapeParams; public float[] diffusionProfileHashes; @@ -275,9 +261,8 @@ SubsurfaceScatteringParameters PrepareSubsurfaceScatteringParameters(HDCamera hd parameters.numTilesY = ((int)hdCamera.screenSize.y + 15) / 16; parameters.numTilesZ = hdCamera.viewCount; - parameters.worldScales = m_SSSWorldScales; - parameters.filterKernels = m_SSSFilterKernels; - parameters.shapeParams = m_SSSShapeParams; + parameters.worldScales = m_SSSWorldScalesAndFilterRadii; + parameters.shapeParams = m_SSSShapeParamsAndMaxScatterDists; parameters.diffusionProfileHashes = m_SSSDiffusionProfileHashes; return parameters; @@ -442,7 +427,7 @@ void RenderSubsurfaceScattering(HDCamera hdCamera, CommandBuffer cmd, RTHandle c } } } - + // Combines specular lighting and diffuse lighting with subsurface scattering. // In the case our frame is MSAA, for the moment given the fact that we do not have read/write access to the stencil buffer of the MSAA target; we need to keep this pass MSAA @@ -457,9 +442,8 @@ static void RenderSubsurfaceScattering(in SubsurfaceScatteringParameters paramet cmd.SetComputeFloatParam(parameters.subsurfaceScatteringCS, HDShaderIDs._TexturingModeFlags, *(float*)&textureingModeFlags); } - cmd.SetComputeVectorArrayParam(parameters.subsurfaceScatteringCS, HDShaderIDs._WorldScales, parameters.worldScales); - cmd.SetComputeVectorArrayParam(parameters.subsurfaceScatteringCS, HDShaderIDs._FilterKernels, parameters.filterKernels); - cmd.SetComputeVectorArrayParam(parameters.subsurfaceScatteringCS, HDShaderIDs._ShapeParams, parameters.shapeParams); + cmd.SetComputeVectorArrayParam(parameters.subsurfaceScatteringCS, HDShaderIDs._WorldScalesAndFilterRadii, parameters.worldScales); + cmd.SetComputeVectorArrayParam(parameters.subsurfaceScatteringCS, HDShaderIDs._ShapeParamsAndMaxScatterDists, parameters.shapeParams); cmd.SetComputeFloatParams(parameters.subsurfaceScatteringCS, HDShaderIDs._DiffusionProfileHashTable, parameters.diffusionProfileHashes); cmd.SetComputeTextureParam(parameters.subsurfaceScatteringCS, parameters.subsurfaceScatteringCSKernel, HDShaderIDs._DepthTexture, resources.depthTexture); 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 7d5b68bb27f..775eb582bb2 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs @@ -225,7 +225,7 @@ static class HDShaderIDs public static readonly int _TexturingModeFlags = Shader.PropertyToID("_TexturingModeFlags"); public static readonly int _TransmissionFlags = Shader.PropertyToID("_TransmissionFlags"); public static readonly int _ThicknessRemaps = Shader.PropertyToID("_ThicknessRemaps"); - public static readonly int _ShapeParams = Shader.PropertyToID("_ShapeParams"); + public static readonly int _ShapeParamsAndMaxScatterDists = Shader.PropertyToID("_ShapeParamsAndMaxScatterDists"); public static readonly int _TransmissionTintsAndFresnel0 = Shader.PropertyToID("_TransmissionTintsAndFresnel0"); public static readonly int specularLightingUAV = Shader.PropertyToID("specularLightingUAV"); public static readonly int diffuseLightingUAV = Shader.PropertyToID("diffuseLightingUAV"); @@ -433,10 +433,7 @@ static class HDShaderIDs public static readonly int _BlitPaddingSize = Shader.PropertyToID("_BlitPaddingSize"); public static readonly int _BlitTexArraySlice = Shader.PropertyToID("_BlitTexArraySlice"); - public static readonly int _WorldScales = Shader.PropertyToID("_WorldScales"); - public static readonly int _FilterKernels = Shader.PropertyToID("_FilterKernels"); - public static readonly int _FilterKernelsBasic = Shader.PropertyToID("_FilterKernelsBasic"); - public static readonly int _HalfRcpWeightedVariances = Shader.PropertyToID("_HalfRcpWeightedVariances"); + public static readonly int _WorldScalesAndFilterRadii = Shader.PropertyToID("_WorldScalesAndFilterRadii"); public static readonly int _CameraDepthTexture = Shader.PropertyToID("_CameraDepthTexture"); public static readonly int _CameraMotionVectorsTexture = Shader.PropertyToID("_CameraMotionVectorsTexture"); @@ -714,7 +711,7 @@ static class HDShaderIDs public static readonly int _NormalTextureRW = Shader.PropertyToID("_NormalTextureRW"); public static readonly int _PositionTextureRW = Shader.PropertyToID("_PositionTextureRW"); public static readonly int _DiffuseLightingTextureRW = Shader.PropertyToID("_DiffuseLightingTextureRW"); - + // Preintegrated texture name public static readonly int _PreIntegratedFGD_GGXDisneyDiffuse = Shader.PropertyToID("_PreIntegratedFGD_GGXDisneyDiffuse"); public static readonly int _PreIntegratedFGD_CharlieAndFabric = Shader.PropertyToID("_PreIntegratedFGD_CharlieAndFabric"); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingSubSurface.raytrace b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingSubSurface.raytrace index faffd8f5997..5638bced9f4 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingSubSurface.raytrace +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingSubSurface.raytrace @@ -50,7 +50,7 @@ void RayGenSubSurface() // Force the throughput value of this pixel to black in case we do not need to compute sss for it _ThroughputTextureRW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(0.0f, 0.0f, 0.0f, 0.0f); - + // Does this pixel have SSS? uint stencilValue = GetStencilValue(LOAD_TEXTURE2D_X(_StencilTexture, currentPixelCoord)); if ((stencilValue & STENCILUSAGE_SUBSURFACE_SCATTERING) == 0) @@ -77,12 +77,12 @@ void RayGenSubSurface() // Read the SSS Data SSSData sssData; DECODE_FROM_SSSBUFFER(posInput.positionSS, sssData); - float3 shapeParam = _ShapeParams[sssData.diffusionProfileIndex].rgb; + float3 shapeParam = _ShapeParamsAndMaxScatterDists[sssData.diffusionProfileIndex].rgb; // Deduce our scattering distance // For some reason the value in shapeParam is negative, convert it to milimeters while we are there. float3 scatteringDistance = -1.0 / shapeParam * 0.001; - + // Define which sample in the sequence we are up to. int globalSampleIndex = _RaytracingFrameIndex * _RaytracingNumSamples + _RaytracingSampleIndex; From cf7bde2d1ffa1bce9aa26a0c618c24b1c7d1b93a Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Thu, 20 Feb 2020 16:10:36 -0800 Subject: [PATCH 05/63] Attempt to fix previews --- .../DiffusionProfileSettingsEditor.cs | 12 +++++------- .../DiffusionProfile/DrawDiffusionProfile.shader | 14 ++++++++------ .../DiffusionProfile/DrawTransmittanceGraph.shader | 12 ++++++++---- .../DiffusionProfile/DiffusionProfileSettings.cs | 4 ++-- .../ShaderVariablesSubsurfaceScattering.cs | 2 +- 5 files changed, 24 insertions(+), 20 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DiffusionProfileSettingsEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DiffusionProfileSettingsEditor.cs index 3451cd5ddbf..d18fe75c9ac 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DiffusionProfileSettingsEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DiffusionProfileSettingsEditor.cs @@ -151,11 +151,9 @@ void RenderPreview(Profile profile) { var obj = profile.objReference; float r = obj.filterRadius; - var S = obj.shapeParam; - var T = (Vector4)profile.transmissionTint.colorValue; - var R = profile.thicknessRemap.vector2Value; + var S = obj.shapeParam; - m_ProfileMaterial.SetFloat(HDShaderIDs._MaxRadius, r); + m_ProfileMaterial.SetFloat( HDShaderIDs._MaxRadius, r); m_ProfileMaterial.SetVector(HDShaderIDs._ShapeParam, S); // Draw the profile. @@ -167,9 +165,9 @@ void RenderPreview(Profile profile) EditorGUILayout.LabelField(s_Styles.transmittancePreview2, EditorStyles.centeredGreyMiniLabel); EditorGUILayout.Space(); - m_TransmittanceMaterial.SetVector(HDShaderIDs._ShapeParam, S); - m_TransmittanceMaterial.SetVector(HDShaderIDs._TransmissionTint, T); - m_TransmittanceMaterial.SetVector(HDShaderIDs._ThicknessRemap, R); + m_TransmittanceMaterial.SetVector(HDShaderIDs._ShapeParam, S); + m_TransmittanceMaterial.SetVector(HDShaderIDs._TransmissionTint, obj.transmissionTint); + m_TransmittanceMaterial.SetVector(HDShaderIDs._ThicknessRemap, obj.thicknessRemap); // Draw the transmittance graph. EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(16f, 16f), profile.transmittanceRT, m_TransmittanceMaterial, ScaleMode.ScaleToFit, 16f); diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DrawDiffusionProfile.shader b/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DrawDiffusionProfile.shader index 3b1a0cce06e..0c44c124a16 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DrawDiffusionProfile.shader +++ b/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DrawDiffusionProfile.shader @@ -24,6 +24,7 @@ Shader "Hidden/HDRP/DrawDiffusionProfile" #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/DiffusionProfile/DiffusionProfile.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/EditorShaderVariables.hlsl" //------------------------------------------------------------------------------------- @@ -59,15 +60,16 @@ Shader "Hidden/HDRP/DrawDiffusionProfile" float4 Frag(Varyings input) : SV_Target { + // Profile display does not use premultiplied S. - float r = (2 * length(input.texcoord - 0.5)) * _MaxRadius; + float r = _MaxRadius * 0.5 * length(input.texcoord - 0.5); // (-0.25 * R, 0.25 * R) float3 S = _ShapeParam.rgb; - float3 M = S * (exp(-r * S) + exp(-r * S * (1.0 / 3.0))) / (8 * PI * r); - float3 A = _MaxRadius / S; + float3 M; - // N.b.: we multiply by the surface albedo of the actual geometry during shading. - // Apply gamma for visualization only. Do not apply gamma to the color. - return float4(sqrt(M) * A, 1); + // Gamma in previews is weird... + S = S * S; + M = EvalBurleyDiffusionProfile(r, S) / r; // Divide by 'r' since we are not integrating in polar coords + return float4(sqrt(M), 1); } ENDHLSL } diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DrawTransmittanceGraph.shader b/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DrawTransmittanceGraph.shader index d7001e31df2..0d778f47059 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DrawTransmittanceGraph.shader +++ b/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DrawTransmittanceGraph.shader @@ -32,7 +32,6 @@ Shader "Hidden/HDRP/DrawTransmittanceGraph" // Inputs & outputs //------------------------------------------------------------------------------------- - float4 _HalfRcpVarianceAndWeight1, _HalfRcpVarianceAndWeight2; float4 _ShapeParam, _TransmissionTint, _ThicknessRemap; //------------------------------------------------------------------------------------- @@ -64,10 +63,15 @@ Shader "Hidden/HDRP/DrawTransmittanceGraph" { // Profile display does not use premultiplied S. float d = (_ThicknessRemap.x + input.texcoord.x * (_ThicknessRemap.y - _ThicknessRemap.x)); - float3 T = ComputeTransmittanceDisney(_ShapeParam.rgb * ((-1.0 / 3.0) * LOG2_E), float3(0.25, 0.25, 0.25), d); + float3 S = _ShapeParam.rgb; + float3 A = _TransmissionTint.rgb; + float3 M; - // Apply gamma for visualization only. Do not apply gamma to the color. - return float4(sqrt(T) * _TransmissionTint.rgb, 1); + // Gamma in previews is weird... + S = S * S; + A = A * A; + M = ComputeTransmittanceDisney(S, 0.25 * A, d); // The function expects pre-multiplied inputs + return float4(sqrt(M), 1); } ENDHLSL } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs index 1c5416f9231..1b9990f5eeb 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs @@ -186,7 +186,7 @@ internal partial class DiffusionProfileSettings : ScriptableObject internal DiffusionProfile profile; [NonSerialized] internal Vector4 thicknessRemap; // Remap: 0 = start, 1 = end - start - [NonSerialized] internal Vector4 worldScalesAndFilterRadii; // X = meters per world unit, Y = filter radius (in mm), Z = 1/X, W = 1/Y + [NonSerialized] internal Vector4 worldScalesAndFilterRadii; // X = meters per world unit, Y = filter radius (in mm) [NonSerialized] internal Vector4 shapeParamAndMaxScatterDist; // RGB = S = 1 / D, A = d = RgbMax(D) [NonSerialized] internal Vector4 transmissionTintAndFresnel0; // RGB = color, A = fresnel0 [NonSerialized] internal Vector4 disabledTransmissionTintAndFresnel0; // RGB = black, A = fresnel0 - For debug to remove the transmission @@ -217,7 +217,7 @@ void OnEnable() internal void UpdateCache() { thicknessRemap = new Vector4(profile.thicknessRemap.x, profile.thicknessRemap.y - profile.thicknessRemap.x, 0, 0); - worldScalesAndFilterRadii = new Vector4(profile.worldScale, profile.filterRadius, 1.0f / profile.worldScale, 1.0f / profile.filterRadius); + worldScalesAndFilterRadii = new Vector4(profile.worldScale, profile.filterRadius, 0, 0); shapeParamAndMaxScatterDist = profile.shapeParam; shapeParamAndMaxScatterDist.w = profile.maxScatteringDistance; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs index 3584ab0a6bf..309fc6247e9 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs @@ -11,7 +11,7 @@ unsafe struct ShaderVariablesSubsurfaceScattering [HLSLArray(DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT, typeof(Vector4))] public fixed float _TransmissionTintsAndFresnel0[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT * 4]; // RGB = 1/4 * color, A = fresnel0 [HLSLArray(DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT, typeof(Vector4))] - public fixed float _WorldScalesAndFilterRadii[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT * 4]; // X = meters per world unit, Y = filter radius (in mm), Z = 1/X, W = 1/Y + public fixed float _WorldScalesAndFilterRadii[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT * 4]; // X = meters per world unit, Y = filter radius (in mm) [HLSLArray(DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT, typeof(float))] public fixed uint _DiffusionProfileHashTable[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; // TODO: constant From 9537b6862c94aa9160a76ac149d1277a54abc31c Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Thu, 20 Feb 2020 16:20:37 -0800 Subject: [PATCH 06/63] Fix transmission --- .../Runtime/Lighting/SurfaceShading.hlsl | 13 +++---------- .../DiffusionProfile/DiffusionProfileSettings.cs | 12 ++++++------ .../SubsurfaceScattering.compute | 2 +- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/SurfaceShading.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Lighting/SurfaceShading.hlsl index e32773fbf5b..e71b3adeac8 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/SurfaceShading.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/SurfaceShading.hlsl @@ -137,20 +137,13 @@ float3 EvaluateTransmittance_Punctual(LightLoopContext lightLoopContext, float thicknessInMillimeters = thicknessInMeters * MILLIMETERS_PER_METER; // We need to make sure it's not less than the baked thickness to minimize light leaking. - float thicknessDelta = max(0, thicknessInMillimeters - bsdfData.thickness); - + float dt = max(0, thicknessInMillimeters - bsdfData.thickness); float3 S = _ShapeParamsAndMaxScatterDists[bsdfData.diffusionProfileIndex].rgb; -#if 0 - float3 expOneThird = exp(((-1.0 / 3.0) * thicknessDelta) * S); -#else - // Help the compiler. S is premultiplied by ((-1.0 / 3.0) * LOG2_E) on the CPU. - float3 p = thicknessDelta * S; - float3 expOneThird = exp2(p); -#endif + float3 exp_13 = exp2(((LOG2_E * (-1.0/3.0)) * dt) * S); // Exp[-S * r / 3] // Approximate the decrease of transmittance by e^(-1/3 * dt * S). - return bsdfData.transmittance * expOneThird; + return bsdfData.transmittance * exp_13; } #endif diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs index 1b9990f5eeb..f3c2d65e384 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs @@ -72,11 +72,11 @@ void UpdateKernel() Vector3 sd = (Vector3)(Vector4)scatteringDistance; // Rather inconvenient to support (S = Inf). - shapeParam = new Vector3(Mathf.Min(16777215, 1.0f / sd.x), - Mathf.Min(16777215, 1.0f / sd.y), - Mathf.Min(16777215, 1.0f / sd.z)); + shapeParam = new Vector3(Mathf.Min(16777216, 1.0f / sd.x), + Mathf.Min(16777216, 1.0f / sd.y), + Mathf.Min(16777216, 1.0f / sd.z)); - int n = DiffusionProfileConstants.SSS_N_SAMPLES_NEAR_FIELD; // TODO + int n = DiffusionProfileConstants.SSS_N_SAMPLES_FAR_FIELD; // TODO float p = ((n - 1) + 0.5f) * (1.0f / n); // Last sample // Importance sample the normalized diffuse reflectance profile for the computed value of 's'. @@ -240,8 +240,8 @@ internal bool HasChanged(int update) /// public void SetDefaultParams() { - worldScalesAndFilterRadii = new Vector4(1, 1, 0, 0); - shapeParamAndMaxScatterDist = new Vector4(Mathf.Infinity, Mathf.Infinity, Mathf.Infinity, 0); + worldScalesAndFilterRadii = new Vector4(1, 0, 0, 0); + shapeParamAndMaxScatterDist = new Vector4(16777216, 16777216, 16777216, 0); transmissionTintAndFresnel0.w = 0.04f; // Match DEFAULT_SPECULAR_VALUE defined in Lit.hlsl } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute index 527c2050a76..d2996dfacf6 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute @@ -452,7 +452,7 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, // Compute the indices used to access the individual components of the float4 of the kernel. uint iR = useNearFieldKernel ? 0 : 2; // radius uint iP = useNearFieldKernel ? 1 : 3; // rcp(pdf) - uint n = SSS_N_SAMPLES_NEAR_FIELD; + uint n = SSS_N_SAMPLES_FAR_FIELD; const float scale = rcp(n); const float offset = 0.5 * rcp(n); From e9afd2887db54a21b3797c4e8861c9f29aaa4a2b Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Fri, 21 Feb 2020 16:20:00 -0800 Subject: [PATCH 07/63] Support quality levels --- .../ShaderLibrary/Sampling/Fibonacci.hlsl | 10 +- .../RenderPipeline/HDRenderPipelineUI.Skin.cs | 2 +- .../RenderPipeline/HDRenderPipelineUI.cs | 2 +- .../Settings/FrameSettingsUI.Drawers.cs | 27 ++++- .../Settings/SerializedFrameSettings.cs | 25 +++-- .../SerializedRenderPipelineSettings.cs | 11 +- .../DiffusionProfileSettings.cs | 8 ++ .../SubsurfaceScattering.compute | 26 ++--- .../SubsurfaceScatteringManager.cs | 8 +- .../RenderPipeline/HDRenderPipeline.cs | 5 +- .../RenderPipeline/HDStringConstants.cs | 1 + .../RenderPipeline/Settings/FrameSettings.cs | 106 ++++++++++++++---- .../Settings/RenderPipelineSettings.cs | 7 +- 13 files changed, 172 insertions(+), 66 deletions(-) diff --git a/com.unity.render-pipelines.core/ShaderLibrary/Sampling/Fibonacci.hlsl b/com.unity.render-pipelines.core/ShaderLibrary/Sampling/Fibonacci.hlsl index c10b85f9124..80ffef36e98 100644 --- a/com.unity.render-pipelines.core/ShaderLibrary/Sampling/Fibonacci.hlsl +++ b/com.unity.render-pipelines.core/ShaderLibrary/Sampling/Fibonacci.hlsl @@ -12,8 +12,8 @@ real2 Fibonacci2dSeq(real fibN1, real fibN2, uint i) return real2(i / fibN1 + (0.5 / fibN1), frac(i * (fibN2 / fibN1))); } -#define GOLDEN_RATIO 1.61803 -#define GOLDEN_ANGLE 2.39996 +#define GOLDEN_RATIO 1.618033988749895 +#define GOLDEN_ANGLE 2.399963229728653 // Replaces the Fibonacci sequence in Fibonacci2dSeq() with the Golden ratio. real2 Golden2dSeq(uint i, real n) @@ -268,6 +268,12 @@ real2 Fibonacci2d(uint i, uint sampleCount) } } +real2 SampleDiskGolden(uint i, uint sampleCount) +{ + real2 f = Golden2dSeq(i, sampleCount); + return real2(sqrt(f.x), TWO_PI * f.y); +} + // Returns the radius as the X coordinate, and the angle as the Y coordinate. real2 SampleDiskFibonacci(uint i, uint sampleCount) { diff --git a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.Skin.cs b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.Skin.cs index e78b1a0adf4..3b0e38b65c4 100644 --- a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.Skin.cs +++ b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.Skin.cs @@ -81,7 +81,7 @@ public class GeneralSection public static readonly GUIContent supportSSRContent = EditorGUIUtility.TrTextContent("Screen Space Reflection", "When enabled, HDRP allocates memory for processing screen space reflection (SSR). This allows you to use SSR in your Unity Project."); public static readonly GUIContent supportSSAOContent = EditorGUIUtility.TrTextContent("Screen Space Ambient Occlusion", "When enabled, HDRP allocates memory for processing screen space ambient occlusion (SSAO). This allows you to use SSAO in your Unity Project."); public static readonly GUIContent supportedSSSContent = EditorGUIUtility.TrTextContent("Subsurface Scattering", "When enabled, HDRP allocates memory for processing subsurface scattering (SSS). This allows you to use SSS in your Unity Project."); - public static readonly GUIContent SSSSampleCountContent = EditorGUIUtility.TrTextContent("High Quality ", "When enabled, HDRP processes higher quality subsurface scattering effects. Warning: There is a high performance cost, do not enable on consoles."); + public static readonly GUIContent sssSampleBudget = EditorGUIUtility.TrTextContent("Sample Budget", "Maximum number of samples the Subsurface Scattering algorithm is allowed to take."); public static readonly GUIContent supportVolumetricContent = EditorGUIUtility.TrTextContent("Volumetrics", "When enabled, HDRP allocates Shader variants and memory for volumetric effects. This allows you to use volumetric lighting and fog in your Unity Project."); public static readonly GUIContent volumetricResolutionContent = EditorGUIUtility.TrTextContent("High Quality ", "When enabled, HDRP increases the resolution of volumetric lighting buffers. Warning: There is a high performance cost, do not enable on consoles."); public static readonly GUIContent supportLightLayerContent = EditorGUIUtility.TrTextContent("Enable", "When enabled, HDRP allocates memory for processing Light Layers. This allows you to use Light Layers in your Unity Project. For deferred rendering, this allocation includes an extra render target in memory and extra cost."); diff --git a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.cs b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.cs index 6da2fed2e01..c3e0e3539f0 100644 --- a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.cs +++ b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.cs @@ -882,7 +882,7 @@ static void Drawer_SectionMaterialUnsorted(SerializedHDRenderPipelineAsset seria || !serialized.renderPipelineSettings.supportSubsurfaceScattering.boolValue)) { ++EditorGUI.indentLevel; - EditorGUILayout.PropertyField(serialized.renderPipelineSettings.increaseSssSampleCount, Styles.SSSSampleCountContent); + serialized.renderPipelineSettings.sssSampleBudget.ValueGUI(Styles.sssSampleBudget); --EditorGUI.indentLevel; } diff --git a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/FrameSettingsUI.Drawers.cs b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/FrameSettingsUI.Drawers.cs index 3a5972baca5..4f6b13b1e5e 100644 --- a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/FrameSettingsUI.Drawers.cs +++ b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/FrameSettingsUI.Drawers.cs @@ -63,7 +63,7 @@ internal static CED.IDrawer Inspector(bool withOverride = true) => CED.Group( CED.Group((serialized, owner) => { lastBoxRect = EditorGUILayout.BeginVertical("box"); - + // Add dedicated scope here and on each FrameSettings field to have the contextual menu on everything Rect rect = GUILayoutUtility.GetRect(1, EditorGUIUtility.singleLineHeight); using (new SerializedFrameSettings.TitleDrawingScope(rect, FrameSettingsUI.frameSettingsHeaderContent, serialized)) @@ -278,7 +278,30 @@ static void Drawer_SectionLightingSettings(SerializedFrameSettings serialized, E area.AmmendInfo(FrameSettingsField.Shadowmask, overrideable: () => hdrpSettings.supportShadowMask); area.AmmendInfo(FrameSettingsField.SSR, overrideable: () => hdrpSettings.supportSSR); area.AmmendInfo(FrameSettingsField.SSAO, overrideable: () => hdrpSettings.supportSSAO); - area.AmmendInfo(FrameSettingsField.SubsurfaceScattering, overrideable: () => hdrpSettings.supportSubsurfaceScattering); + + // SSS + area.AmmendInfo( + FrameSettingsField.SubsurfaceScattering, overrideable: () => hdrpSettings.supportSubsurfaceScattering + ); + area.AmmendInfo( + FrameSettingsField.SssQualityMode, + overridedDefaultValue: SssQualityMode.FromQualitySettings, + customGetter: () => serialized.sssQualityMode.GetEnumValue(), + customSetter: v => serialized.sssQualityMode.SetEnumValue((SssQualityMode)v) + ); + area.AmmendInfo(FrameSettingsField.SssQualityLevel, + overridedDefaultValue: ScalableLevel3ForFrameSettingsUIOnly.Low, + customGetter: () => (ScalableLevel3ForFrameSettingsUIOnly)serialized.sssQualityLevel.intValue, // 3 levels + customSetter: v => serialized.sssQualityLevel.intValue = Math.Max(0, Math.Min((int)v, 2)), // Levels 0-2 + customOverrideable: () => (serialized.IsEnabled(FrameSettingsField.SubsurfaceScattering) ?? false) && serialized.sssQualityMode.GetEnumValue() == SssQualityMode.FromQualitySettings + ); + area.AmmendInfo(FrameSettingsField.SssCustomSampleBudget, + overridedDefaultValue: (int)DefaultSssSampleBudgetForQualityLevel.Low, + customGetter: () => serialized.sssCustomSampleBudget.intValue, + customSetter: v => serialized.sssCustomSampleBudget.intValue = Math.Max(1, Math.Min((int)v, (int)DefaultSssSampleBudgetForQualityLevel.Max)), + customOverrideable: () => (serialized.IsEnabled(FrameSettingsField.SubsurfaceScattering) ?? false) && serialized.sssQualityMode.GetEnumValue() != SssQualityMode.FromQualitySettings + ); + area.AmmendInfo(FrameSettingsField.Volumetrics, overrideable: () => hdrpSettings.supportVolumetrics); area.AmmendInfo(FrameSettingsField.ReprojectionForVolumetrics, overrideable: () => hdrpSettings.supportVolumetrics); area.AmmendInfo(FrameSettingsField.LightLayers, overrideable: () => hdrpSettings.supportLightLayers); diff --git a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/SerializedFrameSettings.cs b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/SerializedFrameSettings.cs index 1771300ff5c..b7f49dcd186 100644 --- a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/SerializedFrameSettings.cs +++ b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/SerializedFrameSettings.cs @@ -11,6 +11,9 @@ class SerializedFrameSettings SerializedProperty m_RootOverrides; SerializedBitArray128 m_BitDatas; SerializedBitArray128 m_BitOverrides; + public SerializedProperty sssQualityMode; + public SerializedProperty sssQualityLevel; + public SerializedProperty sssCustomSampleBudget; public SerializedProperty lodBias; public SerializedProperty lodBiasMode; public SerializedProperty lodBiasQualityLevel; @@ -83,17 +86,21 @@ ref FrameSettings GetData(Object obj) public SerializedFrameSettings(SerializedProperty rootData, SerializedProperty rootOverrides) { - m_RootData = rootData; + m_RootData = rootData; m_RootOverrides = rootOverrides; - m_BitDatas = rootData.FindPropertyRelative("bitDatas").ToSerializeBitArray128(); - m_BitOverrides = rootOverrides?.FindPropertyRelative("mask").ToSerializeBitArray128(); //rootOverride can be null in case of hdrpAsset defaults - lodBias = rootData.FindPropertyRelative("lodBias"); - lodBiasMode = rootData.FindPropertyRelative("lodBiasMode"); - lodBiasQualityLevel = rootData.FindPropertyRelative("lodBiasQualityLevel"); - maximumLODLevel = rootData.FindPropertyRelative("maximumLODLevel"); - maximumLODLevelMode = rootData.FindPropertyRelative("maximumLODLevelMode"); + m_BitDatas = rootData.FindPropertyRelative("bitDatas").ToSerializeBitArray128(); + m_BitOverrides = rootOverrides?.FindPropertyRelative("mask").ToSerializeBitArray128(); //rootOverride can be null in case of hdrpAsset defaults + + sssQualityMode = rootData.FindPropertyRelative("sssQualityMode"); + sssQualityLevel = rootData.FindPropertyRelative("sssQualityLevel"); + sssCustomSampleBudget = rootData.FindPropertyRelative("sssCustomSampleBudget"); + lodBias = rootData.FindPropertyRelative("lodBias"); + lodBiasMode = rootData.FindPropertyRelative("lodBiasMode"); + lodBiasQualityLevel = rootData.FindPropertyRelative("lodBiasQualityLevel"); + maximumLODLevel = rootData.FindPropertyRelative("maximumLODLevel"); + maximumLODLevelMode = rootData.FindPropertyRelative("maximumLODLevelMode"); maximumLODLevelQualityLevel = rootData.FindPropertyRelative("maximumLODLevelQualityLevel"); - materialQuality = rootData.Find((FrameSettings s) => s.materialQuality); + materialQuality = rootData.Find((FrameSettings s) => s.materialQuality); } public struct TitleDrawingScope : IDisposable diff --git a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/SerializedRenderPipelineSettings.cs b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/SerializedRenderPipelineSettings.cs index d0dc00f88a2..ead7cc2bec3 100644 --- a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/SerializedRenderPipelineSettings.cs +++ b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/SerializedRenderPipelineSettings.cs @@ -21,8 +21,7 @@ class SerializedRenderPipelineSettings public SerializedProperty supportSSR; public SerializedProperty supportSSAO; public SerializedProperty supportSubsurfaceScattering; - [UnityEngine.Serialization.FormerlySerializedAs("enableUltraQualitySSS")] - public SerializedProperty increaseSssSampleCount; + public SerializedScalableSetting sssSampleBudget; [UnityEngine.Serialization.FormerlySerializedAs("supportVolumetric")] public SerializedProperty supportVolumetrics; public SerializedProperty increaseResolutionOfVolumetrics; @@ -76,7 +75,7 @@ public SerializedRenderPipelineSettings(SerializedProperty root) supportSSR = root.Find((RenderPipelineSettings s) => s.supportSSR); supportSSAO = root.Find((RenderPipelineSettings s) => s.supportSSAO); supportSubsurfaceScattering = root.Find((RenderPipelineSettings s) => s.supportSubsurfaceScattering); - increaseSssSampleCount = root.Find((RenderPipelineSettings s) => s.increaseSssSampleCount); + sssSampleBudget = new SerializedScalableSetting(root.Find((RenderPipelineSettings s) => s.sssSampleBudget)); supportVolumetrics = root.Find((RenderPipelineSettings s) => s.supportVolumetrics); increaseResolutionOfVolumetrics = root.Find((RenderPipelineSettings s) => s.increaseResolutionOfVolumetrics); supportLightLayers = root.Find((RenderPipelineSettings s) => s.supportLightLayers); @@ -92,13 +91,13 @@ public SerializedRenderPipelineSettings(SerializedProperty root) customBufferFormat = root.Find((RenderPipelineSettings s) => s.customBufferFormat); supportCustomPass = root.Find((RenderPipelineSettings s) => s.supportCustomPass); supportedLitShaderMode = root.Find((RenderPipelineSettings s) => s.supportedLitShaderMode); - + supportDecals = root.Find((RenderPipelineSettings s) => s.supportDecals); - MSAASampleCount = root.Find((RenderPipelineSettings s) => s.msaaSampleCount); + MSAASampleCount = root.Find((RenderPipelineSettings s) => s.msaaSampleCount); supportMotionVectors = root.Find((RenderPipelineSettings s) => s.supportMotionVectors); supportRuntimeDebugDisplay = root.Find((RenderPipelineSettings s) => s.supportRuntimeDebugDisplay); supportDitheringCrossFade = root.Find((RenderPipelineSettings s) => s.supportDitheringCrossFade); - supportTerrainHole = root.Find((RenderPipelineSettings s) => s.supportTerrainHole); + supportTerrainHole = root.Find((RenderPipelineSettings s) => s.supportTerrainHole); supportDistortion = root.Find((RenderPipelineSettings s) => s.supportDistortion); supportTransparentBackface = root.Find((RenderPipelineSettings s) => s.supportTransparentBackface); supportTransparentDepthPrepass = root.Find((RenderPipelineSettings s) => s.supportTransparentDepthPrepass); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs index f3c2d65e384..3ad73c6fb29 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs @@ -12,6 +12,14 @@ class DiffusionProfileConstants public const int SSS_PIXELS_PER_SAMPLE = 4; } + public enum DefaultSssSampleBudgetForQualityLevel + { + Low = 20, + Medium = 40, + High = 80, + Max = 1000 + } + [Serializable] class DiffusionProfile : IEquatable { diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute index d2996dfacf6..1ebc7bf05cd 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute @@ -56,7 +56,7 @@ // Inputs & outputs //-------------------------------------------------------------------------------------------------- -float4 _FilterKernels[DIFFUSION_PROFILE_COUNT][SSS_N_SAMPLES_NEAR_FIELD]; // XY = near field, ZW = far field; 0 = radius, 1 = reciprocal of the PDF +int _SssSampleBudget; TEXTURE2D_X(_DepthTexture); // Z-buffer TEXTURE2D_X(_IrradianceSource); // Includes transmitted light @@ -176,7 +176,7 @@ void EvaluateSample(uint i, uint n, uint profileIndex, uint iR, uint iP, float2 r = _FilterKernels[profileIndex][i][iR]; rcpPdf = _FilterKernels[profileIndex][i][iP]; #endif - float phi = SampleDiskFibonacci(i, n).y; + float phi = SampleDiskGolden(i, n).y; // The angle 'psi' is loop-invariant. float sinPsi = sin(startAngle); @@ -432,9 +432,6 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, #endif #if SSS_RANDOM_ROTATION - // Previously, we used asuint(centerPosVS) as the seed. - // This was not temporarily stable for some reason (pattern changed every frame), - // even if both the camera and the scene were completely static. // Note that GenerateHashedRandomFloat() only uses the 23 low bits, hence the 2^24 factor. float startAngle = TWO_PI * GenerateHashedRandomFloat(uint3(pixelCoord, (uint)(centerDepth * 16777216))); #else @@ -452,23 +449,14 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, // Compute the indices used to access the individual components of the float4 of the kernel. uint iR = useNearFieldKernel ? 0 : 2; // radius uint iP = useNearFieldKernel ? 1 : 3; // rcp(pdf) - uint n = SSS_N_SAMPLES_FAR_FIELD; - - const float scale = rcp(n); - const float offset = 0.5 * rcp(n); - - float r, rcpPdf; - SampleBurleyDiffusionProfile(0 * scale + offset, d, r, rcpPdf); + uint n = (uint)_SssSampleBudget; // Accumulate filtered irradiance and bilateral weights (for renormalization). - float3 centerWeight = EvalBurleyDiffusionProfile(r, S) * rcpPdf; // Defer (* albedo) - float3 totalIrradiance = centerWeight * centerIrradiance; - float3 totalWeight = centerWeight; - - uint i; // Declare once to avoid the warning from the Unity shader compiler. + float3 centerWeight = 0; // Defer (* albedo) + float3 totalIrradiance = 0; + float3 totalWeight = 0; - UNITY_UNROLL - for (i = 1; i < n; i++) + for (uint i = 0; i < n; i++) { // Integrate over the image or tangent plane in the view space. EvaluateSample(i, n, profileIndex, iR, iP, pixelCoord + 0.5, cacheOffset, diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs index 05d85475728..9379f118f35 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs @@ -95,8 +95,8 @@ RTHandle GetSSSBufferMSAA() void InitializeSubsurfaceScattering() { // Disney SSS (compute + combine) - string kernelName = asset.currentPlatformRenderPipelineSettings.increaseSssSampleCount ? "SubsurfaceScatteringHQ" : "SubsurfaceScatteringMQ"; - string kernelNameMSAA = asset.currentPlatformRenderPipelineSettings.increaseSssSampleCount ? "SubsurfaceScatteringHQ_MSAA" : "SubsurfaceScatteringMQ_MSAA"; + string kernelName = "SubsurfaceScatteringHQ"; + string kernelNameMSAA = "SubsurfaceScatteringHQ_MSAA"; m_SubsurfaceScatteringCS = defaultResources.shaders.subsurfaceScatteringCS; m_SubsurfaceScatteringKernel = m_SubsurfaceScatteringCS.FindKernel(kernelName); m_SubsurfaceScatteringKernelMSAA = m_SubsurfaceScatteringCS.FindKernel(kernelNameMSAA); @@ -222,6 +222,7 @@ struct SubsurfaceScatteringParameters { public ComputeShader subsurfaceScatteringCS; public int subsurfaceScatteringCSKernel; + public int sampleBudget; public bool needTemporaryBuffer; public Material copyStencilForSplitLighting; public Material combineLighting; @@ -232,7 +233,6 @@ struct SubsurfaceScatteringParameters public Vector4[] worldScales; public Vector4[] shapeParams; public float[] diffusionProfileHashes; - } struct SubsurfaceScatteringResources @@ -260,6 +260,7 @@ SubsurfaceScatteringParameters PrepareSubsurfaceScatteringParameters(HDCamera hd parameters.numTilesX = ((int)hdCamera.screenSize.x + 15) / 16; parameters.numTilesY = ((int)hdCamera.screenSize.y + 15) / 16; parameters.numTilesZ = hdCamera.viewCount; + parameters.sampleBudget = hdCamera.frameSettings.sssResolvedSampleBudget; parameters.worldScales = m_SSSWorldScalesAndFilterRadii; parameters.shapeParams = m_SSSShapeParamsAndMaxScatterDists; @@ -445,6 +446,7 @@ static void RenderSubsurfaceScattering(in SubsurfaceScatteringParameters paramet cmd.SetComputeVectorArrayParam(parameters.subsurfaceScatteringCS, HDShaderIDs._WorldScalesAndFilterRadii, parameters.worldScales); cmd.SetComputeVectorArrayParam(parameters.subsurfaceScatteringCS, HDShaderIDs._ShapeParamsAndMaxScatterDists, parameters.shapeParams); cmd.SetComputeFloatParams(parameters.subsurfaceScatteringCS, HDShaderIDs._DiffusionProfileHashTable, parameters.diffusionProfileHashes); + cmd.SetComputeIntParam(parameters.subsurfaceScatteringCS, HDShaderIDs._SssSampleBudget, parameters.sampleBudget); cmd.SetComputeTextureParam(parameters.subsurfaceScatteringCS, parameters.subsurfaceScatteringCSKernel, HDShaderIDs._DepthTexture, resources.depthTexture); cmd.SetComputeTextureParam(parameters.subsurfaceScatteringCS, parameters.subsurfaceScatteringCSKernel, HDShaderIDs._IrradianceSource, resources.diffuseBuffer); 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 e13b1e9310a..37b8807ffaa 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -2532,6 +2532,9 @@ out ScriptableCullingParameters cullingParams else FrameSettings.AggregateFrameSettings(ref currentFrameSettings, camera, additionalCameraData, m_Asset, m_DefaultAsset); + // With the Frame Settings now properly set up, we can resolve the sample budget. + currentFrameSettings.sssResolvedSampleBudget = currentFrameSettings.GetResolvedSssSampleBudget(m_DefaultAsset); + // Specific pass to simply display the content of the camera buffer if users have fill it themselves (like video player) if (additionalCameraData.fullscreenPassthrough) return false; @@ -3957,7 +3960,7 @@ void ApplyDebugDisplaySettings(HDCamera hdCamera, CommandBuffer cmd) CoreUtils.SetKeyword(cmd, "DEBUG_DISPLAY", debugDisplayEnabledOrSceneLightingDisabled); // Setting this all the time due to a strange bug that either reports a (globally) bound texture as not bound or where SetGlobalTexture doesn't behave as expected. - // As a workaround we bind it regardless of debug display. Eventually with + // As a workaround we bind it regardless of debug display. Eventually with cmd.SetGlobalTexture(HDShaderIDs._DebugMatCapTexture, defaultResources.textures.matcapTex); if (debugDisplayEnabledOrSceneLightingDisabled || 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 775eb582bb2..7f5afcf04b2 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs @@ -232,6 +232,7 @@ static class HDShaderIDs public static readonly int _DiffusionProfileHashTable = Shader.PropertyToID("_DiffusionProfileHashTable"); public static readonly int _DiffusionProfileCount = Shader.PropertyToID("_DiffusionProfileCount"); public static readonly int _DiffusionProfileAsset = Shader.PropertyToID("_DiffusionProfileAsset"); + public static readonly int _SssSampleBudget = Shader.PropertyToID("_SssSampleBudget"); public static readonly int _MaterialID = Shader.PropertyToID("_MaterialID"); public static readonly int g_TileListOffset = Shader.PropertyToID("g_TileListOffset"); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.cs index 1bad98da64e..e17d49fcb7a 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.cs @@ -29,7 +29,7 @@ public enum LODBiasMode OverrideQualitySettings, } /// - /// Defines how the MaximumLOD + /// Defines how the MaximumLOD is computed. /// public enum MaximumLODLevelMode { @@ -40,6 +40,16 @@ public enum MaximumLODLevelMode /// Set the current quality settings value. OverrideQualitySettings, } + /// + /// Defines how the SssSampleBudget is computed. + /// + public enum SssQualityMode + { + /// Use a quality settings value. + FromQualitySettings, + /// Use a custom value. + OverrideQualitySettings, + } /* ////// HOW TO ADD FRAME SETTINGS ////// * @@ -213,7 +223,7 @@ public enum FrameSettingsField [FrameSettingsField(0, autoName: MaterialQualityLevel, type: FrameSettingsFieldAttribute.DisplayType.Others, tooltip: "The material quality level to use.")] MaterialQualityLevel = 66, - //lighting settings from 20 to 39 + //lighting settings: 20-39, 46-49 /// When enabled, Cameras using these Frame Settings render shadows. [FrameSettingsField(1, autoName: ShadowMaps, customOrderInGroup: 1, tooltip: "When enabled, Cameras using these Frame Settings render shadows.")] ShadowMaps = 20, @@ -232,9 +242,24 @@ public enum FrameSettingsField /// When enabled, Cameras using these Frame Settings calculate Screen Space Ambient Occlusion. [FrameSettingsField(1, displayedName: "Screen Space Ambient Occlusion", tooltip: "When enabled, Cameras using these Frame Settings calculate Screen Space Ambient Occlusion (Depends on \"Screen Space Ambient Occlusion\" in current HDRP Asset).")] SSAO = 24, + /// When enabled, Cameras using these Frame Settings render subsurface scattering (SSS) effects for GameObjects that use a SSS Material. - [FrameSettingsField(1, autoName: SubsurfaceScattering, tooltip: "When enabled, Cameras using these Frame Settings render subsurface scattering (SSS) effects for GameObjects that use a SSS Material (Depends on \"Subsurface Scattering\" in current HDRP Asset).")] - SubsurfaceScattering = 25, + [FrameSettingsField(1, customOrderInGroup: 46, autoName: SubsurfaceScattering, + tooltip: "When enabled, Cameras using these Frame Settings render subsurface scattering (SSS) effects for GameObjects that use a SSS Material (Depends on \"Subsurface Scattering\" in current HDRP Asset).")] + SubsurfaceScattering = 46, + /// Configures the sample budget of the Subsurface Scattering algorithm using Quality Levels. You can either pick from one of the existing values in the Quality Settings, or request a custom number of samples. + [FrameSettingsField(1, customOrderInGroup: 47, displayedName: "Quality Mode", positiveDependencies: new[] { SubsurfaceScattering }, type: FrameSettingsFieldAttribute.DisplayType.Others, targetType: typeof(SssQualityMode), + tooltip: "Configures the way the sample budget of the Subsurface Scattering algorithm is determined. You can either pick from one of the existing values in the Quality Settings, or request a custom number of samples.")] + SssQualityMode = 47, + /// Sets the Quality Level of the Subsurface Scattering algorithm. + [FrameSettingsField(1, customOrderInGroup: 48, displayedName: "Quality Level", positiveDependencies: new[] { SubsurfaceScattering }, type: FrameSettingsFieldAttribute.DisplayType.Others, + tooltip: "Sets the Quality Level of the Subsurface Scattering algorithm.")] + SssQualityLevel = 48, + /// Sets the custom sample budget of the Subsurface Scattering algorithm. + [FrameSettingsField(1, customOrderInGroup: 49, displayedName: "Custom Sample Budget", positiveDependencies: new[] { SubsurfaceScattering }, type: FrameSettingsFieldAttribute.DisplayType.Others, + tooltip: "Sets the custom sample budget of the Subsurface Scattering algorithm.")] + SssCustomSampleBudget = 49, + /// When enabled, Cameras using these Frame Settings render subsurface scattering (SSS) Materials with an added transmission effect (only if you enable Transmission on the SSS Material in the Material's Inspector). [FrameSettingsField(1, autoName: Transmission, tooltip: "When enabled, Cameras using these Frame Settings render subsurface scattering (SSS) Materials with an added transmission effect (only if you enable Transmission on the SSS Material in the Material's Inspector).")] Transmission = 26, @@ -525,6 +550,19 @@ partial struct FrameSettings [SerializeField] public int maximumLODLevelQualityLevel; + /// Stores SssQualityMode on disk. + [SerializeField] + public SssQualityMode sssQualityMode; + /// Stores SssQualityLevel on disk. + [SerializeField] + public int sssQualityLevel; + /// Stores SssCustomSampleBudget on disk. + [SerializeField] + public int sssCustomSampleBudget; + + /// The actual value used by the Subsurface Scattering algorithm. Updated every frame. + internal int sssResolvedSampleBudget; + /// /// The material quality level to use for this rendering. /// if materialQuality == 0, then the material quality from the current quality settings @@ -586,6 +624,22 @@ public int GetResolvedMaximumLODLevel(HDRenderPipelineAsset hdrp) } } + /// + /// Returns the sample budget of the Subsurface Scattering algorithm. + /// + /// The HDRP Asset to use. + /// The sample budget of the Subsurface Scattering algorithm. + public int GetResolvedSssSampleBudget(HDRenderPipelineAsset hdrp) + { + var source = hdrp.currentPlatformRenderPipelineSettings.sssSampleBudget; + switch (sssQualityMode) + { + case SssQualityMode.FromQualitySettings: return source[sssQualityLevel]; + case SssQualityMode.OverrideQualitySettings: return sssCustomSampleBudget; + default: throw new ArgumentOutOfRangeException(nameof(maximumLODLevelMode)); + } + } + // followings are helper for engine. internal bool fptl => litShaderMode == LitShaderMode.Deferred || bitDatas[(int)FrameSettingsField.FPTLForForwardOpaque]; internal float specularGlobalDimmer => bitDatas[(int)FrameSettingsField.DirectSpecularLighting] ? 1f : 0f; @@ -607,6 +661,12 @@ internal static void Override(ref FrameSettings overriddenFrameSettings, FrameSe overriddenFrameSettings.bitDatas = (overridingFrameSettings.bitDatas & frameSettingsOverideMask.mask) | (~frameSettingsOverideMask.mask & overriddenFrameSettings.bitDatas); //other overrides + if (frameSettingsOverideMask.mask[(uint) FrameSettingsField.SssQualityMode]) + overriddenFrameSettings.sssQualityMode = overridingFrameSettings.sssQualityMode; + if (frameSettingsOverideMask.mask[(uint) FrameSettingsField.SssQualityLevel]) + overriddenFrameSettings.sssQualityLevel = overridingFrameSettings.sssQualityLevel; + if (frameSettingsOverideMask.mask[(uint) FrameSettingsField.SssCustomSampleBudget]) + overriddenFrameSettings.sssCustomSampleBudget = overridingFrameSettings.sssCustomSampleBudget; if (frameSettingsOverideMask.mask[(uint) FrameSettingsField.LODBias]) overriddenFrameSettings.lodBias = overridingFrameSettings.lodBias; if (frameSettingsOverideMask.mask[(uint) FrameSettingsField.LODBiasMode]) @@ -738,14 +798,17 @@ internal static void AggregateFrameSettings(ref FrameSettings aggregatedFrameSet /// Second frame settings. /// True if both settings are equal. public static bool operator ==(FrameSettings a, FrameSettings b) - => a.bitDatas == b.bitDatas - && a.lodBias == b.lodBias - && a.lodBiasMode == b.lodBiasMode - && a.lodBiasQualityLevel == b.lodBiasQualityLevel - && a.maximumLODLevel == b.maximumLODLevel - && a.maximumLODLevelMode == b.maximumLODLevelMode + => a.bitDatas == b.bitDatas + && a.sssQualityMode == b.sssQualityMode + && a.sssQualityLevel == b.sssQualityLevel + && a.sssCustomSampleBudget == b.sssCustomSampleBudget + && a.lodBias == b.lodBias + && a.lodBiasMode == b.lodBiasMode + && a.lodBiasQualityLevel == b.lodBiasQualityLevel + && a.maximumLODLevel == b.maximumLODLevel + && a.maximumLODLevelMode == b.maximumLODLevelMode && a.maximumLODLevelQualityLevel == b.maximumLODLevelQualityLevel - && a.materialQuality == b.materialQuality; + && a.materialQuality == b.materialQuality; /// /// Inequality operator. @@ -753,15 +816,7 @@ internal static void AggregateFrameSettings(ref FrameSettings aggregatedFrameSet /// First frame settings. /// Second frame settings. /// True if settings are not equal. - public static bool operator !=(FrameSettings a, FrameSettings b) - => a.bitDatas != b.bitDatas - || a.lodBias != b.lodBias - || a.lodBiasMode != b.lodBiasMode - || a.lodBiasQualityLevel != b.lodBiasQualityLevel - || a.maximumLODLevel != b.maximumLODLevel - || a.maximumLODLevelMode != b.maximumLODLevelMode - || a.maximumLODLevelQualityLevel != b.maximumLODLevelQualityLevel - || a.materialQuality != b.materialQuality; + public static bool operator !=(FrameSettings a, FrameSettings b) => !(a == b); /// /// Equality operator. @@ -771,6 +826,9 @@ internal static void AggregateFrameSettings(ref FrameSettings aggregatedFrameSet public override bool Equals(object obj) => (obj is FrameSettings) && bitDatas.Equals(((FrameSettings)obj).bitDatas) + && sssQualityMode.Equals(((FrameSettings)obj).sssQualityMode) + && sssQualityLevel.Equals(((FrameSettings)obj).sssQualityLevel) + && sssCustomSampleBudget.Equals(((FrameSettings)obj).sssCustomSampleBudget) && lodBias.Equals(((FrameSettings)obj).lodBias) && lodBiasMode.Equals(((FrameSettings)obj).lodBiasMode) && lodBiasQualityLevel.Equals(((FrameSettings)obj).lodBiasQualityLevel) @@ -786,7 +844,11 @@ public override bool Equals(object obj) public override int GetHashCode() { var hashCode = 1474027755; + hashCode = hashCode * -1521134295 + bitDatas.GetHashCode(); + hashCode = hashCode * -1521134295 + sssQualityMode.GetHashCode(); + hashCode = hashCode * -1521134295 + sssQualityLevel.GetHashCode(); + hashCode = hashCode * -1521134295 + sssCustomSampleBudget.GetHashCode(); hashCode = hashCode * -1521134295 + lodBias.GetHashCode(); hashCode = hashCode * -1521134295 + lodBiasMode.GetHashCode(); hashCode = hashCode * -1521134295 + lodBiasQualityLevel.GetHashCode(); @@ -794,6 +856,7 @@ public override int GetHashCode() hashCode = hashCode * -1521134295 + maximumLODLevelMode.GetHashCode(); hashCode = hashCode * -1521134295 + maximumLODLevelQualityLevel.GetHashCode(); hashCode = hashCode * -1521134295 + materialQuality.GetHashCode(); + return hashCode; } @@ -866,6 +929,9 @@ public DebuggerGroup[] Keys groups.Add(new DebuggerGroup("Bits without attribute", noAttribute.Where(fs => fs != FrameSettingsField.None)?.Select(fs => new DebuggerEntry(Enum.GetName(typeof(FrameSettingsField), fs), m_FrameSettings.bitDatas[(uint)fs])).ToArray())); groups.Add(new DebuggerGroup("Non Bit data", new DebuggerEntry[] { + new DebuggerEntry("sssQualityMode", m_FrameSettings.sssQualityMode), + new DebuggerEntry("sssQualityLevel", m_FrameSettings.sssQualityLevel), + new DebuggerEntry("sssCustomSampleBudget", m_FrameSettings.sssCustomSampleBudget), new DebuggerEntry("lodBias", m_FrameSettings.lodBias), new DebuggerEntry("lodBiasMode", m_FrameSettings.lodBiasMode), new DebuggerEntry("lodBiasQualityLevel", m_FrameSettings.lodBiasQualityLevel), diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/RenderPipelineSettings.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/RenderPipelineSettings.cs index 6c9034cfe73..96f7b9cfce2 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/RenderPipelineSettings.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/RenderPipelineSettings.cs @@ -64,6 +64,9 @@ public enum CustomBufferFormat supportShadowMask = true, supportSSAO = true, supportSubsurfaceScattering = true, + sssSampleBudget = new IntScalableSetting(new[] { (int)DefaultSssSampleBudgetForQualityLevel.Low, + (int)DefaultSssSampleBudgetForQualityLevel.Medium, + (int)DefaultSssSampleBudgetForQualityLevel.High }, ScalableSettingSchemaId.With3Levels), supportVolumetrics = true, supportDistortion = true, supportTransparentBackface = true, @@ -122,8 +125,8 @@ public struct LightSettings public bool supportSSAO; /// Support subsurface scattering. public bool supportSubsurfaceScattering; - /// High quality subsurface scattering. - public bool increaseSssSampleCount; + /// Sample budget for the Subsurface Scattering algorithm. + public IntScalableSetting sssSampleBudget; /// Support volumetric lighting. public bool supportVolumetrics; /// High quality volumetric lighting. From 8b8222f1c450395703c41cc70f92127811b88437 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Fri, 21 Feb 2020 16:39:50 -0800 Subject: [PATCH 08/63] Clean shader --- .../SubsurfaceScattering.compute | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute index 1ebc7bf05cd..a8c186ef252 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute @@ -22,7 +22,6 @@ #define SSS_CLAMP_ARTIFACT 0 // Reduces bleeding. Use with SSS_USE_TANGENT_PLANE. #define SSS_DEBUG_LOD 0 #define SSS_DEBUG_NORMAL_VS 0 -#define SSS_SSS_ADAPTIVE_SAMPLING 1 // Do not modify these. #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl" @@ -163,31 +162,27 @@ float3 ComputeBilateralWeight(float xy2, float z, float mmPerUnit, float3 S, flo void EvaluateSample(uint i, uint n, uint profileIndex, uint iR, uint iP, float2 centerCoord, int2 cacheOffset, float3 S, float d, float3 centerPosVS, float mmPerUnit, float2 pixelsPerMm, - float startAngle, float3 tangentX, float3 tangentY, float4x4 projMatrix, + float phase, float3 tangentX, float3 tangentY, float4x4 projMatrix, inout float3 totalIrradiance, inout float3 totalWeight) { const float scale = rcp(n); - const float offset = 0.5 * rcp(n); + const float offset = rcp(n) * 0.5; + + // The phase angle is loop-invariant. + float sinPhase, cosPhase; + sincos(phase, sinPhase, cosPhase); float r, rcpPdf; -#if SSS_SSS_ADAPTIVE_SAMPLING SampleBurleyDiffusionProfile(i * scale + offset, d, r, rcpPdf); -#else - r = _FilterKernels[profileIndex][i][iR]; - rcpPdf = _FilterKernels[profileIndex][i][iP]; -#endif - float phi = SampleDiskGolden(i, n).y; - // The angle 'psi' is loop-invariant. - float sinPsi = sin(startAngle); - float cosPsi = cos(startAngle); + float phi = SampleDiskGolden(i, n).y; + float sinPhi, cosPhi; + sincos(phi, sinPhi, cosPhi); - // cos(a + b) = cos(a) * cos(b) - sin(a) * sin(b) - // sin(a + b) = sin(a) * cos(b) + cos(a) * sin(b) - float cosSum = cos(phi) * cosPsi - sin(phi) * sinPsi; - float sinSum = sin(phi) * cosPsi + cos(phi) * sinPsi; + float sinPsi = cosPhase * sinPhi + sinPhase * cosPhi; // sin(phase + phi) + float cosPsi = cosPhase * cosPhi - sinPhase * sinPhi; // cos(phase + phi) - float2 vec = r * float2(cosSum, sinSum); + float2 vec = r * float2(cosPsi, sinPsi); // Compute the screen-space position and the squared distance (in mm) in the image plane. int2 position; float xy2; @@ -433,9 +428,9 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, #if SSS_RANDOM_ROTATION // Note that GenerateHashedRandomFloat() only uses the 23 low bits, hence the 2^24 factor. - float startAngle = TWO_PI * GenerateHashedRandomFloat(uint3(pixelCoord, (uint)(centerDepth * 16777216))); + float phase = TWO_PI * GenerateHashedRandomFloat(uint3(pixelCoord, (uint)(centerDepth * 16777216))); #else - float startAngle = 0; + float phase = 0; #endif // Use more samples for SS regions larger than 5x5 pixels (rotated by 45 degrees). @@ -461,9 +456,9 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, // Integrate over the image or tangent plane in the view space. EvaluateSample(i, n, profileIndex, iR, iP, pixelCoord + 0.5, cacheOffset, S, d, centerPosVS, mmPerUnit, pixelsPerMm, - startAngle, tangentX, tangentY, projMatrix, + phase, tangentX, tangentY, projMatrix, totalIrradiance, totalWeight); } - StoreResult(pixelCoord, albedo * totalIrradiance / totalWeight); + StoreResult(pixelCoord, albedo * (totalIrradiance / totalWeight)); } From 1ce50a45f2304e4eeb54bc978bca6f77881b0102 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Fri, 21 Feb 2020 16:42:50 -0800 Subject: [PATCH 09/63] Remove 2 kernels --- .../SubsurfaceScattering.compute | 23 ++++--------------- .../SubsurfaceScatteringManager.cs | 4 ++-- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute index a8c186ef252..6cc993c89dc 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute @@ -7,10 +7,8 @@ // #pragma enable_d3d11_debug_symbols #pragma only_renderers d3d11 ps4 xboxone vulkan metal switch -#pragma kernel SubsurfaceScatteringMQ SubsurfaceScattering=SubsurfaceScatteringMQ SSS_ENABLE_NEAR_FIELD=0 -#pragma kernel SubsurfaceScatteringHQ SubsurfaceScattering=SubsurfaceScatteringHQ SSS_ENABLE_NEAR_FIELD=1 -#pragma kernel SubsurfaceScatteringMQ_MSAA SubsurfaceScattering=SubsurfaceScatteringMQ_MSAA SSS_ENABLE_NEAR_FIELD=0 ENABLE_MSAA -#pragma kernel SubsurfaceScatteringHQ_MSAA SubsurfaceScattering=SubsurfaceScatteringHQ_MSAA SSS_ENABLE_NEAR_FIELD=1 ENABLE_MSAA +#pragma kernel SubsurfaceScattering SubsurfaceScattering=SubsurfaceScattering +#pragma kernel SubsurfaceScattering_MSAA SubsurfaceScattering=SubsurfaceScattering_MSAA ENABLE_MSAA // TODO: use sharp load hoisting on PS4. @@ -160,7 +158,7 @@ float3 ComputeBilateralWeight(float xy2, float z, float mmPerUnit, float3 S, flo #endif } -void EvaluateSample(uint i, uint n, uint profileIndex, uint iR, uint iP, float2 centerCoord, int2 cacheOffset, +void EvaluateSample(uint i, uint n, uint profileIndex, float2 centerCoord, int2 cacheOffset, float3 S, float d, float3 centerPosVS, float mmPerUnit, float2 pixelsPerMm, float phase, float3 tangentX, float3 tangentY, float4x4 projMatrix, inout float3 totalIrradiance, inout float3 totalWeight) @@ -433,18 +431,7 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, float phase = 0; #endif - // Use more samples for SS regions larger than 5x5 pixels (rotated by 45 degrees). - bool useNearFieldKernel = SSS_ENABLE_NEAR_FIELD && maxDistInPixels > SSS_PIXELS_PER_SAMPLE; - -#if SSS_DEBUG_LOD - StoreResult(pixelCoord, useNearFieldKernel ? float3(1, 0, 0) : float3(0.5, 0.5, 0)); - return; -#endif - - // Compute the indices used to access the individual components of the float4 of the kernel. - uint iR = useNearFieldKernel ? 0 : 2; // radius - uint iP = useNearFieldKernel ? 1 : 3; // rcp(pdf) - uint n = (uint)_SssSampleBudget; + uint n = (uint)_SssSampleBudget; // Accumulate filtered irradiance and bilateral weights (for renormalization). float3 centerWeight = 0; // Defer (* albedo) @@ -454,7 +441,7 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, for (uint i = 0; i < n; i++) { // Integrate over the image or tangent plane in the view space. - EvaluateSample(i, n, profileIndex, iR, iP, pixelCoord + 0.5, cacheOffset, + EvaluateSample(i, n, profileIndex, pixelCoord + 0.5, cacheOffset, S, d, centerPosVS, mmPerUnit, pixelsPerMm, phase, tangentX, tangentY, projMatrix, totalIrradiance, totalWeight); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs index 9379f118f35..2215c6d26cf 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs @@ -95,8 +95,8 @@ RTHandle GetSSSBufferMSAA() void InitializeSubsurfaceScattering() { // Disney SSS (compute + combine) - string kernelName = "SubsurfaceScatteringHQ"; - string kernelNameMSAA = "SubsurfaceScatteringHQ_MSAA"; + string kernelName = "SubsurfaceScattering"; + string kernelNameMSAA = "SubsurfaceScattering_MSAA"; m_SubsurfaceScatteringCS = defaultResources.shaders.subsurfaceScatteringCS; m_SubsurfaceScatteringKernel = m_SubsurfaceScatteringCS.FindKernel(kernelName); m_SubsurfaceScatteringKernelMSAA = m_SubsurfaceScatteringCS.FindKernel(kernelNameMSAA); From 9e33e3f35a5b6a6d5aaeffc73442daa66f05887b Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Fri, 21 Feb 2020 17:04:18 -0800 Subject: [PATCH 10/63] PURGE --- .../Runtime/Lighting/SurfaceShading.hlsl | 2 +- .../DiffusionProfileSettings.cs | 24 +++++++++---------- .../DiffusionProfileSettings.cs.hlsl | 2 -- .../ShaderVariablesSubsurfaceScattering.cs | 4 +--- ...haderVariablesSubsurfaceScattering.cs.hlsl | 3 +-- .../SubsurfaceScattering.compute | 4 ++-- .../SubsurfaceScattering.hlsl | 7 +++--- .../SubsurfaceScatteringManager.cs | 24 ++++++++----------- .../RenderPipeline/HDStringConstants.cs | 3 +-- 9 files changed, 31 insertions(+), 42 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/SurfaceShading.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Lighting/SurfaceShading.hlsl index e71b3adeac8..034c177433f 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/SurfaceShading.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/SurfaceShading.hlsl @@ -132,7 +132,7 @@ float3 EvaluateTransmittance_Punctual(LightLoopContext lightLoopContext, // Note: based on the artist's input, dependence on the NdotL has been disabled. float distFrontFaceToLight = distances.x; float thicknessInUnits = (distFrontFaceToLight - distBackFaceToLight) /* * -NdotL */; - float metersPerUnit = _WorldScalesAndFilterRadii[bsdfData.diffusionProfileIndex].x; + float metersPerUnit = _WorldScalesAndFilterRadiiAndThicknessRemaps[bsdfData.diffusionProfileIndex].x; float thicknessInMeters = thicknessInUnits * metersPerUnit; float thicknessInMillimeters = thicknessInMeters * MILLIMETERS_PER_METER; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs index 3ad73c6fb29..80b3d8840dc 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs @@ -7,8 +7,6 @@ class DiffusionProfileConstants { public const int DIFFUSION_PROFILE_COUNT = 16; // Max. number of profiles, including the slot taken by the neutral profile public const int DIFFUSION_PROFILE_NEUTRAL_ID = 0; // Does not result in blurring - public const int SSS_N_SAMPLES_NEAR_FIELD = 55; // Used for extreme close ups; must be a Fibonacci number - public const int SSS_N_SAMPLES_FAR_FIELD = 21; // Used at a regular distance; must be a Fibonacci number public const int SSS_PIXELS_PER_SAMPLE = 4; } @@ -193,11 +191,10 @@ internal partial class DiffusionProfileSettings : ScriptableObject [SerializeField] internal DiffusionProfile profile; - [NonSerialized] internal Vector4 thicknessRemap; // Remap: 0 = start, 1 = end - start - [NonSerialized] internal Vector4 worldScalesAndFilterRadii; // X = meters per world unit, Y = filter radius (in mm) - [NonSerialized] internal Vector4 shapeParamAndMaxScatterDist; // RGB = S = 1 / D, A = d = RgbMax(D) - [NonSerialized] internal Vector4 transmissionTintAndFresnel0; // RGB = color, A = fresnel0 - [NonSerialized] internal Vector4 disabledTransmissionTintAndFresnel0; // RGB = black, A = fresnel0 - For debug to remove the transmission + [NonSerialized] internal Vector4 worldScaleAndFilterRadiusAndThicknessRemap; // X = meters per world unit, Y = filter radius (in mm), Z = remap start, W = end - start + [NonSerialized] internal Vector4 shapeParamAndMaxScatterDist; // RGB = S = 1 / D, A = d = RgbMax(D) + [NonSerialized] internal Vector4 transmissionTintAndFresnel0; // RGB = color, A = fresnel0 + [NonSerialized] internal Vector4 disabledTransmissionTintAndFresnel0; // RGB = black, A = fresnel0 - For debug to remove the transmission [NonSerialized] internal int updateCount; void OnEnable() @@ -224,9 +221,10 @@ void OnEnable() internal void UpdateCache() { - thicknessRemap = new Vector4(profile.thicknessRemap.x, profile.thicknessRemap.y - profile.thicknessRemap.x, 0, 0); - worldScalesAndFilterRadii = new Vector4(profile.worldScale, profile.filterRadius, 0, 0); - + worldScaleAndFilterRadiusAndThicknessRemap = new Vector4(profile.worldScale, + profile.filterRadius, + profile.thicknessRemap.x, + profile.thicknessRemap.y - profile.thicknessRemap.x); shapeParamAndMaxScatterDist = profile.shapeParam; shapeParamAndMaxScatterDist.w = profile.maxScatteringDistance; // Convert ior to fresnel0 @@ -248,9 +246,9 @@ internal bool HasChanged(int update) /// public void SetDefaultParams() { - worldScalesAndFilterRadii = new Vector4(1, 0, 0, 0); - shapeParamAndMaxScatterDist = new Vector4(16777216, 16777216, 16777216, 0); - transmissionTintAndFresnel0.w = 0.04f; // Match DEFAULT_SPECULAR_VALUE defined in Lit.hlsl + worldScaleAndFilterRadiusAndThicknessRemap = new Vector4(1, 0, 0, 1); + shapeParamAndMaxScatterDist = new Vector4(16777216, 16777216, 16777216, 0); + transmissionTintAndFresnel0.w = 0.04f; // Match DEFAULT_SPECULAR_VALUE defined in Lit.hlsl } } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs.hlsl index 2b411fed5d0..fddf55f7a99 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs.hlsl @@ -9,8 +9,6 @@ // #define DIFFUSION_PROFILE_COUNT (16) #define DIFFUSION_PROFILE_NEUTRAL_ID (0) -#define SSS_N_SAMPLES_NEAR_FIELD (55) -#define SSS_N_SAMPLES_FAR_FIELD (21) #define SSS_PIXELS_PER_SAMPLE (4) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs index 309fc6247e9..e6f06399867 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs @@ -5,13 +5,11 @@ unsafe struct ShaderVariablesSubsurfaceScattering { // Use float4 to avoid any packing issue between compute and pixel shaders [HLSLArray(DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT, typeof(Vector4))] - public fixed float _ThicknessRemaps[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT * 4]; // Remap: X = start, Y = end - start - [HLSLArray(DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT, typeof(Vector4))] public fixed float _ShapeParamsAndMaxScatterDists[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT * 4]; // RGB = S = 1 / D, A = d = RgbMax(D) [HLSLArray(DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT, typeof(Vector4))] public fixed float _TransmissionTintsAndFresnel0[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT * 4]; // RGB = 1/4 * color, A = fresnel0 [HLSLArray(DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT, typeof(Vector4))] - public fixed float _WorldScalesAndFilterRadii[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT * 4]; // X = meters per world unit, Y = filter radius (in mm) + public fixed float _WorldScalesAndFilterRadiiAndThicknessRemaps[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT * 4]; // X = meters per world unit, Y = filter radius (in mm) [HLSLArray(DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT, typeof(float))] public fixed uint _DiffusionProfileHashTable[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; // TODO: constant diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs.hlsl index 78f66ef71ae..0ae20a63813 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs.hlsl @@ -6,10 +6,9 @@ #define SHADERVARIABLESSUBSURFACESCATTERING_CS_HLSL // Generated from UnityEngine.Rendering.HighDefinition.ShaderVariablesSubsurfaceScattering // PackingRules = Exact - float4 _ThicknessRemaps[16]; float4 _ShapeParamsAndMaxScatterDists[16]; float4 _TransmissionTintsAndFresnel0[16]; - float4 _WorldScalesAndFilterRadii[16]; + float4 _WorldScalesAndFilterRadiiAndThicknessRemaps[16]; float _DiffusionProfileHashTable[16]; uint _EnableSubsurfaceScattering; float _TexturingModeFlags; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute index 6cc993c89dc..bfb349da0c5 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute @@ -358,8 +358,8 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, float distScale = sssData.subsurfaceMask; float3 S = _ShapeParamsAndMaxScatterDists[profileIndex].rgb; float d = _ShapeParamsAndMaxScatterDists[profileIndex].a; - float metersPerUnit = _WorldScalesAndFilterRadii[profileIndex].x; - float filterRadius = _WorldScalesAndFilterRadii[profileIndex].y; // In millimeters + float metersPerUnit = _WorldScalesAndFilterRadiiAndThicknessRemaps[profileIndex].x; + float filterRadius = _WorldScalesAndFilterRadiiAndThicknessRemaps[profileIndex].y; // In millimeters // Reconstruct the view-space position corresponding to the central sample. float2 centerPosNDC = posInput.positionNDC; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.hlsl index 36357878d96..f4632c21e6e 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.hlsl @@ -190,10 +190,11 @@ float3 GetModifiedDiffuseColorForSSS(BSDFData bsdfData) // Assume that bsdfData.diffusionProfileIndex is init void FillMaterialTransmission(uint diffusionProfileIndex, float thickness, inout BSDFData bsdfData) { - bsdfData.diffusionProfileIndex = diffusionProfileIndex; - bsdfData.fresnel0 = _TransmissionTintsAndFresnel0[diffusionProfileIndex].a; + float2 remap = _WorldScalesAndFilterRadiiAndThicknessRemaps[diffusionProfileIndex].zw; - bsdfData.thickness = _ThicknessRemaps[diffusionProfileIndex].x + _ThicknessRemaps[diffusionProfileIndex].y * thickness; + bsdfData.diffusionProfileIndex = diffusionProfileIndex; + bsdfData.fresnel0 = _TransmissionTintsAndFresnel0[diffusionProfileIndex].a; + bsdfData.thickness = remap.x + remap.y * thickness; // The difference between the thin and the regular (a.k.a. auto-thickness) modes is the following: // * in the thin object mode, we assume that the geometry is thin enough for us to safely share diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs index 2215c6d26cf..872ec3f4817 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs @@ -23,11 +23,10 @@ public partial class HDRenderPipeline Material m_SSSCopyStencilForSplitLighting; // List of every diffusion profile data we need - Vector4[] m_SSSThicknessRemaps; Vector4[] m_SSSShapeParamsAndMaxScatterDists; Vector4[] m_SSSTransmissionTintsAndFresnel0; Vector4[] m_SSSDisabledTransmissionTintsAndFresnel0; - Vector4[] m_SSSWorldScalesAndFilterRadii; + Vector4[] m_SSSWorldScalesAndFilterRadiiAndThicknessRemaps; float[] m_SSSDiffusionProfileHashes; int[] m_SSSDiffusionProfileUpdate; DiffusionProfileSettings[] m_SSSSetDiffusionProfiles; @@ -72,11 +71,10 @@ void InitSSSBuffers() // fill the list with the max number of diffusion profile so we dont have // the error: exceeds previous array size (5 vs 3). Cap to previous size. - m_SSSThicknessRemaps = new Vector4[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; m_SSSShapeParamsAndMaxScatterDists = new Vector4[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; m_SSSTransmissionTintsAndFresnel0 = new Vector4[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; m_SSSDisabledTransmissionTintsAndFresnel0 = new Vector4[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; - m_SSSWorldScalesAndFilterRadii = new Vector4[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; + m_SSSWorldScalesAndFilterRadiiAndThicknessRemaps = new Vector4[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; m_SSSDiffusionProfileHashes = new float[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; m_SSSDiffusionProfileUpdate = new int[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; m_SSSSetDiffusionProfiles = new DiffusionProfileSettings[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; @@ -160,12 +158,11 @@ void SetDiffusionProfileAtIndex(DiffusionProfileSettings settings, int index) if (settings.profile.hash == 0) return; - m_SSSThicknessRemaps[index] = settings.thicknessRemap; - m_SSSShapeParamsAndMaxScatterDists[index] = settings.shapeParamAndMaxScatterDist; - m_SSSTransmissionTintsAndFresnel0[index] = settings.transmissionTintAndFresnel0; - m_SSSDisabledTransmissionTintsAndFresnel0[index] = settings.disabledTransmissionTintAndFresnel0; - m_SSSWorldScalesAndFilterRadii[index] = settings.worldScalesAndFilterRadii; - m_SSSDiffusionProfileHashes[index] = HDShadowUtils.Asfloat(settings.profile.hash); // HDShadowUtils ?.. + m_SSSShapeParamsAndMaxScatterDists[index] = settings.shapeParamAndMaxScatterDist; + m_SSSTransmissionTintsAndFresnel0[index] = settings.transmissionTintAndFresnel0; + m_SSSDisabledTransmissionTintsAndFresnel0[index] = settings.disabledTransmissionTintAndFresnel0; + m_SSSWorldScalesAndFilterRadiiAndThicknessRemaps[index] = settings.worldScaleAndFilterRadiusAndThicknessRemap; + m_SSSDiffusionProfileHashes[index] = HDShadowUtils.Asfloat(settings.profile.hash); // HDShadowUtils ?.. // Erase previous value (This need to be done here individually as in the SSS editor we edit individual component) uint mask = 1u << index; @@ -199,11 +196,10 @@ void PushSubsurfaceScatteringGlobalParams(HDCamera hdCamera, CommandBuffer cmd) cmd.SetGlobalFloat(HDShaderIDs._TexturingModeFlags, *(float*)&texturingModeFlags); cmd.SetGlobalFloat(HDShaderIDs._TransmissionFlags, *(float*)&transmissionFlags); } - cmd.SetGlobalVectorArray(HDShaderIDs._ThicknessRemaps, m_SSSThicknessRemaps); cmd.SetGlobalVectorArray(HDShaderIDs._ShapeParamsAndMaxScatterDists, m_SSSShapeParamsAndMaxScatterDists); // To disable transmission, we simply nullify the transmissionTint cmd.SetGlobalVectorArray(HDShaderIDs._TransmissionTintsAndFresnel0, hdCamera.frameSettings.IsEnabled(FrameSettingsField.Transmission) ? m_SSSTransmissionTintsAndFresnel0 : m_SSSDisabledTransmissionTintsAndFresnel0); - cmd.SetGlobalVectorArray(HDShaderIDs._WorldScalesAndFilterRadii, m_SSSWorldScalesAndFilterRadii); + cmd.SetGlobalVectorArray(HDShaderIDs._WorldScalesAndFilterRadiiAndThicknessRemaps, m_SSSWorldScalesAndFilterRadiiAndThicknessRemaps); cmd.SetGlobalFloatArray(HDShaderIDs._DiffusionProfileHashTable, m_SSSDiffusionProfileHashes); } @@ -262,7 +258,7 @@ SubsurfaceScatteringParameters PrepareSubsurfaceScatteringParameters(HDCamera hd parameters.numTilesZ = hdCamera.viewCount; parameters.sampleBudget = hdCamera.frameSettings.sssResolvedSampleBudget; - parameters.worldScales = m_SSSWorldScalesAndFilterRadii; + parameters.worldScales = m_SSSWorldScalesAndFilterRadiiAndThicknessRemaps; parameters.shapeParams = m_SSSShapeParamsAndMaxScatterDists; parameters.diffusionProfileHashes = m_SSSDiffusionProfileHashes; @@ -443,7 +439,7 @@ static void RenderSubsurfaceScattering(in SubsurfaceScatteringParameters paramet cmd.SetComputeFloatParam(parameters.subsurfaceScatteringCS, HDShaderIDs._TexturingModeFlags, *(float*)&textureingModeFlags); } - cmd.SetComputeVectorArrayParam(parameters.subsurfaceScatteringCS, HDShaderIDs._WorldScalesAndFilterRadii, parameters.worldScales); + cmd.SetComputeVectorArrayParam(parameters.subsurfaceScatteringCS, HDShaderIDs._WorldScalesAndFilterRadiiAndThicknessRemaps, parameters.worldScales); cmd.SetComputeVectorArrayParam(parameters.subsurfaceScatteringCS, HDShaderIDs._ShapeParamsAndMaxScatterDists, parameters.shapeParams); cmd.SetComputeFloatParams(parameters.subsurfaceScatteringCS, HDShaderIDs._DiffusionProfileHashTable, parameters.diffusionProfileHashes); cmd.SetComputeIntParam(parameters.subsurfaceScatteringCS, HDShaderIDs._SssSampleBudget, parameters.sampleBudget); 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 7f5afcf04b2..b263555201e 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs @@ -224,7 +224,6 @@ static class HDShaderIDs public static readonly int _TransmittanceMultiplier = Shader.PropertyToID("_TransmittanceMultiplier"); public static readonly int _TexturingModeFlags = Shader.PropertyToID("_TexturingModeFlags"); public static readonly int _TransmissionFlags = Shader.PropertyToID("_TransmissionFlags"); - public static readonly int _ThicknessRemaps = Shader.PropertyToID("_ThicknessRemaps"); public static readonly int _ShapeParamsAndMaxScatterDists = Shader.PropertyToID("_ShapeParamsAndMaxScatterDists"); public static readonly int _TransmissionTintsAndFresnel0 = Shader.PropertyToID("_TransmissionTintsAndFresnel0"); public static readonly int specularLightingUAV = Shader.PropertyToID("specularLightingUAV"); @@ -434,7 +433,7 @@ static class HDShaderIDs public static readonly int _BlitPaddingSize = Shader.PropertyToID("_BlitPaddingSize"); public static readonly int _BlitTexArraySlice = Shader.PropertyToID("_BlitTexArraySlice"); - public static readonly int _WorldScalesAndFilterRadii = Shader.PropertyToID("_WorldScalesAndFilterRadii"); + public static readonly int _WorldScalesAndFilterRadiiAndThicknessRemaps = Shader.PropertyToID("_WorldScalesAndFilterRadiiAndThicknessRemaps"); public static readonly int _CameraDepthTexture = Shader.PropertyToID("_CameraDepthTexture"); public static readonly int _CameraMotionVectorsTexture = Shader.PropertyToID("_CameraMotionVectorsTexture"); From 294d09a13bcec1fc134320ad99fbd9cee6c9a267 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Fri, 21 Feb 2020 17:38:34 -0800 Subject: [PATCH 11/63] Automatically adjust the number of samples at runtime --- .../DiffusionProfileSettings.cs | 6 ++- .../SubsurfaceScattering.compute | 43 +++++++++++-------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs index 80b3d8840dc..758232c7af9 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs @@ -82,8 +82,10 @@ void UpdateKernel() Mathf.Min(16777216, 1.0f / sd.y), Mathf.Min(16777216, 1.0f / sd.z)); - int n = DiffusionProfileConstants.SSS_N_SAMPLES_FAR_FIELD; // TODO - float p = ((n - 1) + 0.5f) * (1.0f / n); // Last sample + // TODO: should use the value from FrameSettings, but it's not available. :-( + // Is this a serious problem in practice? Maybe! I don't know! + int n = (int)DefaultSssSampleBudgetForQualityLevel.High; + float p = ((n - 1) + 0.5f) * (1.0f / n); // Last sample // Importance sample the normalized diffuse reflectance profile for the computed value of 's'. // ------------------------------------------------------------------------------------ diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute index bfb349da0c5..a0925e03d3d 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute @@ -14,12 +14,12 @@ // Tweak parameters. #define SSS_BILATERAL_FILTER 1 -#define SSS_USE_LDS_CACHE 1 +#define SSS_USE_LDS_CACHE 1 // Use LDS as an L0 texture cache. #define SSS_RANDOM_ROTATION 1 // Hides undersampling artifacts with high-frequency noise. TAA blurs the noise. #define SSS_USE_TANGENT_PLANE 0 // Improves the accuracy of the approximation(0 -> 1st order). High cost. Does not work with back-facing normals. #define SSS_CLAMP_ARTIFACT 0 // Reduces bleeding. Use with SSS_USE_TANGENT_PLANE. -#define SSS_DEBUG_LOD 0 -#define SSS_DEBUG_NORMAL_VS 0 +#define SSS_DEBUG_LOD 0 // Displays the sampling rate: green = no filtering, blue = 1 sample, red = _SssSampleBudget samples. +#define SSS_DEBUG_NORMAL_VS 0 // Allows detection of back-facing normals. // Do not modify these. #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl" @@ -163,6 +163,7 @@ void EvaluateSample(uint i, uint n, uint profileIndex, float2 centerCoord, int2 float phase, float3 tangentX, float3 tangentY, float4x4 projMatrix, inout float3 totalIrradiance, inout float3 totalWeight) { + // The sample count is loop-invariant. const float scale = rcp(n); const float offset = rcp(n) * 0.5; @@ -375,28 +376,32 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, float2 unitsPerPixel = 2 * abs(cornerPosVS.xy - centerPosVS.xy); float2 pixelsPerMm = rcp(unitsPerPixel) * unitsPerMm; - // We perform point sampling. Therefore, we can avoid the cost - // of filtering if we stay within the bounds of the current pixel. - // We use the value of 1 instead of 0.5 as an optimization. - // N.b.: our LoD selection algorithm is the same regardless of - // whether we integrate over the tangent plane or not, since we - // don't want the orientation of the tangent plane to create - // divergence of execution across the warp. - float maxDistInPixels = filterRadius * max(pixelsPerMm.x, pixelsPerMm.y); + // Area of an ellipse. + float filterArea = PI * Sq(filterRadius) * (pixelsPerMm.x * pixelsPerMm.y); + uint sampleCount = (uint)(filterArea * rcp(SSS_PIXELS_PER_SAMPLE)); + uint sampleBudget = (uint)_SssSampleBudget; uint texturingMode = GetSubsurfaceScatteringTexturingMode(profileIndex); float3 albedo = ApplySubsurfaceScatteringTexturingMode(texturingMode, sssData.diffuseColor); - UNITY_BRANCH if (distScale == 0 || maxDistInPixels < 1) + UNITY_BRANCH if (distScale == 0 || sampleCount < 1) { - #if SSS_DEBUG_LOD - StoreResult(pixelCoord, float3(0, 0, 1)); - #else - StoreResult(pixelCoord, albedo * centerIrradiance); - #endif - return; + #if SSS_DEBUG_LOD + float3 green = float3(0, 1, 0); + StoreResult(pixelCoord, green); + #else + StoreResult(pixelCoord, albedo * centerIrradiance); + #endif + return; } +#if SSS_DEBUG_LOD + float3 red = float3(1, 0, 0); + float3 blue = float3(0, 0, 1); + StoreResult(pixelCoord, lerp(blue, red, saturate(sampleCount * rcp(sampleBudget)))); + return; +#endif + float4x4 viewMatrix, projMatrix; GetLeftHandedViewSpaceMatrices(viewMatrix, projMatrix); @@ -431,7 +436,7 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, float phase = 0; #endif - uint n = (uint)_SssSampleBudget; + uint n = min(sampleCount, sampleBudget); // Accumulate filtered irradiance and bilateral weights (for renormalization). float3 centerWeight = 0; // Defer (* albedo) From d1bec8f99610ebbafbaf03993da1df13b5f91fa1 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Fri, 21 Feb 2020 17:42:28 -0800 Subject: [PATCH 12/63] Changelog --- com.unity.render-pipelines.high-definition/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index ad4590227f9..43ada70a274 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -69,6 +69,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Added path tracing support for refraction and internal reflections. - Added support for Thin Refraction Model and Lit's Clear Coat in Path Tracing. - Added the Tint parameter to Sky Colored Fog. +- Added support for Quality Levels to Subsurface Scattering. ### Fixed - Update documentation of HDRISky-Backplate, precise how to have Ambient Occlusion on the Backplate @@ -491,6 +492,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Transform result from CIE XYZ to sRGB color space in EvalSensitivity for iridescence. - Hide the Probes section in the Renderer editos because it was unused. - Moved BeginCameraRendering callback right before culling. +- Replaced "High Quality" Subsurface Scattering with a set of Quality Levels. ## [7.1.1] - 2019-09-05 From a69c046cec3f024dc10b5d68c9a067c4e36af3d3 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Fri, 21 Feb 2020 17:50:10 -0800 Subject: [PATCH 13/63] Spaaaaace --- .../Material/DiffusionProfile/DrawDiffusionProfile.shader | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DrawDiffusionProfile.shader b/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DrawDiffusionProfile.shader index 0c44c124a16..e32f81d8b22 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DrawDiffusionProfile.shader +++ b/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DrawDiffusionProfile.shader @@ -24,7 +24,7 @@ Shader "Hidden/HDRP/DrawDiffusionProfile" #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/DiffusionProfile/DiffusionProfile.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfile.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/EditorShaderVariables.hlsl" //------------------------------------------------------------------------------------- From d2c4ddc5b0fd79b8c02144d207139b68123c154c Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Fri, 21 Feb 2020 18:05:45 -0800 Subject: [PATCH 14/63] Add comment --- .../SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs index e6f06399867..855a4495a20 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/ShaderVariablesSubsurfaceScattering.cs @@ -9,7 +9,7 @@ unsafe struct ShaderVariablesSubsurfaceScattering [HLSLArray(DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT, typeof(Vector4))] public fixed float _TransmissionTintsAndFresnel0[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT * 4]; // RGB = 1/4 * color, A = fresnel0 [HLSLArray(DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT, typeof(Vector4))] - public fixed float _WorldScalesAndFilterRadiiAndThicknessRemaps[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT * 4]; // X = meters per world unit, Y = filter radius (in mm) + public fixed float _WorldScalesAndFilterRadiiAndThicknessRemaps[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT * 4]; // X = meters per world unit, Y = filter radius (in mm), Z = remap start, W = end - start [HLSLArray(DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT, typeof(float))] public fixed uint _DiffusionProfileHashTable[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; // TODO: constant From ee8ff7c4a492bd5d86d38cc9a33ff2b690bb067a Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Fri, 21 Feb 2020 18:06:30 -0800 Subject: [PATCH 15/63] Spaaaaaace --- .../SubsurfaceScattering.compute | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute index a0925e03d3d..a683ce01fa8 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute @@ -13,13 +13,13 @@ // TODO: use sharp load hoisting on PS4. // Tweak parameters. -#define SSS_BILATERAL_FILTER 1 -#define SSS_USE_LDS_CACHE 1 // Use LDS as an L0 texture cache. -#define SSS_RANDOM_ROTATION 1 // Hides undersampling artifacts with high-frequency noise. TAA blurs the noise. -#define SSS_USE_TANGENT_PLANE 0 // Improves the accuracy of the approximation(0 -> 1st order). High cost. Does not work with back-facing normals. -#define SSS_CLAMP_ARTIFACT 0 // Reduces bleeding. Use with SSS_USE_TANGENT_PLANE. -#define SSS_DEBUG_LOD 0 // Displays the sampling rate: green = no filtering, blue = 1 sample, red = _SssSampleBudget samples. -#define SSS_DEBUG_NORMAL_VS 0 // Allows detection of back-facing normals. +#define SSS_BILATERAL_FILTER 1 +#define SSS_USE_LDS_CACHE 1 // Use LDS as an L0 texture cache. +#define SSS_RANDOM_ROTATION 1 // Hides undersampling artifacts with high-frequency noise. TAA blurs the noise. +#define SSS_USE_TANGENT_PLANE 0 // Improves the accuracy of the approximation(0 -> 1st order). High cost. Does not work with back-facing normals. +#define SSS_CLAMP_ARTIFACT 0 // Reduces bleeding. Use with SSS_USE_TANGENT_PLANE. +#define SSS_DEBUG_LOD 0 // Displays the sampling rate: green = no filtering, blue = 1 sample, red = _SssSampleBudget samples. +#define SSS_DEBUG_NORMAL_VS 0 // Allows detection of back-facing normals. // Do not modify these. #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl" @@ -178,8 +178,8 @@ void EvaluateSample(uint i, uint n, uint profileIndex, float2 centerCoord, int2 float sinPhi, cosPhi; sincos(phi, sinPhi, cosPhi); - float sinPsi = cosPhase * sinPhi + sinPhase * cosPhi; // sin(phase + phi) - float cosPsi = cosPhase * cosPhi - sinPhase * sinPhi; // cos(phase + phi) + float sinPsi = cosPhase * sinPhi + sinPhase * cosPhi; // sin(phase + phi) + float cosPsi = cosPhase * cosPhi - sinPhase * sinPhi; // cos(phase + phi) float2 vec = r * float2(cosPsi, sinPsi); From e74aaf8b612cf9406b46b9f4886430aa6a42200c Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Fri, 21 Feb 2020 18:11:26 -0800 Subject: [PATCH 16/63] Rename --- .../SubsurfaceScatteringManager.cs | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs index 872ec3f4817..588412fe304 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs @@ -216,19 +216,19 @@ static bool NeedTemporarySubsurfaceBuffer() struct SubsurfaceScatteringParameters { - public ComputeShader subsurfaceScatteringCS; - public int subsurfaceScatteringCSKernel; - public int sampleBudget; - public bool needTemporaryBuffer; - public Material copyStencilForSplitLighting; - public Material combineLighting; - public uint texturingModeFlags; - public int numTilesX; - public int numTilesY; - public int numTilesZ; - public Vector4[] worldScales; - public Vector4[] shapeParams; - public float[] diffusionProfileHashes; + public ComputeShader subsurfaceScatteringCS; + public int subsurfaceScatteringCSKernel; + public int sampleBudget; + public bool needTemporaryBuffer; + public Material copyStencilForSplitLighting; + public Material combineLighting; + public uint texturingModeFlags; + public int numTilesX; + public int numTilesY; + public int numTilesZ; + public Vector4[] worldScalesAndFilterRadiiAndThicknessRemaps; + public Vector4[] shapeParamsAndMaxScatterDists; + public float[] diffusionProfileHashes; } struct SubsurfaceScatteringResources @@ -258,8 +258,8 @@ SubsurfaceScatteringParameters PrepareSubsurfaceScatteringParameters(HDCamera hd parameters.numTilesZ = hdCamera.viewCount; parameters.sampleBudget = hdCamera.frameSettings.sssResolvedSampleBudget; - parameters.worldScales = m_SSSWorldScalesAndFilterRadiiAndThicknessRemaps; - parameters.shapeParams = m_SSSShapeParamsAndMaxScatterDists; + parameters.worldScalesAndFilterRadiiAndThicknessRemaps = m_SSSWorldScalesAndFilterRadiiAndThicknessRemaps; + parameters.shapeParamsAndMaxScatterDists = m_SSSShapeParamsAndMaxScatterDists; parameters.diffusionProfileHashes = m_SSSDiffusionProfileHashes; return parameters; @@ -439,8 +439,8 @@ static void RenderSubsurfaceScattering(in SubsurfaceScatteringParameters paramet cmd.SetComputeFloatParam(parameters.subsurfaceScatteringCS, HDShaderIDs._TexturingModeFlags, *(float*)&textureingModeFlags); } - cmd.SetComputeVectorArrayParam(parameters.subsurfaceScatteringCS, HDShaderIDs._WorldScalesAndFilterRadiiAndThicknessRemaps, parameters.worldScales); - cmd.SetComputeVectorArrayParam(parameters.subsurfaceScatteringCS, HDShaderIDs._ShapeParamsAndMaxScatterDists, parameters.shapeParams); + cmd.SetComputeVectorArrayParam(parameters.subsurfaceScatteringCS, HDShaderIDs._WorldScalesAndFilterRadiiAndThicknessRemaps, parameters.worldScalesAndFilterRadiiAndThicknessRemaps); + cmd.SetComputeVectorArrayParam(parameters.subsurfaceScatteringCS, HDShaderIDs._ShapeParamsAndMaxScatterDists, parameters.shapeParamsAndMaxScatterDists); cmd.SetComputeFloatParams(parameters.subsurfaceScatteringCS, HDShaderIDs._DiffusionProfileHashTable, parameters.diffusionProfileHashes); cmd.SetComputeIntParam(parameters.subsurfaceScatteringCS, HDShaderIDs._SssSampleBudget, parameters.sampleBudget); From f119b58cf332c3b1eb6fe3d97fca13b5648f6c29 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Fri, 21 Feb 2020 18:30:19 -0800 Subject: [PATCH 17/63] Update ref img 1215, 1216, 1217 --- .../Direct3D11/1215_Lit_SubSurfaceScattering.png | 4 ++-- .../WindowsPlayer/Direct3D11/1216_Lit_SSS_MaxRadius.png | 4 ++-- .../Linear/WindowsPlayer/Direct3D11/1217_Lit_SSS_Pre-Post.png | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1215_Lit_SubSurfaceScattering.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1215_Lit_SubSurfaceScattering.png index 457fb621840..ea70334ca4c 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1215_Lit_SubSurfaceScattering.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1215_Lit_SubSurfaceScattering.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8476a17fe47590387459f9d43936da195650fbb0b757750dfc1b5bb6420be748 -size 79160 +oid sha256:be148ed922104444adfbc8cf8026ada7b546b78c6941e04dff918f35f2d5dc81 +size 91196 diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1216_Lit_SSS_MaxRadius.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1216_Lit_SSS_MaxRadius.png index fc492838228..288676b1b01 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1216_Lit_SSS_MaxRadius.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1216_Lit_SSS_MaxRadius.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dc5672fc95bb6720e025d8e7a0a7f00175b8c41a306d7ff7b35d10d5b478acc4 -size 118451 +oid sha256:588cfb2cfd2ee1be05f581e2813649a0515d3cea34ddd4ab360337d3bb95636a +size 105092 diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1217_Lit_SSS_Pre-Post.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1217_Lit_SSS_Pre-Post.png index 574ed3e1449..44c97b4a879 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1217_Lit_SSS_Pre-Post.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1217_Lit_SSS_Pre-Post.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:09c578b241d26ed3a1a647c813e03f3f6db5de18bd2ef2863785ec0fa230a93f -size 349363 +oid sha256:4ff91a6015d0ddc296c049942c6da17c2f6215c482c576f022c741ba92b62f02 +size 288282 From 787c06a329afe6bd19bf03cda7665650bd87c118 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Fri, 21 Feb 2020 18:33:24 -0800 Subject: [PATCH 18/63] Revert "Update ref img 1215, 1216, 1217" This reverts commit 9aeb1fee054bc0e8a24b76525eb4af5dc2316088. --- .../Direct3D11/1215_Lit_SubSurfaceScattering.png | 4 ++-- .../Direct3D11/1215_Lit_SubSurfaceScattering.png.meta | 4 +++- .../WindowsEditor/Direct3D11/1216_Lit_SSS_MaxRadius.png | 4 ++-- .../Direct3D11/1216_Lit_SSS_MaxRadius.png.meta | 6 ++++-- .../WindowsEditor/Direct3D11/1217_Lit_SSS_Pre-Post.png | 4 ++-- .../WindowsEditor/Direct3D11/1217_Lit_SSS_Pre-Post.png.meta | 4 +++- .../Direct3D11/1215_Lit_SubSurfaceScattering.png | 4 ++-- .../WindowsPlayer/Direct3D11/1216_Lit_SSS_MaxRadius.png | 4 ++-- .../WindowsPlayer/Direct3D11/1217_Lit_SSS_Pre-Post.png | 4 ++-- 9 files changed, 22 insertions(+), 16 deletions(-) diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1215_Lit_SubSurfaceScattering.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1215_Lit_SubSurfaceScattering.png index ea2a523156b..ea70334ca4c 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1215_Lit_SubSurfaceScattering.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1215_Lit_SubSurfaceScattering.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c64100f3f8b7003357fc5367fc60be7a51aeaf22313000cb1f00138a82d93eb3 -size 91450 +oid sha256:be148ed922104444adfbc8cf8026ada7b546b78c6941e04dff918f35f2d5dc81 +size 91196 diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1215_Lit_SubSurfaceScattering.png.meta b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1215_Lit_SubSurfaceScattering.png.meta index 111097988d4..4a351f34369 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1215_Lit_SubSurfaceScattering.png.meta +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1215_Lit_SubSurfaceScattering.png.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 402600e619eec3e41b39cc9b4af7cd70 +guid: 22413fc8a9c75b14a86f46a73590cdf1 TextureImporter: internalIDToNameTable: [] externalObjects: {} @@ -23,6 +23,7 @@ TextureImporter: isReadable: 1 streamingMipmaps: 0 streamingMipmapsPriority: 0 + vTOnly: 0 grayScaleToAlpha: 0 generateCubemap: 6 cubemapConvolution: 0 @@ -57,6 +58,7 @@ TextureImporter: maxTextureSizeSet: 0 compressionQualitySet: 0 textureFormatSet: 0 + ignorePngGamma: 0 platformSettings: - serializedVersion: 3 buildTarget: DefaultTexturePlatform diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1216_Lit_SSS_MaxRadius.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1216_Lit_SSS_MaxRadius.png index fc492838228..288676b1b01 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1216_Lit_SSS_MaxRadius.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1216_Lit_SSS_MaxRadius.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dc5672fc95bb6720e025d8e7a0a7f00175b8c41a306d7ff7b35d10d5b478acc4 -size 118451 +oid sha256:588cfb2cfd2ee1be05f581e2813649a0515d3cea34ddd4ab360337d3bb95636a +size 105092 diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1216_Lit_SSS_MaxRadius.png.meta b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1216_Lit_SSS_MaxRadius.png.meta index a662b8b044b..0decc1411a2 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1216_Lit_SSS_MaxRadius.png.meta +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1216_Lit_SSS_MaxRadius.png.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: cdec89136b49a05479ae6cdb5a2178a3 +guid: a655b05fae6be4249b21d33bc7cb3262 TextureImporter: internalIDToNameTable: [] externalObjects: {} @@ -23,6 +23,7 @@ TextureImporter: isReadable: 1 streamingMipmaps: 0 streamingMipmapsPriority: 0 + vTOnly: 0 grayScaleToAlpha: 0 generateCubemap: 6 cubemapConvolution: 0 @@ -57,6 +58,7 @@ TextureImporter: maxTextureSizeSet: 0 compressionQualitySet: 0 textureFormatSet: 0 + ignorePngGamma: 0 platformSettings: - serializedVersion: 3 buildTarget: DefaultTexturePlatform @@ -69,7 +71,7 @@ TextureImporter: allowsAlphaSplitting: 0 overridden: 0 androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 1 + forceMaximumCompressionQuality_BC6H_BC7: 0 spriteSheet: serializedVersion: 2 sprites: [] diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1217_Lit_SSS_Pre-Post.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1217_Lit_SSS_Pre-Post.png index d77ee10ef84..44c97b4a879 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1217_Lit_SSS_Pre-Post.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1217_Lit_SSS_Pre-Post.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:11334387562441656540ed5eb0a80a1ffa227d0939df9d2af28a3b2592b18ee4 -size 293006 +oid sha256:4ff91a6015d0ddc296c049942c6da17c2f6215c482c576f022c741ba92b62f02 +size 288282 diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1217_Lit_SSS_Pre-Post.png.meta b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1217_Lit_SSS_Pre-Post.png.meta index 855e4b983c2..52b4a09933e 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1217_Lit_SSS_Pre-Post.png.meta +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1217_Lit_SSS_Pre-Post.png.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d84eee5ee2de12146a70a8a385ab8cc5 +guid: f802c6e008663764a857c5b73e1b5931 TextureImporter: internalIDToNameTable: [] externalObjects: {} @@ -23,6 +23,7 @@ TextureImporter: isReadable: 1 streamingMipmaps: 0 streamingMipmapsPriority: 0 + vTOnly: 0 grayScaleToAlpha: 0 generateCubemap: 6 cubemapConvolution: 0 @@ -57,6 +58,7 @@ TextureImporter: maxTextureSizeSet: 0 compressionQualitySet: 0 textureFormatSet: 0 + ignorePngGamma: 0 platformSettings: - serializedVersion: 3 buildTarget: DefaultTexturePlatform diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1215_Lit_SubSurfaceScattering.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1215_Lit_SubSurfaceScattering.png index ea70334ca4c..457fb621840 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1215_Lit_SubSurfaceScattering.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1215_Lit_SubSurfaceScattering.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:be148ed922104444adfbc8cf8026ada7b546b78c6941e04dff918f35f2d5dc81 -size 91196 +oid sha256:8476a17fe47590387459f9d43936da195650fbb0b757750dfc1b5bb6420be748 +size 79160 diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1216_Lit_SSS_MaxRadius.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1216_Lit_SSS_MaxRadius.png index 288676b1b01..fc492838228 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1216_Lit_SSS_MaxRadius.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1216_Lit_SSS_MaxRadius.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:588cfb2cfd2ee1be05f581e2813649a0515d3cea34ddd4ab360337d3bb95636a -size 105092 +oid sha256:dc5672fc95bb6720e025d8e7a0a7f00175b8c41a306d7ff7b35d10d5b478acc4 +size 118451 diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1217_Lit_SSS_Pre-Post.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1217_Lit_SSS_Pre-Post.png index 44c97b4a879..574ed3e1449 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1217_Lit_SSS_Pre-Post.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/1217_Lit_SSS_Pre-Post.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4ff91a6015d0ddc296c049942c6da17c2f6215c482c576f022c741ba92b62f02 -size 288282 +oid sha256:09c578b241d26ed3a1a647c813e03f3f6db5de18bd2ef2863785ec0fa230a93f +size 349363 From d265b2d7da41b7a2d570ec61b7ce481690bf7fb8 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Mon, 24 Feb 2020 12:04:27 -0800 Subject: [PATCH 19/63] Robust filter radius --- .../DiffusionProfile/DiffusionProfile.hlsl | 2 +- .../DiffusionProfile/DiffusionProfileSettings.cs | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfile.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfile.hlsl index d3dcc574ef8..6e597f7b6b9 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfile.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfile.hlsl @@ -30,7 +30,7 @@ float3 EvalBurleyDiffusionProfile(float r, float3 S) // https://zero-radiance.github.io/post/sampling-diffusion/ // Performs sampling of a Normalized Burley diffusion profile in polar coordinates. -// 'u' is the random number: [0, 1). +// 'u' is the random number (the value of the CDF): [0, 1). // rcp(s) = 1 / ShapeParam = ScatteringDistance. // 'r' is the sampled radial distance, s.t. (u = 0 -> r = 0) and (u = 1 -> r = Inf). // rcp(Pdf) is the reciprocal of the corresponding PDF value. diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs index 758232c7af9..2c6a6789a7c 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs @@ -82,10 +82,12 @@ void UpdateKernel() Mathf.Min(16777216, 1.0f / sd.y), Mathf.Min(16777216, 1.0f / sd.z)); - // TODO: should use the value from FrameSettings, but it's not available. :-( - // Is this a serious problem in practice? Maybe! I don't know! - int n = (int)DefaultSssSampleBudgetForQualityLevel.High; - float p = ((n - 1) + 0.5f) * (1.0f / n); // Last sample + // Filter radius is, strictly speaking, infinite. + // The magnitude of the function decays exponentially, but it is never truly zero. + // To estimate the radius, we can use adapt the "three-sigma rule" by defining + // the radius of the kernel by the value of the CDF which corresponds to 99.7% + // of the energy of the filter. + float cdf = 0.997f; // Importance sample the normalized diffuse reflectance profile for the computed value of 's'. // ------------------------------------------------------------------------------------ @@ -96,7 +98,7 @@ void UpdateKernel() // We importance sample the color channel with the widest scattering distance. maxScatteringDistance = Mathf.Max(sd.x, sd.y, sd.z); - filterRadius = SampleBurleyDiffusionProfile(p, maxScatteringDistance); + filterRadius = SampleBurleyDiffusionProfile(cdf, maxScatteringDistance); } static float DisneyProfile(float r, float s) @@ -156,7 +158,7 @@ static float DisneyProfileCdfInverse(float p, float s) // https://zero-radiance.github.io/post/sampling-diffusion/ // Performs sampling of a Normalized Burley diffusion profile in polar coordinates. - // 'u' is the random number: [0, 1). + // 'u' is the random number (the value of the CDF): [0, 1). // rcp(s) = 1 / ShapeParam = ScatteringDistance. // Returns the sampled radial distance, s.t. (u = 0 -> r = 0) and (u = 1 -> r = Inf). static float SampleBurleyDiffusionProfile(float u, float rcpS) From e78aa86070835b13e849cc53e612ab6c827cc8ef Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Mon, 24 Feb 2020 12:46:16 -0800 Subject: [PATCH 20/63] Solve the NaN problem --- .../Material/SubsurfaceScattering/SubsurfaceScattering.compute | 3 +++ 1 file changed, 3 insertions(+) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute index a683ce01fa8..0f2d7815d57 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute @@ -452,5 +452,8 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, totalIrradiance, totalWeight); } + // Total weight is 0 for color channels without scattering. + totalWeight = max(totalWeight, FLT_MIN); + StoreResult(pixelCoord, albedo * (totalIrradiance / totalWeight)); } From 6268d711862a310a84a41a276b4e1af90c1a0be9 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Mon, 24 Feb 2020 15:46:39 -0800 Subject: [PATCH 21/63] Save 1x VGPR --- .../SubsurfaceScattering/SubsurfaceScattering.compute | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute index 0f2d7815d57..c0e5f9728d1 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute @@ -159,7 +159,7 @@ float3 ComputeBilateralWeight(float xy2, float z, float mmPerUnit, float3 S, flo } void EvaluateSample(uint i, uint n, uint profileIndex, float2 centerCoord, int2 cacheOffset, - float3 S, float d, float3 centerPosVS, float mmPerUnit, float2 pixelsPerMm, + float3 S, float d, float3 centerPosVS, float mmPerUnit, float pixelsPerMm, float phase, float3 tangentX, float3 tangentY, float4x4 projMatrix, inout float3 totalIrradiance, inout float3 totalWeight) { @@ -373,11 +373,12 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, float unitsPerMm = rcp(mmPerUnit); // Compute the view-space dimensions of the pixel as a quad projected onto geometry. - float2 unitsPerPixel = 2 * abs(cornerPosVS.xy - centerPosVS.xy); - float2 pixelsPerMm = rcp(unitsPerPixel) * unitsPerMm; + // Assuming square pixels, both X and Y are have the same dimensions. + float unitsPerPixel = 2 * abs(cornerPosVS.x - centerPosVS.x); + float pixelsPerMm = rcp(unitsPerPixel) * unitsPerMm; - // Area of an ellipse. - float filterArea = PI * Sq(filterRadius) * (pixelsPerMm.x * pixelsPerMm.y); + // Area of a disk. + float filterArea = PI * Sq(filterRadius * pixelsPerMm); uint sampleCount = (uint)(filterArea * rcp(SSS_PIXELS_PER_SAMPLE)); uint sampleBudget = (uint)_SssSampleBudget; From 3467d0b5d59bf5414035a0318a278b35c5168b80 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Mon, 24 Feb 2020 16:36:57 -0800 Subject: [PATCH 22/63] Update SSS defaults --- .../RenderPipeline/Settings/FrameSettings.cs | 9 ++++++ .../RP_Assets/HDRP_Test_Def.asset | 29 ++++++++++++++----- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.cs index e17d49fcb7a..4c0b2a1b0d8 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.cs @@ -420,6 +420,9 @@ partial struct FrameSettings (uint)FrameSettingsField.RayTracing, }), lodBias = 1, + sssQualityMode = SssQualityMode.FromQualitySettings, + sssQualityLevel = 0, + sssCustomSampleBudget = (int)DefaultSssSampleBudgetForQualityLevel.Low, }; internal static FrameSettings NewDefaultRealtimeReflectionProbe() => new FrameSettings() { @@ -469,6 +472,9 @@ partial struct FrameSettings (uint)FrameSettingsField.DirectSpecularLighting, }), lodBias = 1, + sssQualityMode = SssQualityMode.FromQualitySettings, + sssQualityLevel = 0, + sssCustomSampleBudget = (int)DefaultSssSampleBudgetForQualityLevel.Low, }; internal static FrameSettings NewDefaultCustomOrBakeReflectionProbe() => new FrameSettings() { @@ -516,6 +522,9 @@ partial struct FrameSettings // (uint)FrameSettingsField.DirectSpecularLighting, }), lodBias = 1, + sssQualityMode = SssQualityMode.FromQualitySettings, + sssQualityLevel = 0, + sssCustomSampleBudget = (int)DefaultSssSampleBudgetForQualityLevel.Low, }; // Each time you add data in the framesettings. Attempt to add boolean one only if possible. diff --git a/com.unity.testing.hdrp/RP_Assets/HDRP_Test_Def.asset b/com.unity.testing.hdrp/RP_Assets/HDRP_Test_Def.asset index 21fe7fe11c5..6d7f8836aa7 100644 --- a/com.unity.testing.hdrp/RP_Assets/HDRP_Test_Def.asset +++ b/com.unity.testing.hdrp/RP_Assets/HDRP_Test_Def.asset @@ -12,7 +12,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 0cf1dab834d4ec34195b920ea7bbf9ec, type: 3} m_Name: HDRP_Test_Def m_EditorClassIdentifier: - m_Version: 12 + m_Version: 14 m_ObsoleteFrameSettings: overrides: 0 enableShadow: 0 @@ -153,17 +153,21 @@ MonoBehaviour: m_RenderPipelineRayTracingResources: {fileID: 0} m_DefaultVolumeProfile: {fileID: 11400000, guid: aea7ff43876258748be47d8751e0e9d5, type: 2} - m_DefaultLookDevProfile: {fileID: 0} + m_DefaultLookDevProfile: {fileID: 11400000, guid: 254c4fe87beb7be4fa72e1681edbed02, + type: 2} m_RenderingPathDefaultCameraFrameSettings: bitDatas: data1: 69180639936349 - data2: 4539628424926265344 + data2: 4539628425463136256 lodBias: 1 lodBiasMode: 0 lodBiasQualityLevel: 0 maximumLODLevel: 0 maximumLODLevelMode: 0 maximumLODLevelQualityLevel: 0 + sssQualityMode: 0 + sssQualityLevel: 0 + sssCustomSampleBudget: 0 materialQuality: 0 m_RenderingPathDefaultBakedOrCustomReflectionFrameSettings: bitDatas: @@ -175,6 +179,9 @@ MonoBehaviour: maximumLODLevel: 0 maximumLODLevelMode: 0 maximumLODLevelQualityLevel: 0 + sssQualityMode: 0 + sssQualityLevel: 0 + sssCustomSampleBudget: 0 materialQuality: 0 m_RenderingPathDefaultRealtimeReflectionFrameSettings: bitDatas: @@ -186,13 +193,19 @@ MonoBehaviour: maximumLODLevel: 0 maximumLODLevelMode: 0 maximumLODLevelQualityLevel: 0 + sssQualityMode: 0 + sssQualityLevel: 0 + sssCustomSampleBudget: 0 materialQuality: 0 m_RenderPipelineSettings: supportShadowMask: 1 supportSSR: 1 supportSSAO: 1 supportSubsurfaceScattering: 1 - increaseSssSampleCount: 0 + sssSampleBudget: + m_Values: 140000002800000050000000 + m_SchemaId: + m_Id: With3Levels supportVolumetrics: 1 increaseResolutionOfVolumetrics: 1 supportLightLayers: 1 @@ -219,15 +232,14 @@ MonoBehaviour: supportDitheringCrossFade: 0 supportTerrainHole: 1 supportRayTracing: 0 - supportedRaytracingTier: 2 lightLoopSettings: cookieAtlasSize: 4096 - cookieAtlasFormat: 74 + cookieFormat: 74 pointCookieSize: 512 cubeCookieTexArraySize: 16 cookieAtlasLastValidMip: 0 - cookieAreaTextureArraySize: 16 - planarReflectionAtlasSize: 2048 + cookieTexArraySize: 1 + planarReflectionAtlasSize: 8192 reflectionProbeCacheSize: 128 reflectionCubemapSize: 128 reflectionCacheCompressed: 0 @@ -281,6 +293,7 @@ MonoBehaviour: postProcessSettings: m_LutSize: 32 lutFormat: 48 + bufferFormat: 74 dynamicResolutionSettings: enabled: 0 maxPercentage: 100 From bf2b7d1cfcb10c35c633229bde8889ac422ca398 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Mon, 24 Feb 2020 16:53:24 -0800 Subject: [PATCH 23/63] Add migration steps --- .../RenderPipeline/HDRenderPipelineAsset.Migration.cs | 9 ++++++++- .../Settings/FrameSettings.Migration.cs | 11 +++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipelineAsset.Migration.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipelineAsset.Migration.cs index 77f25cfd122..e4a70a01d90 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipelineAsset.Migration.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipelineAsset.Migration.cs @@ -21,6 +21,7 @@ enum Version ShadowFilteringVeryHighQualityRemoval, SeparateColorGradingAndTonemappingFrameSettings, ReplaceTextureArraysByAtlasForCookieAndPlanar, + AddedAdaptiveSSS } static readonly MigrationDescription k_Migration = MigrationDescription.New( @@ -80,7 +81,7 @@ enum Version { FrameSettings.MigrateToSeparateColorGradingAndTonemapping(ref data.m_RenderingPathDefaultCameraFrameSettings); }), - MigrationStep.New(Version.ReplaceTextureArraysByAtlasForCookieAndPlanar, (HDRenderPipelineAsset data) => + MigrationStep.New(Version.ReplaceTextureArraysByAtlasForCookieAndPlanar, (HDRenderPipelineAsset data) => { ref var lightLoopSettings = ref data.m_RenderPipelineSettings.lightLoopSettings; @@ -98,6 +99,12 @@ enum Version lightLoopSettings.cookieAtlasSize = (CookieAtlasResolution)cookieAtlasSize; lightLoopSettings.planarReflectionAtlasSize = (PlanarReflectionAtlasResolution)planarSize; + }), + MigrationStep.New(Version.AddedAdaptiveSSS, (HDRenderPipelineAsset data) => + { + FrameSettings.MigrateSubsurfaceParams(ref data.m_RenderingPathDefaultCameraFrameSettings); + FrameSettings.MigrateSubsurfaceParams(ref data.m_RenderingPathDefaultBakedOrCustomReflectionFrameSettings); + FrameSettings.MigrateSubsurfaceParams(ref data.m_RenderingPathDefaultRealtimeReflectionFrameSettings); }) ); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.Migration.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.Migration.cs index 03fb8cf370f..ce4b4e137a0 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.Migration.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.Migration.cs @@ -416,5 +416,16 @@ internal static void MigrateToSeparateColorGradingAndTonemapping(ref FrameSettin { cameraFrameSettings.SetEnabled(FrameSettingsField.Tonemapping, true); } + + internal static void MigrateSubsurfaceParams(ref FrameSettings fs) + { + // SSS moved from 25 to 46. + fs.SetEnabled((FrameSettingsField)25, false); + fs.SetEnabled(FrameSettingsField.SubsurfaceScattering, true); + // Set the defaults. + fs.sssQualityMode = SssQualityMode.FromQualitySettings; + fs.sssQualityLevel = 0; + fs.sssCustomSampleBudget = (int)DefaultSssSampleBudgetForQualityLevel.Low; + } } } From 6b55308aef6dd0b8b583e5754b9df62d20a26523 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Tue, 25 Feb 2020 17:50:17 -0800 Subject: [PATCH 24/63] Volume resolution WIP --- .../Sky/AtmosphericScattering/FogEditor.cs | 6 + .../Lighting/AtmosphericScattering/Fog.cs | 7 + .../VolumetricLighting.compute | 4 +- .../VolumetricLighting/VolumetricLighting.cs | 437 +++++++++++------- .../Runtime/RenderPipeline/Camera/HDCamera.cs | 12 +- .../Camera/HDCameraFrameHistoryType.cs | 2 - .../HDRenderPipeline.LightLoop.cs | 25 +- .../RenderPipeline/HDRenderPipeline.cs | 3 +- .../RenderPipeline/HDStringConstants.cs | 2 +- .../ShaderLibrary/ShaderVariables.hlsl | 2 +- .../Runtime/Sky/SkyManager.cs | 2 +- 11 files changed, 316 insertions(+), 186 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/Sky/AtmosphericScattering/FogEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Sky/AtmosphericScattering/FogEditor.cs index ce918bb696b..9626b33834f 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Sky/AtmosphericScattering/FogEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Sky/AtmosphericScattering/FogEditor.cs @@ -25,6 +25,8 @@ class FogEditor : VolumeComponentEditor protected SerializedDataParameter m_EnableVolumetricFog; protected SerializedDataParameter m_DepthExtent; protected SerializedDataParameter m_SliceDistributionUniformity; + protected SerializedDataParameter m_ScreenResolutionPercentage; + protected SerializedDataParameter m_VolumeSliceCount; protected SerializedDataParameter m_Filter; static GUIContent s_Enabled = new GUIContent("Enable", "Check this to enable fog in your scene."); @@ -61,6 +63,8 @@ public override void OnEnable() m_EnableVolumetricFog = Unpack(o.Find(x => x.enableVolumetricFog)); m_DepthExtent = Unpack(o.Find(x => x.depthExtent)); m_SliceDistributionUniformity = Unpack(o.Find(x => x.sliceDistributionUniformity)); + m_ScreenResolutionPercentage = Unpack(o.Find(x => x.screenResolutionPercentage)); + m_VolumeSliceCount = Unpack(o.Find(x => x.volumeSliceCount)); m_Filter = Unpack(o.Find(x => x.filter)); } @@ -117,6 +121,8 @@ public override void OnInspectorGUI() { PropertyField(m_DepthExtent); PropertyField(m_SliceDistributionUniformity); + PropertyField(m_ScreenResolutionPercentage); + PropertyField(m_VolumeSliceCount); PropertyField(m_Filter); } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/Fog.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/Fog.cs index 733c81fa19b..ae9f5739063 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/Fog.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/Fog.cs @@ -65,6 +65,13 @@ public class Fog : VolumeComponent /// Controls the distribution of slices along the Camera's focal axis. 0 is exponential distribution and 1 is linear distribution. [Tooltip("Controls the distribution of slices along the Camera's focal axis. 0 is exponential distribution and 1 is linear distribution.")] public ClampedFloatParameter sliceDistributionUniformity = new ClampedFloatParameter(0.75f, 0, 1); + /// Resolution of the volumetric buffer (3D texture) along the X and Y axes relative to the resolution of the frame buffer. + [Tooltip("Resolution of the volumetric buffer (3D texture) along the X and Y axes relative to the resolution of the frame buffer." + + "Setting it to 12.5% (1/8) means the number of voxels per slice is 1/8^2 = 1/64 = 1.5625%.")] + public ClampedFloatParameter screenResolutionPercentage = new ClampedFloatParameter((1.0f/8.0f) * 100, (1.0f/12.0f) * 100, 100); + /// Number of slices of the volumetric buffer (3D texture) along the camera's focal axis. + [Tooltip("Number of slices of the volumetric buffer (3D texture) along the camera's focal axis.")] + public ClampedIntParameter volumeSliceCount = new ClampedIntParameter(64, 1, 1024); /// Applies a blur to smoothen the volumetric lighting output. [Tooltip("Applies a blur to smoothen the volumetric lighting output.")] diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute index 287ed65d0e1..ba7103acb4e 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute @@ -585,8 +585,8 @@ void FillVolumetricLightingBuffer(LightLoopContext context, uint featureFlags, _PrevCamPosRWS, UNITY_MATRIX_PREV_VP, _VBufferPrevViewportSize, - _VBufferHistoryPrevUvScaleAndLimit.xy, - _VBufferHistoryPrevUvScaleAndLimit.zw, + _VBufferHistoryUvScaleAndLimit.xy, + _VBufferHistoryUvScaleAndLimit.zw, _VBufferPrevDepthEncodingParams, _VBufferPrevDepthDecodingParams, false, true) * float4(GetInversePreviousExposureMultiplier().xxx, 1); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs index 6d7114311de..f1c36eecf70 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs @@ -25,14 +25,14 @@ public static DensityVolumeEngineData GetNeutralValues() { DensityVolumeEngineData data; - data.scattering = Vector3.zero; - data.extinction = 0; - data.textureIndex = -1; - data.textureTiling = Vector3.one; - data.textureScroll = Vector3.zero; - data.rcpPosFaceFade = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); - data.rcpNegFaceFade = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); - data.invertFade = 0; + data.scattering = Vector3.zero; + data.extinction = 0; + data.textureIndex = -1; + data.textureTiling = Vector3.one; + data.textureScroll = Vector3.zero; + data.rcpPosFaceFade = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); + data.rcpNegFaceFade = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); + data.invertFade = 0; data.rcpDistFadeLen = 0; data.endTimesRcpDistFadeLen = 1; @@ -85,17 +85,19 @@ enum VolumetricLightingPreset struct VBufferParameters { public Vector3Int viewportSize; - public Vector4 depthEncodingParams; - public Vector4 depthDecodingParams; + public int frameIndex; + public Vector4 depthEncodingParams; + public Vector4 depthDecodingParams; - public VBufferParameters(Vector3Int viewportResolution, float depthExtent, float camNear, float camFar, float camVFoV, float sliceDistributionUniformity) + public VBufferParameters(Vector3Int viewportSize, float depthExtent, float camNear, float camFar, float camVFoV, float sliceDistributionUniformity, int frameIndex) { - viewportSize = viewportResolution; + this.viewportSize = viewportSize; + this.frameIndex = frameIndex; // The V-Buffer is sphere-capped, while the camera frustum is not. // We always start from the near plane of the camera. - float aspectRatio = viewportResolution.x / (float)viewportResolution.y; + float aspectRatio = viewportSize.x / (float)viewportSize.y; float farPlaneHeight = 2.0f * Mathf.Tan(0.5f * camVFoV) * camFar; float farPlaneWidth = farPlaneHeight * aspectRatio; float farPlaneMaxDim = Mathf.Max(farPlaneWidth, farPlaneHeight); @@ -175,8 +177,8 @@ public partial class HDRenderPipeline ComputeBuffer m_VisibleVolumeDataBuffer = null; // These two buffers do not depend on the frameID and are therefore shared by all views. - RTHandle m_DensityBufferHandle; - RTHandle m_LightingBufferHandle; + RenderTexture m_DensityBuffer; + RenderTexture m_LightingBuffer; // Is the feature globally disabled? bool m_SupportVolumetrics = false; @@ -227,62 +229,47 @@ void InitializeVolumetricLighting() CreateVolumetricLightingBuffers(); } - // RTHandleSystem API expects a function that computes the resolution. We define it here. - // Note that the RTHandleSytem never reduces the size of the render target. - // Therefore, if this function returns a smaller resolution, the size of the render target will not change. - Vector2Int ComputeVBufferResolutionXY(Vector2Int screenSize) + static internal int RoundToNearestInt(float f) { - Vector3Int resolution = ComputeVBufferResolution(volumetricLightingPreset, screenSize.x, screenSize.y); - - return new Vector2Int(resolution.x, resolution.y); + return (int)(f + 0.5f); } - void CreateVolumetricLightingBuffers() + static internal Vector3Int ComputeVolumetricViewportSize(HDCamera hdCamera) { - Debug.Assert(m_VolumetricLightingCS != null); - - m_VisibleVolumeBounds = new List(); - m_VisibleVolumeData = new List(); - m_VisibleVolumeBoundsBuffer = new ComputeBuffer(k_MaxVisibleVolumeCount, Marshal.SizeOf(typeof(OrientedBBox))); - m_VisibleVolumeDataBuffer = new ComputeBuffer(k_MaxVisibleVolumeCount, Marshal.SizeOf(typeof(DensityVolumeEngineData))); + var controller = hdCamera.volumeStack.GetComponent(); + Debug.Assert(controller != null); - int d = ComputeVBufferSliceCount(volumetricLightingPreset); + int viewportWidth = hdCamera.actualWidth; + int viewportHeight = hdCamera.actualHeight; + float screenFraction = controller.screenResolutionPercentage.value * 0.01f; + int sliceCount = controller.volumeSliceCount.value; - m_DensityBufferHandle = RTHandles.Alloc(scaleFunc: ComputeVBufferResolutionXY, - slices: d, - dimension: TextureDimension.Tex3D, - colorFormat: GraphicsFormat.R16G16B16A16_SFloat, // 8888_sRGB is not precise enough - enableRandomWrite: true, - enableMSAA: false, - /* useDynamicScale: true, // <- TODO */ - name: "VBufferDensity"); + int w = RoundToNearestInt(viewportWidth * screenFraction); + int h = RoundToNearestInt(viewportHeight * screenFraction); + int d = sliceCount; - m_LightingBufferHandle = RTHandles.Alloc(scaleFunc: ComputeVBufferResolutionXY, - slices: d, - dimension: TextureDimension.Tex3D, - colorFormat: GraphicsFormat.R16G16B16A16_SFloat, - enableRandomWrite: true, - enableMSAA: false, - /* useDynamicScale: true, // <- TODO */ - name: "VBufferIntegral"); + return new Vector3Int(w, h, d); } - // For the initial allocation, no suballocation happens (the texture is full size). - VBufferParameters ComputeVBufferParameters(HDCamera hdCamera) + static internal VBufferParameters ComputeVolumetricBufferParameters(HDCamera hdCamera, int frameIndex) { - Vector3Int viewportResolution = ComputeVBufferResolution(volumetricLightingPreset, hdCamera.actualWidth, hdCamera.actualHeight); - var controller = hdCamera.volumeStack.GetComponent(); + Debug.Assert(controller != null); - return new VBufferParameters(viewportResolution, controller.depthExtent.value, + Vector3Int viewportSize = ComputeVolumetricViewportSize(hdCamera); + + return new VBufferParameters(viewportSize, controller.depthExtent.value, hdCamera.camera.nearClipPlane, hdCamera.camera.farClipPlane, hdCamera.camera.fieldOfView, - controller.sliceDistributionUniformity.value); + controller.sliceDistributionUniformity.value, frameIndex); } - internal void ReinitializeVolumetricBufferParams(HDCamera hdCamera) + static internal void ReinitializeVolumetricBufferParams(HDCamera hdCamera, int frameIndex) { + if (!Fog.IsVolumetricFogEnabled(hdCamera)) + return; + bool fog = Fog.IsVolumetricFogEnabled(hdCamera); bool init = hdCamera.vBufferParams != null; @@ -297,7 +284,7 @@ internal void ReinitializeVolumetricBufferParams(HDCamera hdCamera) { // Initialize. // Start with the same parameters for both frames. Then update them one by one every frame. - var parameters = ComputeVBufferParameters(hdCamera); + var parameters = ComputeVolumetricBufferParameters(hdCamera, frameIndex); hdCamera.vBufferParams = new VBufferParameters[2]; hdCamera.vBufferParams[0] = parameters; hdCamera.vBufferParams[1] = parameters; @@ -307,119 +294,219 @@ internal void ReinitializeVolumetricBufferParams(HDCamera hdCamera) // This function relies on being called once per camera per frame. // The results are undefined otherwise. - internal void UpdateVolumetricBufferParams(HDCamera hdCamera) + static internal void UpdateVolumetricBufferParams(HDCamera hdCamera, int frameIndex) { if (!Fog.IsVolumetricFogEnabled(hdCamera)) return; - var parameters = ComputeVBufferParameters(hdCamera); + Debug.Assert(hdCamera.vBufferParams != null); + Debug.Assert(hdCamera.vBufferParams.Length == 2); - // Double-buffer. I assume the cost of copying is negligible (don't want to use the frame index). - // Handle case of first frame. When we are on the first frame, we reuse the value of original frame. - if (hdCamera.vBufferParams[0].viewportSize.x == 0.0f && hdCamera.vBufferParams[0].viewportSize.y == 0.0f) + var currentParams = ComputeVolumetricBufferParameters(hdCamera, frameIndex); + + var currIdx = (frameIndex + 0) & 1; + var prevIdx = (frameIndex + 1) & 1; + + if (hdCamera.vBufferParams[currIdx].frameIndex != frameIndex) { - hdCamera.vBufferParams[1] = parameters; + // Swap the two buffers. + hdCamera.vBufferParams[prevIdx] = hdCamera.vBufferParams[currIdx]; + hdCamera.vBufferParams[currIdx] = currentParams; } else { - hdCamera.vBufferParams[1] = hdCamera.vBufferParams[0]; + // Multiple updates per frame. Do not swap. + hdCamera.vBufferParams[currIdx] = currentParams; + } + + // Handle case of first frame. When we are on the first frame, we reuse the value of original frame. + if (hdCamera.vBufferParams[prevIdx].viewportSize.x == 0.0f && hdCamera.vBufferParams[prevIdx].viewportSize.y == 0.0f) + { + hdCamera.vBufferParams[prevIdx] = currentParams; } - hdCamera.vBufferParams[0] = parameters; } - internal void AllocateVolumetricHistoryBuffers(HDCamera hdCamera, int bufferCount) + static internal void ResizeVolumetricBuffer(ref RenderTexture rt, int viewportWidth, int viewportHeight, int viewportDepth) { - RTHandle HistoryBufferAllocatorFunction(string viewName, int frameIndex, RTHandleSystem rtHandleSystem) + Debug.Assert(rt != null); + + string name = rt.name; + int width = rt.width; + int height = rt.height; + int depth = rt.volumeDepth; + + bool realloc = (width < viewportWidth) || (height < viewportHeight) || (depth < viewportDepth); + + if (realloc) { - frameIndex &= 1; // 0 or 1 - - int d = ComputeVBufferSliceCount(volumetricLightingPreset); - - return rtHandleSystem.Alloc(scaleFunc: ComputeVBufferResolutionXY, - slices: d, - dimension: TextureDimension.Tex3D, - colorFormat: GraphicsFormat.R16G16B16A16_SFloat, - enableRandomWrite: true, - enableMSAA: false, - /* useDynamicScale: true, // <- TODO */ - name: string.Format("{0}_VBufferHistory{1}", viewName, frameIndex) - ); + rt.Release(); + + width = Math.Max(width, viewportWidth); + height = Math.Max(height, viewportHeight); + depth = Math.Max(depth, viewportDepth); + + rt = new RenderTexture(width: width, height: height, depth: 0, format: GraphicsFormat.R16G16B16A16_SFloat, mipCount: 0); // 8888_sRGB is not precise enough + rt.name = name; + rt.dimension = TextureDimension.Tex3D; + rt.volumeDepth = depth; + rt.enableRandomWrite = true; + + bool success = rt.Create(); + Debug.Assert(success); } + } + + static internal void CreateVolumetricHistoryBuffers(HDCamera hdCamera, int bufferCount) + { + if (!Fog.IsVolumetricFogEnabled(hdCamera)) + return; + + Debug.Assert(hdCamera.volumetricHistoryBuffers == null); + + hdCamera.volumetricHistoryBuffers = new RenderTexture[bufferCount]; - hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.VolumetricLighting, HistoryBufferAllocatorFunction, bufferCount); + // Allocation happens early in the frame. So we shouldn't rely on 'hdCamera.vBufferParams'. + // Allocate the smallest possible 3D texture. + // We will perform rescaling manually, in a custom manner, based on volume parameters. + const int minSize = 4; + + for (int i = 0; i < bufferCount; i++) + { + hdCamera.volumetricHistoryBuffers[i] = new RenderTexture(width: minSize, height: minSize, depth: 0, format: GraphicsFormat.R16G16B16A16_SFloat, mipCount: 0); // 8888_sRGB is not precise enough + hdCamera.volumetricHistoryBuffers[i].name = string.Format("VBufferHistory{0}", i); + hdCamera.volumetricHistoryBuffers[i].dimension = TextureDimension.Tex3D; + hdCamera.volumetricHistoryBuffers[i].volumeDepth = minSize; + hdCamera.volumetricHistoryBuffers[i].enableRandomWrite = true; + hdCamera.volumetricHistoryBuffers[i].Create(); + + bool success = hdCamera.volumetricHistoryBuffers[i].Create(); + Debug.Assert(success); + } } - void DestroyVolumetricLightingBuffers() + static internal void DestroyVolumetricHistoryBuffers(HDCamera hdCamera) { - if (m_DensityBufferHandle != null) - RTHandles.Release(m_DensityBufferHandle); - if (m_LightingBufferHandle != null) - RTHandles.Release(m_LightingBufferHandle); + if (hdCamera.volumetricHistoryBuffers == null) + return; - CoreUtils.SafeRelease(m_VisibleVolumeBoundsBuffer); - CoreUtils.SafeRelease(m_VisibleVolumeDataBuffer); + int bufferCount = hdCamera.volumetricHistoryBuffers.Length; + + for (int i = 0; i < bufferCount; i++) + { + hdCamera.volumetricHistoryBuffers[i].Release(); + } - m_VisibleVolumeBounds = null; - m_VisibleVolumeData = null; + hdCamera.volumetricHistoryBuffers = null; } - void CleanupVolumetricLighting() + // Must be called AFTER UpdateVolumetricBufferParams (which swaps and updates the parameters). + static internal void ResizeVolumetricHistoryBuffers(HDCamera hdCamera, int frameIndex) { - // Note: No need to test for support volumetric here, we do saferelease and null assignation - DestroyVolumetricLightingBuffers(); + if (hdCamera.volumetricHistoryBuffers == null) + return; - m_VolumeVoxelizationCS = null; - m_VolumetricLightingCS = null; + Debug.Assert(hdCamera.vBufferParams != null); + Debug.Assert(hdCamera.vBufferParams.Length == 2); + Debug.Assert(hdCamera.volumetricHistoryBuffers.Length == 2); + + var currIdx = (frameIndex + 0) & 1; + var prevIdx = (frameIndex + 1) & 1; + + var currentParams = hdCamera.vBufferParams[currIdx]; + + // We only resize the feedback buffer (#0), not the history buffer (#1). + // We must NOT resize the buffer from the previous frame (#1), as that would invalidate its contents. + ResizeVolumetricBuffer(ref hdCamera.volumetricHistoryBuffers[currIdx], currentParams.viewportSize.x, + currentParams.viewportSize.y, + currentParams.viewportSize.z); } - static int ComputeVBufferTileSize(VolumetricLightingPreset preset) + internal void CreateVolumetricLightingBuffers() { - switch (preset) - { - case VolumetricLightingPreset.Medium: - return 8; - case VolumetricLightingPreset.High: - return 4; - case VolumetricLightingPreset.Off: - return 0; - default: - Debug.Assert(false, "Encountered an unexpected VolumetricLightingPreset."); - return 0; - } + Debug.Assert(m_VolumetricLightingCS != null); + Debug.Assert(m_DensityBuffer == null); + Debug.Assert(m_LightingBuffer == null); + + m_VisibleVolumeBounds = new List(); + m_VisibleVolumeData = new List(); + m_VisibleVolumeBoundsBuffer = new ComputeBuffer(k_MaxVisibleVolumeCount, Marshal.SizeOf(typeof(OrientedBBox))); + m_VisibleVolumeDataBuffer = new ComputeBuffer(k_MaxVisibleVolumeCount, Marshal.SizeOf(typeof(DensityVolumeEngineData))); + + // Allocate the smallest possible 3D texture. + // We will perform rescaling manually, in a custom manner, based on volume parameters. + const int minSize = 4; + + m_DensityBuffer = new RenderTexture(width: minSize, height: minSize, depth: 0, format: GraphicsFormat.R16G16B16A16_SFloat, mipCount: 0); // 8888_sRGB is not precise enough + m_DensityBuffer.name = "VBufferDensity"; + m_DensityBuffer.dimension = TextureDimension.Tex3D; + m_DensityBuffer.volumeDepth = minSize; + m_DensityBuffer.enableRandomWrite = true; + + bool success = m_DensityBuffer.Create(); + Debug.Assert(success); + + m_LightingBuffer = new RenderTexture(width: minSize, height: minSize, depth: 0, format: GraphicsFormat.R16G16B16A16_SFloat, mipCount: 0); // 8888_sRGB is not precise enough + m_LightingBuffer.name = "VBufferLighting"; + m_LightingBuffer.dimension = TextureDimension.Tex3D; + m_LightingBuffer.volumeDepth = minSize; + m_LightingBuffer.enableRandomWrite = true; + + success = m_LightingBuffer.Create(); + Debug.Assert(success); } - static int ComputeVBufferSliceCount(VolumetricLightingPreset preset) + static internal void SafeRelease(RenderTexture rt) { - var result = 0; - switch (preset) + if (rt != null) { - case VolumetricLightingPreset.Medium: - result = 64; - break; - case VolumetricLightingPreset.High: - result = 128; - break; - case VolumetricLightingPreset.Off: - result = 0; - break; - default: - Debug.Assert(false, "Encountered an unexpected VolumetricLightingPreset."); - result = 0; - break; + rt.Release(); } - return result; + rt = null; } - static Vector3Int ComputeVBufferResolution(VolumetricLightingPreset preset, int screenWidth, int screenHeight) + internal void DestroyVolumetricLightingBuffers() { - int t = ComputeVBufferTileSize(preset); + SafeRelease(m_LightingBuffer); + SafeRelease(m_DensityBuffer); - int w = HDUtils.DivRoundUp(screenWidth, t); - int h = HDUtils.DivRoundUp(screenHeight, t); - int d = ComputeVBufferSliceCount(preset); + CoreUtils.SafeRelease(m_VisibleVolumeDataBuffer); + CoreUtils.SafeRelease(m_VisibleVolumeBoundsBuffer); - return new Vector3Int(w, h, d); + m_VisibleVolumeData = null; // free() + m_VisibleVolumeBounds = null; // free() + } + + // Must be called AFTER UpdateVolumetricBufferParams (which swaps and updates the parameters). + internal void ResizeVolumetricLightingBuffers(HDCamera hdCamera, int frameIndex) + { + if (!Fog.IsVolumetricFogEnabled(hdCamera)) + return; + + Debug.Assert(hdCamera.vBufferParams != null); + Debug.Assert(m_DensityBuffer != null); + Debug.Assert(m_LightingBuffer != null); + + var currIdx = (frameIndex + 0) & 1; + var prevIdx = (frameIndex + 1) & 1; + + var currentParams = hdCamera.vBufferParams[currIdx]; + + ResizeVolumetricBuffer(ref m_DensityBuffer, currentParams.viewportSize.x, + currentParams.viewportSize.y, + currentParams.viewportSize.z); + ResizeVolumetricBuffer(ref m_LightingBuffer, currentParams.viewportSize.x, + currentParams.viewportSize.y, + currentParams.viewportSize.z); + } + + void CleanupVolumetricLighting() + { + // Note: No need to test for support volumetric here, we do saferelease and null assignation + DestroyVolumetricLightingBuffers(); + + m_VolumeVoxelizationCS = null; + m_VolumetricLightingCS = null; } void SetPreconvolvedAmbientLightProbe(HDCamera hdCamera, CommandBuffer cmd, float dimmer, float anisotropy) @@ -453,8 +540,11 @@ void PushVolumetricLightingGlobalParams(HDCamera hdCamera, CommandBuffer cmd, in SetPreconvolvedAmbientLightProbe(hdCamera, cmd, fog.globalLightProbeDimmer.value, fog.anisotropy.value); - var currFrameParams = hdCamera.vBufferParams[0]; - var prevFrameParams = hdCamera.vBufferParams[1]; + var currIdx = (frameIndex + 0) & 1; + var prevIdx = (frameIndex + 1) & 1; + + var currFrameParams = hdCamera.vBufferParams[currIdx]; + var prevFrameParams = hdCamera.vBufferParams[prevIdx]; // The lighting & density buffers are shared by all cameras. // The history & feedback buffers are specific to the camera. @@ -464,18 +554,18 @@ void PushVolumetricLightingGlobalParams(HDCamera hdCamera, CommandBuffer cmd, in // The viewport size is the same for all of these buffers. // All of these buffers may have sub-native-resolution viewports. // The 3rd dimension (number of slices) is the same for all of these buffers. - Vector2Int sharedBufferSize = new Vector2Int(m_LightingBufferHandle.rt.width, m_LightingBufferHandle.rt.height); + Vector2Int sharedBufferSize = new Vector2Int(m_LightingBuffer.width, m_LightingBuffer.height); - Debug.Assert(m_LightingBufferHandle.rt.width == m_DensityBufferHandle.rt.width); - Debug.Assert(m_LightingBufferHandle.rt.height == m_DensityBufferHandle.rt.height); + Debug.Assert(m_LightingBuffer.width == m_DensityBuffer.width); + Debug.Assert(m_LightingBuffer.height == m_DensityBuffer.height); Vector2Int historyBufferSize = Vector2Int.zero; if (hdCamera.IsVolumetricReprojectionEnabled()) { - var historyRT = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.VolumetricLighting); + RenderTexture historyRT = hdCamera.volumetricHistoryBuffers[prevIdx]; - historyBufferSize = new Vector2Int(historyRT.rt.width, historyRT.rt.height); + historyBufferSize = new Vector2Int(historyRT.width, historyRT.height); // Handle case of first frame. When we are on the first frame, we reuse the value of original frame. if (historyBufferSize.x == 0.0f && historyBufferSize.y == 0.0f) @@ -490,21 +580,21 @@ void PushVolumetricLightingGlobalParams(HDCamera hdCamera, CommandBuffer cmd, in // Adjust slices for XR rendering: VBuffer is shared for all single-pass views int sliceCount = cvp.z / hdCamera.viewCount; - cmd.SetGlobalVector(HDShaderIDs._VBufferViewportSize, new Vector4(cvp.x, cvp.y, 1.0f / cvp.x, 1.0f / cvp.y)); - cmd.SetGlobalInt( HDShaderIDs._VBufferSliceCount, sliceCount); - cmd.SetGlobalFloat( HDShaderIDs._VBufferRcpSliceCount, 1.0f / sliceCount); - cmd.SetGlobalVector(HDShaderIDs._VBufferSharedUvScaleAndLimit, currFrameParams.ComputeUvScaleAndLimit(sharedBufferSize)); - cmd.SetGlobalVector(HDShaderIDs._VBufferDistanceEncodingParams, currFrameParams.depthEncodingParams); - cmd.SetGlobalVector(HDShaderIDs._VBufferDistanceDecodingParams, currFrameParams.depthDecodingParams); - cmd.SetGlobalFloat( HDShaderIDs._VBufferLastSliceDist, currFrameParams.ComputeLastSliceDistance(sliceCount)); - cmd.SetGlobalFloat( HDShaderIDs._VBufferRcpInstancedViewCount, 1.0f / hdCamera.viewCount); + cmd.SetGlobalVector(HDShaderIDs._VBufferViewportSize, new Vector4(cvp.x, cvp.y, 1.0f / cvp.x, 1.0f / cvp.y)); + cmd.SetGlobalInt( HDShaderIDs._VBufferSliceCount, sliceCount); + cmd.SetGlobalFloat( HDShaderIDs._VBufferRcpSliceCount, 1.0f / sliceCount); + cmd.SetGlobalVector(HDShaderIDs._VBufferSharedUvScaleAndLimit, currFrameParams.ComputeUvScaleAndLimit(sharedBufferSize)); + cmd.SetGlobalVector(HDShaderIDs._VBufferDistanceEncodingParams, currFrameParams.depthEncodingParams); + cmd.SetGlobalVector(HDShaderIDs._VBufferDistanceDecodingParams, currFrameParams.depthDecodingParams); + cmd.SetGlobalFloat( HDShaderIDs._VBufferLastSliceDist, currFrameParams.ComputeLastSliceDistance(sliceCount)); + cmd.SetGlobalFloat( HDShaderIDs._VBufferRcpInstancedViewCount, 1.0f / hdCamera.viewCount); - cmd.SetGlobalVector(HDShaderIDs._VBufferPrevViewportSize, new Vector4(pvp.x, pvp.y, 1.0f / pvp.x, 1.0f / pvp.y)); - cmd.SetGlobalVector(HDShaderIDs._VBufferHistoryPrevUvScaleAndLimit, prevFrameParams.ComputeUvScaleAndLimit(historyBufferSize)); - cmd.SetGlobalVector(HDShaderIDs._VBufferPrevDepthEncodingParams, prevFrameParams.depthEncodingParams); - cmd.SetGlobalVector(HDShaderIDs._VBufferPrevDepthDecodingParams, prevFrameParams.depthDecodingParams); + cmd.SetGlobalVector(HDShaderIDs._VBufferPrevViewportSize, new Vector4(pvp.x, pvp.y, 1.0f / pvp.x, 1.0f / pvp.y)); + cmd.SetGlobalVector(HDShaderIDs._VBufferHistoryUvScaleAndLimit, prevFrameParams.ComputeUvScaleAndLimit(historyBufferSize)); + cmd.SetGlobalVector(HDShaderIDs._VBufferPrevDepthEncodingParams, prevFrameParams.depthEncodingParams); + cmd.SetGlobalVector(HDShaderIDs._VBufferPrevDepthDecodingParams, prevFrameParams.depthDecodingParams); - cmd.SetGlobalTexture(HDShaderIDs._VBufferLighting, m_LightingBufferHandle); + cmd.SetGlobalTexture(HDShaderIDs._VBufferLighting, m_LightingBuffer); } DensityVolumeList PrepareVisibleDensityVolumeList(HDCamera hdCamera, CommandBuffer cmd, float time) @@ -582,7 +672,7 @@ struct VolumeVoxelizationParameters public Matrix4x4[] pixelCoordToViewDirWS; } - VolumeVoxelizationParameters PrepareVolumeVoxelizationParameters(HDCamera hdCamera) + VolumeVoxelizationParameters PrepareVolumeVoxelizationParameters(HDCamera hdCamera, int frameIndex) { var parameters = new VolumeVoxelizationParameters(); @@ -596,7 +686,10 @@ VolumeVoxelizationParameters PrepareVolumeVoxelizationParameters(HDCamera hdCame parameters.voxelizationCS = m_VolumeVoxelizationCS; parameters.voxelizationKernel = (parameters.tiledLighting ? 1 : 0) | (highQuality ? 2 : 0); - var currFrameParams = hdCamera.vBufferParams[0]; + var currIdx = (frameIndex + 0) & 1; + var prevIdx = (frameIndex + 1) & 1; + + var currFrameParams = hdCamera.vBufferParams[currIdx]; var cvp = currFrameParams.viewportSize; parameters.resolution = new Vector4(cvp.x, cvp.y, 1.0f / cvp.x, 1.0f / cvp.y); @@ -630,12 +723,14 @@ VolumeVoxelizationParameters PrepareVolumeVoxelizationParameters(HDCamera hdCame } static void VolumeVoxelizationPass( in VolumeVoxelizationParameters parameters, - RTHandle densityBuffer, + RenderTexture densityBuffer, ComputeBuffer visibleVolumeBoundsBuffer, ComputeBuffer visibleVolumeDataBuffer, ComputeBuffer bigTileLightList, CommandBuffer cmd) - { + { + // Before we set the buffer, we must make sure + cmd.SetComputeIntParam(parameters.voxelizationCS, HDShaderIDs._NumTileBigTileX, parameters.numBigTileX); cmd.SetComputeIntParam(parameters.voxelizationCS, HDShaderIDs._NumTileBigTileY, parameters.numBigTileY); if (parameters.tiledLighting) @@ -663,8 +758,8 @@ void VolumeVoxelizationPass(HDCamera hdCamera, CommandBuffer cmd) using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.VolumeVoxelization))) { - var parameters = PrepareVolumeVoxelizationParameters(hdCamera); - VolumeVoxelizationPass(parameters, m_DensityBufferHandle, m_VisibleVolumeBoundsBuffer, m_VisibleVolumeDataBuffer, m_TileAndClusterData.bigTileLightList, cmd); + var parameters = PrepareVolumeVoxelizationParameters(hdCamera, GetFrameCount()); + VolumeVoxelizationPass(parameters, m_DensityBuffer, m_VisibleVolumeBoundsBuffer, m_VisibleVolumeDataBuffer, m_TileAndClusterData.bigTileLightList, cmd); } } @@ -741,7 +836,11 @@ VolumetricLightingParameters PrepareVolumetricLightingParameters(HDCamera hdCame parameters.volumetricLightingKernel = (parameters.tiledLighting ? 1 : 0) | (parameters.enableReprojection ? 2 : 0) | (enableAnisotropy ? 4 : 0) | (highQuality ? 8 : 0); parameters.volumetricFilteringKernelX = 16; parameters.volumetricFilteringKernelY = 17; - var currFrameParams = hdCamera.vBufferParams[0]; + + var currIdx = (frameIndex + 0) & 1; + var prevIdx = (frameIndex + 1) & 1; + + var currFrameParams = hdCamera.vBufferParams[currIdx]; var cvp = currFrameParams.viewportSize; parameters.resolution = new Vector4(cvp.x, cvp.y, 1.0f / cvp.x, 1.0f / cvp.y); @@ -772,10 +871,10 @@ VolumetricLightingParameters PrepareVolumetricLightingParameters(HDCamera hdCame } static void VolumetricLightingPass( in VolumetricLightingParameters parameters, - RTHandle densityBuffer, - RTHandle lightingBuffer, - RTHandle historyRT, - RTHandle feedbackRT, + RenderTexture densityBuffer, + RenderTexture lightingBuffer, + RenderTexture historyRT, + RenderTexture feedbackRT, ComputeBuffer bigTileLightList, CommandBuffer cmd) { @@ -806,7 +905,7 @@ static void VolumetricLightingPass( in VolumetricLightingParameters parameters, cmd.DispatchCompute(parameters.volumetricLightingCS, parameters.volumetricLightingKernel, ((int)parameters.resolution.x + 7) / 8, ((int)parameters.resolution.y + 7) / 8, parameters.viewCount); } - static void FilterVolumetricLighting(in VolumetricLightingParameters parameters, RTHandle outputBuffer, RTHandle inputBuffer, CommandBuffer cmd) + static void FilterVolumetricLighting(in VolumetricLightingParameters parameters, RenderTexture outputBuffer, RenderTexture inputBuffer, CommandBuffer cmd) { using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.VolumetricLightingFiltering))) { @@ -830,12 +929,18 @@ void VolumetricLightingPass(HDCamera hdCamera, CommandBuffer cmd, int frameIndex using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.VolumetricLighting))) { - // It is safe to request these RTs even if they have not been allocated. - // The system will return NULL in that case. - RTHandle historyRT = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.VolumetricLighting); - RTHandle feedbackRT = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.VolumetricLighting); + RenderTexture feedbackRT = null, historyRT = null; + + if (parameters.enableReprojection) + { + var currIdx = (frameIndex + 0) & 1; + var prevIdx = (frameIndex + 1) & 1; + + feedbackRT = hdCamera.volumetricHistoryBuffers[currIdx]; + historyRT = hdCamera.volumetricHistoryBuffers[prevIdx]; + } - VolumetricLightingPass(parameters, m_DensityBufferHandle, m_LightingBufferHandle, historyRT, feedbackRT, m_TileAndClusterData.bigTileLightList, cmd); + VolumetricLightingPass(parameters, m_DensityBuffer, m_LightingBuffer, historyRT, feedbackRT, m_TileAndClusterData.bigTileLightList, cmd); if (parameters.enableReprojection) hdCamera.volumetricHistoryIsValid = true; // For the next frame... @@ -843,7 +948,7 @@ void VolumetricLightingPass(HDCamera hdCamera, CommandBuffer cmd, int frameIndex // Let's filter out volumetric buffer if (parameters.filterVolume) - FilterVolumetricLighting(parameters, m_DensityBufferHandle, m_LightingBufferHandle, cmd); + FilterVolumetricLighting(parameters, m_DensityBuffer, m_LightingBuffer, cmd); } } // class VolumetricLightingModule } // namespace UnityEngine.Rendering.HighDefinition diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs index 5fb0e9bc083..990269b1b6a 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs @@ -179,7 +179,8 @@ internal struct ShadowHistoryUsage internal Transform volumeAnchor; internal Rect finalViewport; // This will have the correct viewport position and the size will be full resolution (ie : not taking dynamic rez into account) internal int colorPyramidHistoryMipCount = 0; - internal VBufferParameters[] vBufferParams; // Double-buffered; needed even if reprojection is off + internal VBufferParameters[] vBufferParams; // Double-buffered; needed even if reprojection is off + internal RenderTexture[] volumetricHistoryBuffers; // Double-buffered; only used for reprojection // Currently the frame count is not increase every render, for ray tracing shadow filtering. We need to have a number that increases every render internal uint cameraFrameCount = 0; internal bool animateMaterials; @@ -386,7 +387,7 @@ internal void Update(FrameSettings currentFrameSettings, HDRenderPipeline hdrp, { // Have to do this every frame in case the settings have changed. // The condition inside controls whether we perform init/deinit or not. - hdrp.ReinitializeVolumetricBufferParams(this); + HDRenderPipeline.ReinitializeVolumetricBufferParams(this, hdrp.GetFrameCount()); bool isCurrentColorPyramidRequired = frameSettings.IsEnabled(FrameSettingsField.Refraction) || frameSettings.IsEnabled(FrameSettingsField.Distortion); bool isHistoryColorPyramidRequired = frameSettings.IsEnabled(FrameSettingsField.SSR) || antialiasing == AntialiasingMode.TemporalAntialiasing; @@ -407,6 +408,8 @@ internal void Update(FrameSettings currentFrameSettings, HDRenderPipeline hdrp, colorPyramidHistoryIsValid = false; volumetricHistoryIsValid = false; + HDRenderPipeline.DestroyVolumetricHistoryBuffers(this); + // The history system only supports the "nuke all" option. m_HistoryRTSystem.Dispose(); m_HistoryRTSystem = new BufferedRTHandleSystem(); @@ -418,7 +421,7 @@ internal void Update(FrameSettings currentFrameSettings, HDRenderPipeline hdrp, if (numVolumetricBuffersRequired != 0) { - hdrp.AllocateVolumetricHistoryBuffers(this, numVolumetricBuffersRequired); + HDRenderPipeline.CreateVolumetricHistoryBuffers(this, numVolumetricBuffersRequired); } // Mark as init. @@ -462,7 +465,8 @@ internal void Update(FrameSettings currentFrameSettings, HDRenderPipeline hdrp, isFirstFrame = false; cameraFrameCount++; - hdrp.UpdateVolumetricBufferParams(this); + HDRenderPipeline.UpdateVolumetricBufferParams(this, hdrp.GetFrameCount()); + HDRenderPipeline.ResizeVolumetricHistoryBuffers(this, hdrp.GetFrameCount()); // Here we use the non scaled resolution for the RTHandleSystem ref size because we assume that at some point we will need full resolution anyway. // This is necessary because we assume that after post processes, we have the full size render target for debug rendering 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 0f6182b3e81..d24a65a2d0b 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 @@ -7,8 +7,6 @@ public enum HDCameraFrameHistoryType { /// Color buffer mip chain. ColorBufferMipChain, - /// Volumetric lighting buffer. - VolumetricLighting, /// Exposure buffer. Exposure, /// Temporal antialiasing history. diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index 1541719d28c..e423d6d7258 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -380,16 +380,19 @@ RenderGraphResource VolumeVoxelizationPass( RenderGraph renderGraph, { builder.EnableAsyncCompute(hdCamera.frameSettings.VolumeVoxelizationRunsAsync()); - passData.parameters = PrepareVolumeVoxelizationParameters(hdCamera); + passData.parameters = PrepareVolumeVoxelizationParameters(hdCamera, GetFrameCount()); passData.visibleVolumeBoundsBuffer = visibleVolumeBoundsBuffer; passData.visibleVolumeDataBuffer = visibleVolumeDataBuffer; passData.bigTileLightListBuffer = bigTileLightListBuffer; - passData.densityBuffer = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(ComputeVBufferResolutionXY, false, false) + + Vector3Int viewportSize = ComputeVolumetricViewportSize(hdCamera); + + passData.densityBuffer = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(viewportSize.x, viewportSize.y, false, false) { dimension = TextureDimension.Tex3D, colorFormat = GraphicsFormat.R16G16B16A16_SFloat, // 8888_sRGB is not precise enough enableRandomWrite = true, - slices = ComputeVBufferSliceCount(volumetricLightingPreset), + slices = viewportSize.z, /* useDynamicScale: true, // <- TODO ,*/ name = "VBufferDensity" })); @@ -434,19 +437,25 @@ RenderGraphResource VolumetricLightingPass(RenderGraph renderGraph, HDCamera hdC passData.parameters = parameters; passData.bigTileLightListBuffer = bigTileLightListBuffer; passData.densityBuffer = builder.ReadTexture(densityBuffer); - passData.lightingBuffer = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(ComputeVBufferResolutionXY, false, false) + + Vector3Int viewportSize = ComputeVolumetricViewportSize(hdCamera); + + passData.lightingBuffer = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(viewportSize.x, viewportSize.y, false, false) { dimension = TextureDimension.Tex3D, colorFormat = GraphicsFormat.R16G16B16A16_SFloat, // 8888_sRGB is not precise enough enableRandomWrite = true, - slices = ComputeVBufferSliceCount(volumetricLightingPreset), + slices = viewportSize.z, /* useDynamicScale: true, // <- TODO ,*/ - name = "VBufferIntegral" + name = "VBufferLighting" }, HDShaderIDs._VBufferLighting)); if (passData.parameters.enableReprojection) { - passData.historyBuffer = builder.ReadTexture(renderGraph.ImportTexture(hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.VolumetricLighting))); - passData.feedbackBuffer = builder.WriteTexture(renderGraph.ImportTexture(hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.VolumetricLighting))); + // Cannot import a RenderTexture => WILL BE HORRIBLY BROKEN. + //passData.feedbackBuffer = builder.WriteTexture(renderGraph.ImportTexture(hdCamera.volumetricHistoryBuffers[0])); + //passData.historyBuffer = builder.ReadTexture(renderGraph.ImportTexture(hdCamera.volumetricHistoryBuffers[1])); + passData.feedbackBuffer = passData.lightingBuffer; + passData.historyBuffer = passData.densityBuffer; } HDShadowManager.ReadShadowResult(shadowResult, builder); 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 37b8807ffaa..b2c39685589 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -2579,6 +2579,7 @@ out ScriptableCullingParameters cullingParams // From this point, we should only use frame settings from the camera hdCamera.Update(currentFrameSettings, this, m_MSAASamples, xrPass); + ResizeVolumetricLightingBuffers(hdCamera, GetFrameCount()); // Safe to update the Volumetric Lighting System now // Custom Render requires a proper HDCamera, so we return after the HDCamera was setup if (additionalCameraData != null && additionalCameraData.hasCustomRender) @@ -3368,7 +3369,7 @@ void RenderSky(HDCamera hdCamera, CommandBuffer cmd) if (Fog.IsFogEnabled(hdCamera) || Fog.IsPBRFogEnabled(hdCamera)) { var pixelCoordToViewDirWS = hdCamera.mainViewConstants.pixelCoordToViewDirWS; - m_SkyManager.RenderOpaqueAtmosphericScattering(cmd, hdCamera, colorBuffer, m_LightingBufferHandle, intermediateBuffer, depthBuffer, pixelCoordToViewDirWS, hdCamera.frameSettings.IsEnabled(FrameSettingsField.MSAA)); + m_SkyManager.RenderOpaqueAtmosphericScattering(cmd, hdCamera, colorBuffer, m_LightingBuffer, intermediateBuffer, depthBuffer, pixelCoordToViewDirWS, hdCamera.frameSettings.IsEnabled(FrameSettingsField.MSAA)); } } 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 b263555201e..71ebae0b9d4 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs @@ -501,7 +501,7 @@ static class HDShaderIDs public static readonly int _VBufferDistanceEncodingParams = Shader.PropertyToID("_VBufferDistanceEncodingParams"); public static readonly int _VBufferDistanceDecodingParams = Shader.PropertyToID("_VBufferDistanceDecodingParams"); public static readonly int _VBufferPrevViewportSize = Shader.PropertyToID("_VBufferPrevViewportSize"); - public static readonly int _VBufferHistoryPrevUvScaleAndLimit = Shader.PropertyToID("_VBufferHistoryPrevUvScaleAndLimit"); + public static readonly int _VBufferHistoryUvScaleAndLimit = Shader.PropertyToID("_VBufferHistoryUvScaleAndLimit"); public static readonly int _VBufferPrevDepthEncodingParams = Shader.PropertyToID("_VBufferPrevDepthEncodingParams"); public static readonly int _VBufferPrevDepthDecodingParams = Shader.PropertyToID("_VBufferPrevDepthDecodingParams"); public static readonly int _VBufferLastSliceDist = Shader.PropertyToID("_VBufferLastSliceDist"); diff --git a/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl b/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl index f2de209be44..358140d5413 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl @@ -254,7 +254,7 @@ CBUFFER_START(UnityGlobal) // Once reprojection is performed in a separate pass, we should probably // move these to a dedicated CBuffer to avoid polluting the global one. float4 _VBufferPrevViewportSize; - float4 _VBufferHistoryPrevUvScaleAndLimit; + float4 _VBufferHistoryUvScaleAndLimit; float4 _VBufferPrevDepthEncodingParams; float4 _VBufferPrevDepthDecodingParams; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs b/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs index beba35ba06e..271e21ed2cc 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs @@ -872,7 +872,7 @@ public void RenderSky(HDCamera hdCamera, Light sunLight, RTHandle colorBuffer, R public void RenderOpaqueAtmosphericScattering(CommandBuffer cmd, HDCamera hdCamera, RTHandle colorBuffer, - RTHandle volumetricLighting, + RenderTexture volumetricLighting, RTHandle intermediateBuffer, RTHandle depthBuffer, Matrix4x4 pixelCoordToViewDirWS, bool isMSAA) From 7678bd7bbbc4d7112275eee4672e67a7f4e7b601 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Tue, 25 Feb 2020 17:56:28 -0800 Subject: [PATCH 25/63] Shorter names FTW --- .../AtmosphericScattering.hlsl | 2 ++ .../ShaderVariablesAtmosphericScattering.hlsl | 1 - .../VolumeVoxelization.compute | 2 +- .../VolumetricLighting.compute | 20 +++++++++---------- .../VolumetricLighting/VolumetricLighting.cs | 18 ++++++++--------- .../RenderPipeline/HDStringConstants.cs | 7 +++---- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/AtmosphericScattering.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/AtmosphericScattering.hlsl index fc99fcf5603..95a787482bf 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/AtmosphericScattering.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/AtmosphericScattering.hlsl @@ -14,6 +14,8 @@ #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl" #endif +TEXTURE3D(_VBufferLighting); + float3 ExpLerp(float3 A, float3 B, float t, float x, float y) { // Remap t: (exp(10 k t) - 1) / (exp(10 k) - 1) = exp(x t) y - y. diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/ShaderVariablesAtmosphericScattering.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/ShaderVariablesAtmosphericScattering.hlsl index bc67f69e7c3..67bf3018007 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/ShaderVariablesAtmosphericScattering.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/ShaderVariablesAtmosphericScattering.hlsl @@ -1,7 +1,6 @@ #ifdef SHADER_VARIABLES_INCLUDE_CB #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/ShaderVariablesAtmosphericScattering.cs.hlsl" #else - TEXTURE3D(_VBufferLighting); TEXTURECUBE_ARRAY(_SkyTexture); #define _MipFogNear _MipFogParameters.x diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumeVoxelization.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumeVoxelization.compute index cdc875aa477..e726a1d0772 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumeVoxelization.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumeVoxelization.compute @@ -66,7 +66,7 @@ CBUFFER_START(UnityVolumetricLighting) float _VBufferUnitDepthTexelSpacing; uint _NumVisibleDensityVolumes; float _CornetteShanksConstant; // Not used by this shader - uint _VBufferLightingHistoryIsValid; // Not used by this shader + uint _VBufferHistoryIsValid; // Not used by this shader float4 _VBufferSampleOffset; // Not used by this shader float4 _VolumeMaskDimensions; // x = 1/numTextures , y = width, z = depth = width * numTextures, w = maxLod diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute index ba7103acb4e..34412ab0e94 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute @@ -83,9 +83,9 @@ // Inputs & outputs //-------------------------------------------------------------------------------------------------- -RW_TEXTURE3D(float4, _VBufferLightingIntegral); -RW_TEXTURE3D(float4, _VBufferLightingFeedback); -TEXTURE3D(_VBufferLightingHistory); +RW_TEXTURE3D(float4, _VBufferLighting); +RW_TEXTURE3D(float4, _VBufferFeedback); +TEXTURE3D(_VBufferHistory); TEXTURE3D(_VBufferDensity); // RGB = scattering, A = extinction // TODO: avoid creating another Constant Buffer... @@ -95,7 +95,7 @@ CBUFFER_START(UnityVolumetricLighting) float _VBufferUnitDepthTexelSpacing; uint _NumVisibleDensityVolumes; // Not used by this shader float _CornetteShanksConstant; - uint _VBufferLightingHistoryIsValid; + uint _VBufferHistoryIsValid; float4 _VBufferSampleOffset; float4 _VolumeMaskDimensions; // Not used by this shader @@ -580,7 +580,7 @@ void FillVolumetricLightingBuffer(LightLoopContext context, uint featureFlags, #endif // Reproject the history at 'centerWS'. - float4 reprojValue = SampleVBuffer(TEXTURE3D_ARGS(_VBufferLightingHistory, s_linear_clamp_sampler), + float4 reprojValue = SampleVBuffer(TEXTURE3D_ARGS(_VBufferHistory, s_linear_clamp_sampler), centerWS, _PrevCamPosRWS, UNITY_MATRIX_PREV_VP, @@ -591,7 +591,7 @@ void FillVolumetricLightingBuffer(LightLoopContext context, uint featureFlags, _VBufferPrevDepthDecodingParams, false, true) * float4(GetInversePreviousExposureMultiplier().xxx, 1); - bool reprojSuccess = (_VBufferLightingHistoryIsValid != 0) && (reprojValue.a != 0); + bool reprojSuccess = (_VBufferHistoryIsValid != 0) && (reprojValue.a != 0); if (reprojSuccess) { @@ -603,7 +603,7 @@ void FillVolumetricLightingBuffer(LightLoopContext context, uint featureFlags, // TODO: dynamic lights (which update their position, rotation, cookie or shadow at runtime) // do not support reprojection and should neither read nor write to the history buffer. // This will cause them to alias, but it is the only way to prevent ghosting. - _VBufferLightingFeedback[voxelCoord] = normalizedBlendValue * float4(GetCurrentExposureMultiplier().xxx, 1); + _VBufferFeedback[voxelCoord] = normalizedBlendValue * float4(GetCurrentExposureMultiplier().xxx, 1); float4 linearizedBlendValue = normalizedBlendValue * dt; float4 blendValue = DelinearizeRGBD(linearizedBlendValue); @@ -661,7 +661,7 @@ void FillVolumetricLightingBuffer(LightLoopContext context, uint featureFlags, // This means storing the tone mapped radiance and transmittance instead of optical depth. // See "A Fresh Look at Generalized Sampling", p. 51. // TODO: re-enable tone mapping after implementing pre-exposure. - _VBufferLightingIntegral[voxelCoord] = LinearizeRGBD(float4(/*FastTonemap*/(totalRadiance), opticalDepth)) * float4(GetCurrentExposureMultiplier().xxx, 1); + _VBufferLighting[voxelCoord] = LinearizeRGBD(float4(/*FastTonemap*/(totalRadiance), opticalDepth)) * float4(GetCurrentExposureMultiplier().xxx, 1); // Compute the optical depth up to the end of the interval. opticalDepth += 0.5 * blendValue.a; @@ -777,7 +777,7 @@ void FilterVolumetricLighting(uint3 dispatchThreadId : SV_DispatchThreadID, // Compute the next tapping coordinate int3 tapCoord = int3(voxelCoord.x, voxelCoord.y, voxelCoord.z) + vec * idx; // Tap the value we should be tapping from - float4 currentValue = _VBufferLightingFeedback[tapCoord]; + float4 currentValue = _VBufferFeedback[tapCoord]; // Compute the weight for this tap float weight = Gaussian(abs(idx), SIGMA_FILTER); @@ -793,6 +793,6 @@ void FilterVolumetricLighting(uint3 dispatchThreadId : SV_DispatchThreadID, sumW += weight; } // Normalize and output - _VBufferLightingIntegral[voxelCoord] = value / sumW; + _VBufferLighting[voxelCoord] = value / sumW; } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs index f1c36eecf70..3f0dc550166 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs @@ -889,16 +889,16 @@ static void VolumetricLightingPass( in VolumetricLightingParameters parameters, cmd.SetComputeFloatParam(parameters.volumetricLightingCS, HDShaderIDs._VBufferUnitDepthTexelSpacing, parameters.unitDepthTexelSpacing); cmd.SetComputeFloatParam(parameters.volumetricLightingCS, HDShaderIDs._CornetteShanksConstant, CornetteShanksPhasePartConstant(parameters.anisotropy)); cmd.SetComputeVectorParam(parameters.volumetricLightingCS, HDShaderIDs._VBufferSampleOffset, parameters.xySeqOffset); - cmd.SetComputeTextureParam(parameters.volumetricLightingCS, parameters.volumetricLightingKernel, HDShaderIDs._VBufferDensity, densityBuffer); // Read - cmd.SetComputeTextureParam(parameters.volumetricLightingCS, parameters.volumetricLightingKernel, HDShaderIDs._VBufferLightingIntegral, lightingBuffer); // Write + cmd.SetComputeTextureParam(parameters.volumetricLightingCS, parameters.volumetricLightingKernel, HDShaderIDs._VBufferDensity, densityBuffer); // Read + cmd.SetComputeTextureParam(parameters.volumetricLightingCS, parameters.volumetricLightingKernel, HDShaderIDs._VBufferLighting, lightingBuffer); // Write // We set this even when not re-projecting to make sure it stays in a safe state when we switch camera - cmd.SetComputeIntParam(parameters.volumetricLightingCS, HDShaderIDs._VBufferLightingHistoryIsValid, parameters.historyIsValid ? 1 : 0); + cmd.SetComputeIntParam(parameters.volumetricLightingCS, HDShaderIDs._VBufferHistoryIsValid, parameters.historyIsValid ? 1 : 0); if (parameters.enableReprojection) { - cmd.SetComputeTextureParam(parameters.volumetricLightingCS, parameters.volumetricLightingKernel, HDShaderIDs._VBufferLightingHistory, historyRT); // Read - cmd.SetComputeTextureParam(parameters.volumetricLightingCS, parameters.volumetricLightingKernel, HDShaderIDs._VBufferLightingFeedback, feedbackRT); // Write + cmd.SetComputeTextureParam(parameters.volumetricLightingCS, parameters.volumetricLightingKernel, HDShaderIDs._VBufferHistory, historyRT); // Read + cmd.SetComputeTextureParam(parameters.volumetricLightingCS, parameters.volumetricLightingKernel, HDShaderIDs._VBufferFeedback, feedbackRT); // Write } // The shader defines GROUP_SIZE_1D = 8. @@ -910,12 +910,12 @@ static void FilterVolumetricLighting(in VolumetricLightingParameters parameters, using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.VolumetricLightingFiltering))) { // The shader defines GROUP_SIZE_1D = 8. - cmd.SetComputeTextureParam(parameters.volumetricLightingCS, parameters.volumetricFilteringKernelX, HDShaderIDs._VBufferLightingFeedback, inputBuffer); // Read - cmd.SetComputeTextureParam(parameters.volumetricLightingCS, parameters.volumetricFilteringKernelX, HDShaderIDs._VBufferLightingIntegral, outputBuffer); // Write + cmd.SetComputeTextureParam(parameters.volumetricLightingCS, parameters.volumetricFilteringKernelX, HDShaderIDs._VBufferFeedback, inputBuffer); // Read + cmd.SetComputeTextureParam(parameters.volumetricLightingCS, parameters.volumetricFilteringKernelX, HDShaderIDs._VBufferLighting, outputBuffer); // Write cmd.DispatchCompute(parameters.volumetricLightingCS, parameters.volumetricFilteringKernelX, ((int)parameters.resolution.x + 7) / 8, ((int)parameters.resolution.y + 7) / 8, parameters.viewCount); - cmd.SetComputeTextureParam(parameters.volumetricLightingCS, parameters.volumetricFilteringKernelY, HDShaderIDs._VBufferLightingFeedback, outputBuffer); // Read - cmd.SetComputeTextureParam(parameters.volumetricLightingCS, parameters.volumetricFilteringKernelY, HDShaderIDs._VBufferLightingIntegral, inputBuffer); // Write + cmd.SetComputeTextureParam(parameters.volumetricLightingCS, parameters.volumetricFilteringKernelY, HDShaderIDs._VBufferFeedback, outputBuffer); // Read + cmd.SetComputeTextureParam(parameters.volumetricLightingCS, parameters.volumetricFilteringKernelY, HDShaderIDs._VBufferLighting, inputBuffer); // Write cmd.DispatchCompute(parameters.volumetricLightingCS, parameters.volumetricFilteringKernelY, ((int)parameters.resolution.x + 7) / 8, ((int)parameters.resolution.y + 7) / 8, parameters.viewCount); } } 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 71ebae0b9d4..3eed7f9a055 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs @@ -509,10 +509,9 @@ static class HDShaderIDs public static readonly int _VBufferUnitDepthTexelSpacing = Shader.PropertyToID("_VBufferUnitDepthTexelSpacing"); public static readonly int _VBufferDensity = Shader.PropertyToID("_VBufferDensity"); public static readonly int _VBufferLighting = Shader.PropertyToID("_VBufferLighting"); - public static readonly int _VBufferLightingIntegral = Shader.PropertyToID("_VBufferLightingIntegral"); - public static readonly int _VBufferLightingHistory = Shader.PropertyToID("_VBufferLightingHistory"); - public static readonly int _VBufferLightingHistoryIsValid = Shader.PropertyToID("_VBufferLightingHistoryIsValid"); - public static readonly int _VBufferLightingFeedback = Shader.PropertyToID("_VBufferLightingFeedback"); + public static readonly int _VBufferHistory = Shader.PropertyToID("_VBufferHistory"); + public static readonly int _VBufferFeedback = Shader.PropertyToID("_VBufferFeedback"); + public static readonly int _VBufferHistoryIsValid = Shader.PropertyToID("_VBufferHistoryIsValid"); public static readonly int _VBufferSampleOffset = Shader.PropertyToID("_VBufferSampleOffset"); public static readonly int _VolumeBounds = Shader.PropertyToID("_VolumeBounds"); public static readonly int _VolumeData = Shader.PropertyToID("_VolumeData"); From 5d89ce681e5eb3756f8c81f7d40084fd9e3a1c50 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Tue, 25 Feb 2020 18:08:48 -0800 Subject: [PATCH 26/63] Comment --- .../Runtime/Lighting/AtmosphericScattering/Fog.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/Fog.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/Fog.cs index ae9f5739063..b339ced85c8 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/Fog.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/Fog.cs @@ -66,8 +66,8 @@ public class Fog : VolumeComponent [Tooltip("Controls the distribution of slices along the Camera's focal axis. 0 is exponential distribution and 1 is linear distribution.")] public ClampedFloatParameter sliceDistributionUniformity = new ClampedFloatParameter(0.75f, 0, 1); /// Resolution of the volumetric buffer (3D texture) along the X and Y axes relative to the resolution of the frame buffer. - [Tooltip("Resolution of the volumetric buffer (3D texture) along the X and Y axes relative to the resolution of the frame buffer." + - "Setting it to 12.5% (1/8) means the number of voxels per slice is 1/8^2 = 1/64 = 1.5625%.")] + [Tooltip("Resolution of the volumetric buffer (3D texture) along the X and Y axes relative to the resolution of the frame buffer. " + + "Setting it to 12.5% (1/8) means the number of voxels per slice is 1/8^2 = 1/64 = 1.5625% of the resolution of the frame buffer.")] public ClampedFloatParameter screenResolutionPercentage = new ClampedFloatParameter((1.0f/8.0f) * 100, (1.0f/12.0f) * 100, 100); /// Number of slices of the volumetric buffer (3D texture) along the camera's focal axis. [Tooltip("Number of slices of the volumetric buffer (3D texture) along the camera's focal axis.")] From 95fba9f88aac5bbd29306f601ba5788d3060d283 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Wed, 26 Feb 2020 15:15:38 -0800 Subject: [PATCH 27/63] Dynamic slice count works --- .../AtmosphericScattering.hlsl | 16 +++--- .../Lighting/VolumetricLighting/VBuffer.hlsl | 57 ++++++++++++------- .../VolumetricLighting.compute | 4 +- .../VolumetricLighting/VolumetricLighting.cs | 30 ++++++---- .../RenderPipeline/HDRenderPipeline.cs | 2 +- .../RenderPipeline/HDStringConstants.cs | 6 +- .../Runtime/RenderPipeline/Utility/HDUtils.cs | 28 ++++++--- .../ShaderLibrary/ShaderVariables.hlsl | 6 +- 8 files changed, 93 insertions(+), 56 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/AtmosphericScattering.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/AtmosphericScattering.hlsl index 95a787482bf..308f3cecee0 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/AtmosphericScattering.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/AtmosphericScattering.hlsl @@ -275,14 +275,14 @@ void EvaluateAtmosphericScattering(PositionInputs posInput, float3 V, out float3 if (_EnableVolumetricFog != 0) { float4 value = SampleVBuffer(TEXTURE3D_ARGS(_VBufferLighting, s_linear_clamp_sampler), - posInput.positionNDC, - fogFragDist, - _VBufferViewportSize, - _VBufferSharedUvScaleAndLimit.xy, - _VBufferSharedUvScaleAndLimit.zw, - _VBufferDistanceEncodingParams, - _VBufferDistanceDecodingParams, - true, false); + posInput.positionNDC, + fogFragDist, + _VBufferViewportSize, + _VBufferLightingViewportScale, + _VBufferLightingViewportLimit, + _VBufferDistanceEncodingParams, + _VBufferDistanceDecodingParams, + true, false); // TODO: add some slowly animated noise (dither?) to the reconstructed value. // TODO: re-enable tone mapping after implementing pre-exposure. diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VBuffer.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VBuffer.hlsl index 1bfd11ee33b..a6fd641a23f 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VBuffer.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VBuffer.hlsl @@ -9,15 +9,15 @@ // This means storing tone mapped radiance and transmittance instead of optical depth. // See "A Fresh Look at Generalized Sampling", p. 51. // -// if (clampToBorder), samples outside of the buffer return 0 (we perform a smooth fade). +// if (clampToBorder), samples outside of the buffer return 0 (border color). // Otherwise, the sampler simply clamps the texture coordinate to the edge of the texture. // Warning: clamping to border may not work as expected with the quadratic filter due to its extent. float4 SampleVBuffer(TEXTURE3D_PARAM(VBuffer, clampSampler), float2 positionNDC, float linearDistance, float4 VBufferViewportSize, - float2 VBufferUvScale, - float2 VBufferUvLimit, + float3 VBufferViewportScale, + float3 VBufferViewportLimit, float4 VBufferDistanceEncodingParams, float4 VBufferDistanceDecodingParams, bool quadraticFilterXY, @@ -27,17 +27,19 @@ float4 SampleVBuffer(TEXTURE3D_PARAM(VBuffer, clampSampler), float2 uv = positionNDC; float w = EncodeLogarithmicDepthGeneralized(linearDistance, VBufferDistanceEncodingParams); - bool coordIsInsideFrustum = true; + bool coordIsInsideFrustum; if (clampToBorder) { - // Coordinates are always clamped to edge. We just introduce a clipping operation. + // Coordinates are always clamped to the edge. We just introduce a clipping operation. float3 positionCS = float3(uv, w) * 2 - 1; coordIsInsideFrustum = Max3(abs(positionCS.x), abs(positionCS.y), abs(positionCS.z)) < 1; } - - float4 result = 0; + else + { + coordIsInsideFrustum = true; // No clipping + } #if defined(UNITY_STEREO_INSTANCING_ENABLED) // With XR single-pass, one 3D buffer is used to store all views (split along w) @@ -51,6 +53,8 @@ float4 SampleVBuffer(TEXTURE3D_PARAM(VBuffer, clampSampler), w = clamp(w, lowerSliceRange + limitSliceRange, upperSliceRange - limitSliceRange); #endif + float4 result = 0; + if (coordIsInsideFrustum) { if (quadraticFilterXY) @@ -62,21 +66,30 @@ float4 SampleVBuffer(TEXTURE3D_PARAM(VBuffer, clampSampler), float2 weights[2], offsets[2]; BiquadraticFilter(1 - fc, weights, offsets); // Inverse-translate the filter centered around 0.5 - const float2 ssToUv = VBufferViewportSize.zw * VBufferUvScale; + // Don't want to pass another shader parameter... + const float2 rcpBufDim = VBufferViewportScale.xy * VBufferViewportSize.zw; // (vp_dim / buf_dim) * (1 / vp_dim) + + // And these are the texture coordinates. + // TODO: will the compiler eliminate redundant computations? + float2 texUv0 = (ic + float2(offsets[0].x, offsets[0].y)) * rcpBufDim; // Top left + float2 texUv1 = (ic + float2(offsets[1].x, offsets[0].y)) * rcpBufDim; // Top right + float2 texUv2 = (ic + float2(offsets[0].x, offsets[1].y)) * rcpBufDim; // Bottom left + float2 texUv3 = (ic + float2(offsets[1].x, offsets[1].y)) * rcpBufDim; // Bottom right + float texW = w * VBufferViewportScale.z; - // The sampler clamps to edge. This takes care of 4 frustum faces out of 6. - // Due to the RTHandle scaling system, we must take care of the other 2 manually. + // The sampler clamps to the edge (so UVWs < 0 are OK). // TODO: perform per-sample (4, in this case) bilateral filtering, rather than per-pixel. This should reduce leaking. - result = (weights[0].x * weights[0].y) * SAMPLE_TEXTURE3D_LOD(VBuffer, clampSampler, float3(min((ic + float2(offsets[0].x, offsets[0].y)) * ssToUv, VBufferUvLimit), w), 0) // Top left - + (weights[1].x * weights[0].y) * SAMPLE_TEXTURE3D_LOD(VBuffer, clampSampler, float3(min((ic + float2(offsets[1].x, offsets[0].y)) * ssToUv, VBufferUvLimit), w), 0) // Top right - + (weights[0].x * weights[1].y) * SAMPLE_TEXTURE3D_LOD(VBuffer, clampSampler, float3(min((ic + float2(offsets[0].x, offsets[1].y)) * ssToUv, VBufferUvLimit), w), 0) // Bottom left - + (weights[1].x * weights[1].y) * SAMPLE_TEXTURE3D_LOD(VBuffer, clampSampler, float3(min((ic + float2(offsets[1].x, offsets[1].y)) * ssToUv, VBufferUvLimit), w), 0); // Bottom right + result = (weights[0].x * weights[0].y) * SAMPLE_TEXTURE3D_LOD(VBuffer, clampSampler, min(float3(texUv0, texW), VBufferViewportLimit), 0) + + (weights[1].x * weights[0].y) * SAMPLE_TEXTURE3D_LOD(VBuffer, clampSampler, min(float3(texUv1, texW), VBufferViewportLimit), 0) + + (weights[0].x * weights[1].y) * SAMPLE_TEXTURE3D_LOD(VBuffer, clampSampler, min(float3(texUv2, texW), VBufferViewportLimit), 0) + + (weights[1].x * weights[1].y) * SAMPLE_TEXTURE3D_LOD(VBuffer, clampSampler, min(float3(texUv3, texW), VBufferViewportLimit), 0); } else { - // The sampler clamps to edge. This takes care of 4 frustum faces out of 6. - // Due to the RTHandle scaling system, we must take care of the other 2 manually. - result = SAMPLE_TEXTURE3D_LOD(VBuffer, clampSampler, float3(min(uv * VBufferUvScale, VBufferUvLimit), w), 0); + // And these are the texture coordinates. + float3 texUVW = float3(uv, w) * VBufferViewportScale; + // The sampler clamps to the edge (so UVWs < 0 are OK). + result = SAMPLE_TEXTURE3D_LOD(VBuffer, clampSampler, min(texUVW, VBufferViewportLimit), 0); } } @@ -88,22 +101,22 @@ float4 SampleVBuffer(TEXTURE3D_PARAM(VBuffer, clampSampler), float3 cameraPositionWS, float4x4 viewProjMatrix, float4 VBufferViewportSize, - float2 VBufferUvScale, - float2 VBufferUvLimit, + float3 VBufferViewportScale, + float3 VBufferViewportLimit, float4 VBufferDistanceEncodingParams, float4 VBufferDistanceDecodingParams, bool quadraticFilterXY, bool clampToBorder) { - float2 positionNDC = ComputeNormalizedDeviceCoordinates(positionWS, viewProjMatrix); + float2 positionNDC = ComputeNormalizedDeviceCoordinates(positionWS, viewProjMatrix); float linearDistance = distance(positionWS, cameraPositionWS); return SampleVBuffer(TEXTURE3D_ARGS(VBuffer, clampSampler), positionNDC, linearDistance, VBufferViewportSize, - VBufferUvScale, - VBufferUvLimit, + VBufferViewportScale, + VBufferViewportLimit, VBufferDistanceEncodingParams, VBufferDistanceDecodingParams, quadraticFilterXY, diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute index 34412ab0e94..389bee6981d 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute @@ -585,8 +585,8 @@ void FillVolumetricLightingBuffer(LightLoopContext context, uint featureFlags, _PrevCamPosRWS, UNITY_MATRIX_PREV_VP, _VBufferPrevViewportSize, - _VBufferHistoryUvScaleAndLimit.xy, - _VBufferHistoryUvScaleAndLimit.zw, + _VBufferHistoryViewportScale, + _VBufferHistoryViewportLimit, _VBufferPrevDepthEncodingParams, _VBufferPrevDepthDecodingParams, false, true) * float4(GetInversePreviousExposureMultiplier().xxx, 1); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs index 3f0dc550166..13a9b4693c5 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs @@ -113,10 +113,18 @@ public VBufferParameters(Vector3Int viewportSize, float depthExtent, float camNe depthDecodingParams = ComputeLogarithmicDepthDecodingParams(nearDist, farDist, c); } - internal Vector4 ComputeUvScaleAndLimit(Vector2Int bufferSize) + internal Vector3 ComputeViewportScale(Vector3Int bufferSize) { - // The slice count is fixed for now. - return HDUtils.ComputeUvScaleAndLimit(new Vector2Int(viewportSize.x, viewportSize.y), bufferSize); + return new Vector3(HDUtils.ComputeViewportScale(viewportSize.x, bufferSize.x), + HDUtils.ComputeViewportScale(viewportSize.y, bufferSize.y), + HDUtils.ComputeViewportScale(viewportSize.z, bufferSize.z)); + } + + internal Vector3 ComputeViewportLimit(Vector3Int bufferSize) + { + return new Vector3(HDUtils.ComputeViewportLimit(viewportSize.x, bufferSize.x), + HDUtils.ComputeViewportLimit(viewportSize.y, bufferSize.y), + HDUtils.ComputeViewportLimit(viewportSize.z, bufferSize.z)); } internal float ComputeLastSliceDistance(int sliceCount) @@ -554,23 +562,23 @@ void PushVolumetricLightingGlobalParams(HDCamera hdCamera, CommandBuffer cmd, in // The viewport size is the same for all of these buffers. // All of these buffers may have sub-native-resolution viewports. // The 3rd dimension (number of slices) is the same for all of these buffers. - Vector2Int sharedBufferSize = new Vector2Int(m_LightingBuffer.width, m_LightingBuffer.height); + Vector3Int lightingBufferSize = new Vector3Int(m_LightingBuffer.width, m_LightingBuffer.height, m_LightingBuffer.volumeDepth); Debug.Assert(m_LightingBuffer.width == m_DensityBuffer.width); Debug.Assert(m_LightingBuffer.height == m_DensityBuffer.height); - Vector2Int historyBufferSize = Vector2Int.zero; + Vector3Int historyBufferSize = Vector3Int.zero; if (hdCamera.IsVolumetricReprojectionEnabled()) { RenderTexture historyRT = hdCamera.volumetricHistoryBuffers[prevIdx]; - historyBufferSize = new Vector2Int(historyRT.width, historyRT.height); + historyBufferSize = new Vector3Int(historyRT.width, historyRT.height, historyRT.volumeDepth); // Handle case of first frame. When we are on the first frame, we reuse the value of original frame. if (historyBufferSize.x == 0.0f && historyBufferSize.y == 0.0f) { - historyBufferSize = sharedBufferSize; + historyBufferSize = lightingBufferSize; } } @@ -583,18 +591,20 @@ void PushVolumetricLightingGlobalParams(HDCamera hdCamera, CommandBuffer cmd, in cmd.SetGlobalVector(HDShaderIDs._VBufferViewportSize, new Vector4(cvp.x, cvp.y, 1.0f / cvp.x, 1.0f / cvp.y)); cmd.SetGlobalInt( HDShaderIDs._VBufferSliceCount, sliceCount); cmd.SetGlobalFloat( HDShaderIDs._VBufferRcpSliceCount, 1.0f / sliceCount); - cmd.SetGlobalVector(HDShaderIDs._VBufferSharedUvScaleAndLimit, currFrameParams.ComputeUvScaleAndLimit(sharedBufferSize)); + cmd.SetGlobalVector(HDShaderIDs._VBufferLightingViewportScale, currFrameParams.ComputeViewportScale(lightingBufferSize)); + cmd.SetGlobalVector(HDShaderIDs._VBufferLightingViewportLimit, currFrameParams.ComputeViewportLimit(lightingBufferSize)); cmd.SetGlobalVector(HDShaderIDs._VBufferDistanceEncodingParams, currFrameParams.depthEncodingParams); cmd.SetGlobalVector(HDShaderIDs._VBufferDistanceDecodingParams, currFrameParams.depthDecodingParams); cmd.SetGlobalFloat( HDShaderIDs._VBufferLastSliceDist, currFrameParams.ComputeLastSliceDistance(sliceCount)); cmd.SetGlobalFloat( HDShaderIDs._VBufferRcpInstancedViewCount, 1.0f / hdCamera.viewCount); cmd.SetGlobalVector(HDShaderIDs._VBufferPrevViewportSize, new Vector4(pvp.x, pvp.y, 1.0f / pvp.x, 1.0f / pvp.y)); - cmd.SetGlobalVector(HDShaderIDs._VBufferHistoryUvScaleAndLimit, prevFrameParams.ComputeUvScaleAndLimit(historyBufferSize)); + cmd.SetGlobalVector(HDShaderIDs._VBufferHistoryViewportScale, prevFrameParams.ComputeViewportScale(historyBufferSize)); + cmd.SetGlobalVector(HDShaderIDs._VBufferHistoryViewportLimit, prevFrameParams.ComputeViewportLimit(historyBufferSize)); cmd.SetGlobalVector(HDShaderIDs._VBufferPrevDepthEncodingParams, prevFrameParams.depthEncodingParams); cmd.SetGlobalVector(HDShaderIDs._VBufferPrevDepthDecodingParams, prevFrameParams.depthDecodingParams); - cmd.SetGlobalTexture(HDShaderIDs._VBufferLighting, m_LightingBuffer); + cmd.SetGlobalTexture(HDShaderIDs._VBufferLighting, m_LightingBuffer); } DensityVolumeList PrepareVisibleDensityVolumeList(HDCamera hdCamera, CommandBuffer cmd, float time) 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 b2c39685589..deb05fc753b 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -3743,7 +3743,7 @@ RenderSSRParameters PrepareSSRParameters(HDCamera hdCamera) parameters.roughnessFadeRcpLength = (roughnessFadeLength != 0) ? (1.0f / roughnessFadeLength) : 0; parameters.edgeFadeRcpLength = Mathf.Min(1.0f / volumeSettings.screenFadeDistance.value, float.MaxValue); - parameters.colorPyramidUVScaleAndLimit = HDUtils.ComputeUvScaleAndLimit(hdCamera.historyRTHandleProperties.previousViewportSize, hdCamera.historyRTHandleProperties.previousRenderTargetSize); + parameters.colorPyramidUVScaleAndLimit = HDUtils.ComputeViewportScaleAndLimit(hdCamera.historyRTHandleProperties.previousViewportSize, hdCamera.historyRTHandleProperties.previousRenderTargetSize); parameters.colorPyramidMipCount = hdCamera.colorPyramidHistoryMipCount; return parameters; 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 3eed7f9a055..e74e16bb9a3 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs @@ -497,11 +497,13 @@ static class HDShaderIDs public static readonly int _VBufferSliceCount = Shader.PropertyToID("_VBufferSliceCount"); public static readonly int _VBufferRcpSliceCount = Shader.PropertyToID("_VBufferRcpSliceCount"); public static readonly int _VBufferRcpInstancedViewCount = Shader.PropertyToID("_VBufferRcpInstancedViewCount"); - public static readonly int _VBufferSharedUvScaleAndLimit = Shader.PropertyToID("_VBufferSharedUvScaleAndLimit"); + public static readonly int _VBufferLightingViewportScale = Shader.PropertyToID("_VBufferLightingViewportScale"); + public static readonly int _VBufferLightingViewportLimit = Shader.PropertyToID("_VBufferLightingViewportLimit"); public static readonly int _VBufferDistanceEncodingParams = Shader.PropertyToID("_VBufferDistanceEncodingParams"); public static readonly int _VBufferDistanceDecodingParams = Shader.PropertyToID("_VBufferDistanceDecodingParams"); public static readonly int _VBufferPrevViewportSize = Shader.PropertyToID("_VBufferPrevViewportSize"); - public static readonly int _VBufferHistoryUvScaleAndLimit = Shader.PropertyToID("_VBufferHistoryUvScaleAndLimit"); + public static readonly int _VBufferHistoryViewportScale = Shader.PropertyToID("_VBufferHistoryViewportScale"); + public static readonly int _VBufferHistoryViewportLimit = Shader.PropertyToID("_VBufferHistoryViewportLimit"); public static readonly int _VBufferPrevDepthEncodingParams = Shader.PropertyToID("_VBufferPrevDepthEncodingParams"); public static readonly int _VBufferPrevDepthDecodingParams = Shader.PropertyToID("_VBufferPrevDepthDecodingParams"); public static readonly int _VBufferLastSliceDist = Shader.PropertyToID("_VBufferLastSliceDist"); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs index 59ca696143d..3389ef63a35 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs @@ -554,21 +554,31 @@ internal static void CheckRTCreated(RenderTexture rt) rt.Create(); } - internal static Vector4 ComputeUvScaleAndLimit(Vector2Int viewportResolution, Vector2Int bufferSize) + internal static float ComputeViewportScale(int viewportSize, int bufferSize) { - Vector2 rcpBufferSize = new Vector2(1.0f / bufferSize.x, 1.0f / bufferSize.y); + float rcpBufferSize = 1.0f / bufferSize; - // vp_scale = vp_dim / tex_dim. - Vector2 uvScale = new Vector2(viewportResolution.x * rcpBufferSize.x, - viewportResolution.y * rcpBufferSize.y); + // Scale by (vp_dim / buf_dim). + return viewportSize * rcpBufferSize; + } + + internal static float ComputeViewportLimit(int viewportSize, int bufferSize) + { + float rcpBufferSize = 1.0f / bufferSize; - // clamp to (vp_dim - 0.5) / tex_dim. - Vector2 uvLimit = new Vector2((viewportResolution.x - 0.5f) * rcpBufferSize.x, - (viewportResolution.y - 0.5f) * rcpBufferSize.y); + // Clamp to (vp_dim - 0.5) / buf_dim. + return (viewportSize - 0.5f) * rcpBufferSize; + } - return new Vector4(uvScale.x, uvScale.y, uvLimit.x, uvLimit.y); + internal static Vector4 ComputeViewportScaleAndLimit(Vector2Int viewportSize, Vector2Int bufferSize) + { + return new Vector4(ComputeViewportScale(viewportSize.x, bufferSize.x), // Scale(x) + ComputeViewportScale(viewportSize.y, bufferSize.y), // Scale(y) + ComputeViewportLimit(viewportSize.x, bufferSize.x), // Limit(x) + ComputeViewportLimit(viewportSize.y, bufferSize.y)); // Limit(y) } + #if UNITY_EDITOR // This function can't be in HDEditorUtils because we need it in HDRenderPipeline.cs (and HDEditorUtils is in an editor asmdef) internal static bool IsSupportedBuildTarget(UnityEditor.BuildTarget buildTarget) diff --git a/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl b/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl index 358140d5413..e425c54a758 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl @@ -245,7 +245,8 @@ CBUFFER_START(UnityGlobal) float _VBufferRcpInstancedViewCount; // Used to remap VBuffer coordinates for XR float _ContactShadowOpacity; - float4 _VBufferSharedUvScaleAndLimit; // Necessary us to work with sub-allocation (resource aliasing) in the RTHandle system + float3 _VBufferLightingViewportScale; // Necessary to support sub-allocation of the RT system + float3 _VBufferLightingViewportLimit; // Necessary to support sub-allocation of the RT system float4 _VBufferDistanceEncodingParams; // See the call site for description float4 _VBufferDistanceDecodingParams; // See the call site for description @@ -254,7 +255,8 @@ CBUFFER_START(UnityGlobal) // Once reprojection is performed in a separate pass, we should probably // move these to a dedicated CBuffer to avoid polluting the global one. float4 _VBufferPrevViewportSize; - float4 _VBufferHistoryUvScaleAndLimit; + float3 _VBufferHistoryViewportScale; // Necessary to support sub-allocation of the RT system + float3 _VBufferHistoryViewportLimit; // Necessary to support sub-allocation of the RT system float4 _VBufferPrevDepthEncodingParams; float4 _VBufferPrevDepthDecodingParams; From f14b2d248b58d46521483157b4ef4c3c5d6ca01f Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Wed, 26 Feb 2020 16:39:39 -0800 Subject: [PATCH 28/63] Dynamic res works --- .../VolumeVoxelization.compute | 29 ++++--- .../VolumetricLighting.compute | 73 +++++++++--------- .../VolumetricLighting/VolumetricLighting.cs | 76 +++++++++---------- .../Runtime/RenderPipeline/Camera/HDCamera.cs | 2 +- .../HDRenderPipeline.LightLoop.cs | 6 +- .../RenderPipeline/HDStringConstants.cs | 1 + .../ShaderLibrary/ShaderVariables.hlsl | 5 +- 7 files changed, 92 insertions(+), 100 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumeVoxelization.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumeVoxelization.compute index e726a1d0772..420eeeae444 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumeVoxelization.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumeVoxelization.compute @@ -5,24 +5,21 @@ // #pragma enable_d3d11_debug_symbols #pragma only_renderers d3d11 ps4 xboxone vulkan metal switch -#pragma kernel VolumeVoxelizationBruteforceMQ VolumeVoxelization=VolumeVoxelizationBruteforceMQ LIGHTLOOP_DISABLE_TILE_AND_CLUSTER VL_PRESET_MQ -#pragma kernel VolumeVoxelizationTiledMQ VolumeVoxelization=VolumeVoxelizationTiledMQ VL_PRESET_MQ -#pragma kernel VolumeVoxelizationBruteforceHQ VolumeVoxelization=VolumeVoxelizationBruteforceHQ LIGHTLOOP_DISABLE_TILE_AND_CLUSTER VL_PRESET_HQ -#pragma kernel VolumeVoxelizationTiledHQ VolumeVoxelization=VolumeVoxelizationTiledHQ VL_PRESET_HQ +#pragma kernel VolumeVoxelizationBruteforceOptimal VolumeVoxelization=VolumeVoxelizationBruteforceOptimal LIGHTLOOP_DISABLE_TILE_AND_CLUSTER VL_PRESET_OPTIMAL +#pragma kernel VolumeVoxelizationTiledOptimal VolumeVoxelization=VolumeVoxelizationTiledOptimal VL_PRESET_OPTIMAL +#pragma kernel VolumeVoxelizationBruteforce VolumeVoxelization=VolumeVoxelizationBruteforce LIGHTLOOP_DISABLE_TILE_AND_CLUSTER +#pragma kernel VolumeVoxelizationTiled VolumeVoxelization=VolumeVoxelizationTiled #ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER #define USE_BIG_TILE_LIGHTLIST #endif -#ifdef VL_PRESET_MQ - // E.g. for 1080p: (1920/8)x(1080/8)x(64) = 2,073,600 voxels - // Same texel count as in a 1080p frame buffer. +#ifdef VL_PRESET_OPTIMAL + // E.g. for 1080p: (1920/8)x(1080/8)x(64) = 2,073,600 voxels #define VBUFFER_TILE_SIZE 8 -#endif -#ifdef VL_PRESET_HQ - // E.g. for 1080p: (1920/4)x(1080/4)x(128) = 16,588,800 voxels - // Double the texel count of a 4K frame buffer! - #define VBUFFER_TILE_SIZE 4 +#else + // No compile-time optimizations, no scalarization. + #define VBUFFER_TILE_SIZE _VBufferTileSize #endif #define GROUP_SIZE_1D 8 @@ -335,14 +332,14 @@ void VolumeVoxelization(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 groupId : SV_GroupID, uint2 groupThreadId : SV_GroupThreadID) { - // Perform compile-time checks. - if (!IsPower2(VBUFFER_TILE_SIZE) || !IsPower2(TILE_SIZE_BIG_TILE)) return; - UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadId.z); uint2 groupOffset = groupId * GROUP_SIZE_1D; uint2 voxelCoord = groupOffset + groupThreadId; - uint2 tileCoord = groupOffset * VBUFFER_TILE_SIZE / TILE_SIZE_BIG_TILE; + // Note that if VBUFFER_TILE_SIZE is not an integer, a voxel may straddle a tile boundary. + // This means different voxel subsamples may belong to different tiles. + // We accept this error, and simply use the coordinates of the corner of the voxel. + uint2 tileCoord = (uint2)(groupOffset * (VBUFFER_TILE_SIZE / TILE_SIZE_BIG_TILE)); uint tileIndex = tileCoord.x + _NumTileBigTileX * tileCoord.y; // Reminder: our voxels are sphere-capped right frustums (truncated right pyramids). diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute index 389bee6981d..ec3f28345ea 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute @@ -5,53 +5,48 @@ // #pragma enable_d3d11_debug_symbols #pragma only_renderers d3d11 ps4 xboxone vulkan metal switch -#pragma kernel VolumetricLightingBruteforceMQ VolumetricLighting=VolumetricLightingBruteforceMQ LIGHTLOOP_DISABLE_TILE_AND_CLUSTER ENABLE_REPROJECTION=0 ENABLE_ANISOTROPY=0 VL_PRESET_MQ -#pragma kernel VolumetricLightingTiledMQ VolumetricLighting=VolumetricLightingTiledMQ ENABLE_REPROJECTION=0 ENABLE_ANISOTROPY=0 VL_PRESET_MQ -#pragma kernel VolumetricLightingBruteforceReprojMQ VolumetricLighting=VolumetricLightingBruteforceReprojMQ LIGHTLOOP_DISABLE_TILE_AND_CLUSTER ENABLE_REPROJECTION=1 ENABLE_ANISOTROPY=0 VL_PRESET_MQ -#pragma kernel VolumetricLightingTiledReprojMQ VolumetricLighting=VolumetricLightingTiledReprojMQ ENABLE_REPROJECTION=1 ENABLE_ANISOTROPY=0 VL_PRESET_MQ +#pragma kernel VolumetricLightingBruteforceOptimal VolumetricLighting=VolumetricLightingBruteforceOptimal LIGHTLOOP_DISABLE_TILE_AND_CLUSTER ENABLE_REPROJECTION=0 ENABLE_ANISOTROPY=0 VL_PRESET_OPTIMAL +#pragma kernel VolumetricLightingTiledOptimal VolumetricLighting=VolumetricLightingTiledOptimal ENABLE_REPROJECTION=0 ENABLE_ANISOTROPY=0 VL_PRESET_OPTIMAL +#pragma kernel VolumetricLightingBruteforceReprojOptimal VolumetricLighting=VolumetricLightingBruteforceReprojOptimal LIGHTLOOP_DISABLE_TILE_AND_CLUSTER ENABLE_REPROJECTION=1 ENABLE_ANISOTROPY=0 VL_PRESET_OPTIMAL +#pragma kernel VolumetricLightingTiledReprojOptimal VolumetricLighting=VolumetricLightingTiledReprojOptimal ENABLE_REPROJECTION=1 ENABLE_ANISOTROPY=0 VL_PRESET_OPTIMAL -#pragma kernel VolumetricLightingBruteforceAnisoMQ VolumetricLighting=VolumetricLightingBruteforceAnisoMQ LIGHTLOOP_DISABLE_TILE_AND_CLUSTER ENABLE_REPROJECTION=0 ENABLE_ANISOTROPY=1 VL_PRESET_MQ -#pragma kernel VolumetricLightingTiledAnisoMQ VolumetricLighting=VolumetricLightingTiledAnisoMQ ENABLE_REPROJECTION=0 ENABLE_ANISOTROPY=1 VL_PRESET_MQ -#pragma kernel VolumetricLightingBruteforceReprojAnisoMQ VolumetricLighting=VolumetricLightingBruteforceReprojAnisoMQ LIGHTLOOP_DISABLE_TILE_AND_CLUSTER ENABLE_REPROJECTION=1 ENABLE_ANISOTROPY=1 VL_PRESET_MQ -#pragma kernel VolumetricLightingTiledReprojAnisoMQ VolumetricLighting=VolumetricLightingTiledReprojAnisoMQ ENABLE_REPROJECTION=1 ENABLE_ANISOTROPY=1 VL_PRESET_MQ +#pragma kernel VolumetricLightingBruteforceAnisoOptimal VolumetricLighting=VolumetricLightingBruteforceAnisoOptimal LIGHTLOOP_DISABLE_TILE_AND_CLUSTER ENABLE_REPROJECTION=0 ENABLE_ANISOTROPY=1 VL_PRESET_OPTIMAL +#pragma kernel VolumetricLightingTiledAnisoOptimal VolumetricLighting=VolumetricLightingTiledAnisoOptimal ENABLE_REPROJECTION=0 ENABLE_ANISOTROPY=1 VL_PRESET_OPTIMAL +#pragma kernel VolumetricLightingBruteforceReprojAnisoOptimal VolumetricLighting=VolumetricLightingBruteforceReprojAnisoOptimal LIGHTLOOP_DISABLE_TILE_AND_CLUSTER ENABLE_REPROJECTION=1 ENABLE_ANISOTROPY=1 VL_PRESET_OPTIMAL +#pragma kernel VolumetricLightingTiledReprojAnisoOptimal VolumetricLighting=VolumetricLightingTiledReprojAnisoOptimal ENABLE_REPROJECTION=1 ENABLE_ANISOTROPY=1 VL_PRESET_OPTIMAL -#pragma kernel VolumetricLightingBruteforceHQ VolumetricLighting=VolumetricLightingBruteforceHQ LIGHTLOOP_DISABLE_TILE_AND_CLUSTER ENABLE_REPROJECTION=0 ENABLE_ANISOTROPY=0 VL_PRESET_HQ -#pragma kernel VolumetricLightingTiledHQ VolumetricLighting=VolumetricLightingTiledHQ ENABLE_REPROJECTION=0 ENABLE_ANISOTROPY=0 VL_PRESET_HQ -#pragma kernel VolumetricLightingBruteforceReprojHQ VolumetricLighting=VolumetricLightingBruteforceReprojHQ LIGHTLOOP_DISABLE_TILE_AND_CLUSTER ENABLE_REPROJECTION=1 ENABLE_ANISOTROPY=0 VL_PRESET_HQ -#pragma kernel VolumetricLightingTiledReprojHQ VolumetricLighting=VolumetricLightingTiledReprojHQ ENABLE_REPROJECTION=1 ENABLE_ANISOTROPY=0 VL_PRESET_HQ +#pragma kernel VolumetricLightingBruteforce VolumetricLighting=VolumetricLightingBruteforce LIGHTLOOP_DISABLE_TILE_AND_CLUSTER ENABLE_REPROJECTION=0 ENABLE_ANISOTROPY=0 +#pragma kernel VolumetricLightingTiled VolumetricLighting=VolumetricLightingTiled ENABLE_REPROJECTION=0 ENABLE_ANISOTROPY=0 +#pragma kernel VolumetricLightingBruteforceReproj VolumetricLighting=VolumetricLightingBruteforceReproj LIGHTLOOP_DISABLE_TILE_AND_CLUSTER ENABLE_REPROJECTION=1 ENABLE_ANISOTROPY=0 +#pragma kernel VolumetricLightingTiledReproj VolumetricLighting=VolumetricLightingTiledReproj ENABLE_REPROJECTION=1 ENABLE_ANISOTROPY=0 -#pragma kernel VolumetricLightingBruteforceAnisoHQ VolumetricLighting=VolumetricLightingBruteforceAnisoHQ LIGHTLOOP_DISABLE_TILE_AND_CLUSTER ENABLE_REPROJECTION=0 ENABLE_ANISOTROPY=1 VL_PRESET_HQ -#pragma kernel VolumetricLightingTiledAnisoHQ VolumetricLighting=VolumetricLightingTiledAnisoHQ ENABLE_REPROJECTION=0 ENABLE_ANISOTROPY=1 VL_PRESET_HQ -#pragma kernel VolumetricLightingBruteforceReprojAnisoHQ VolumetricLighting=VolumetricLightingBruteforceReprojAnisoHQ LIGHTLOOP_DISABLE_TILE_AND_CLUSTER ENABLE_REPROJECTION=1 ENABLE_ANISOTROPY=1 VL_PRESET_HQ -#pragma kernel VolumetricLightingTiledReprojAnisoHQ VolumetricLighting=VolumetricLightingTiledReprojAnisoHQ ENABLE_REPROJECTION=1 ENABLE_ANISOTROPY=1 VL_PRESET_HQ +#pragma kernel VolumetricLightingBruteforceAniso VolumetricLighting=VolumetricLightingBruteforceAniso LIGHTLOOP_DISABLE_TILE_AND_CLUSTER ENABLE_REPROJECTION=0 ENABLE_ANISOTROPY=1 +#pragma kernel VolumetricLightingTiledAniso VolumetricLighting=VolumetricLightingTiledAniso ENABLE_REPROJECTION=0 ENABLE_ANISOTROPY=1 +#pragma kernel VolumetricLightingBruteforceReprojAniso VolumetricLighting=VolumetricLightingBruteforceReprojAniso LIGHTLOOP_DISABLE_TILE_AND_CLUSTER ENABLE_REPROJECTION=1 ENABLE_ANISOTROPY=1 +#pragma kernel VolumetricLightingTiledReprojAniso VolumetricLighting=VolumetricLightingTiledReprojAniso ENABLE_REPROJECTION=1 ENABLE_ANISOTROPY=1 -#pragma kernel FilterVolumetricLightingX FilterVolumetricLighting=FilterVolumetricLightingX LIGHTLOOP_DISABLE_TILE_AND_CLUSTER VL_PRESET_HQ -#pragma kernel FilterVolumetricLightingY FilterVolumetricLighting=FilterVolumetricLightingY LIGHTLOOP_DISABLE_TILE_AND_CLUSTER VL_PRESET_HQ VERTICAL_PASS - -#ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER - #define USE_BIG_TILE_LIGHTLIST -#endif +#pragma kernel FilterVolumetricLightingX FilterVolumetricLighting=FilterVolumetricLightingX LIGHTLOOP_DISABLE_TILE_AND_CLUSTER +#pragma kernel FilterVolumetricLightingY FilterVolumetricLighting=FilterVolumetricLightingY LIGHTLOOP_DISABLE_TILE_AND_CLUSTER VERTICAL_PASS // Don't want contact shadows #define LIGHT_EVALUATION_NO_CONTACT_SHADOWS // To define before LightEvaluation.hlsl -#ifdef VL_PRESET_MQ - // E.g. for 1080p: (1920/8)x(1080/8)x(64) = 2,073,600 voxels - // Same texel count as in a 1080p frame buffer. - #define VBUFFER_TILE_SIZE 8 -#endif -#ifdef VL_PRESET_HQ - // E.g. for 1080p: (1920/4)x(1080/4)x(128) = 16,588,800 voxels - // Double the texel count of a 4K frame buffer! - #define VBUFFER_TILE_SIZE 4 +#ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER + #define USE_BIG_TILE_LIGHTLIST #endif -#define GROUP_SIZE_1D 8 -#define SUPPORT_LOCAL_LIGHTS 1 // Local lights contribute to fog lighting +#ifdef VL_PRESET_OPTIMAL + // E.g. for 1080p: (1920/8)x(1080/8)x(64) = 2,073,600 voxels + #define VBUFFER_TILE_SIZE 8 +#else -#define SHADOW_USE_DEPTH_BIAS 0 + #define VBUFFER_TILE_SIZE _VBufferTileSize +#endif -#define PREFER_HALF 0 +#define GROUP_SIZE_1D 8 +#define SUPPORT_LOCAL_LIGHTS 1 // Local lights contribute to fog lighting +#define SHADOW_USE_DEPTH_BIAS 0 +#define PREFER_HALF 0 //-------------------------------------------------------------------------------------------------- // Included headers @@ -675,14 +670,14 @@ void VolumetricLighting(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 groupId : SV_GroupID, uint2 groupThreadId : SV_GroupThreadID) { - // Perform compile-time checks. - if (!IsPower2(VBUFFER_TILE_SIZE) || !IsPower2(TILE_SIZE_BIG_TILE)) return; - UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadId.z); uint2 groupOffset = groupId * GROUP_SIZE_1D; uint2 voxelCoord = groupOffset + groupThreadId; - uint2 tileCoord = groupOffset * VBUFFER_TILE_SIZE / TILE_SIZE_BIG_TILE; + // Note that if VBUFFER_TILE_SIZE is not an integer, a voxel may straddle a tile boundary. + // This means different voxel subsamples may belong to different tiles. + // We accept this error, and simply use the coordinates of the corner of the voxel. + uint2 tileCoord = (uint2)(groupOffset * (VBUFFER_TILE_SIZE / TILE_SIZE_BIG_TILE)); uint tileIndex = tileCoord.x + _NumTileBigTileX * tileCoord.y; // Reminder: our voxels are sphere-capped right frustums (truncated right pyramids). diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs index 13a9b4693c5..c91b53798ca 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs @@ -85,14 +85,14 @@ enum VolumetricLightingPreset struct VBufferParameters { public Vector3Int viewportSize; - public int frameIndex; + public float tileSize; public Vector4 depthEncodingParams; public Vector4 depthDecodingParams; - public VBufferParameters(Vector3Int viewportSize, float depthExtent, float camNear, float camFar, float camVFoV, float sliceDistributionUniformity, int frameIndex) + public VBufferParameters(Vector3Int viewportSize, float depthExtent, float camNear, float camFar, float camVFoV, float sliceDistributionUniformity, float tileSize) { this.viewportSize = viewportSize; - this.frameIndex = frameIndex; + this.tileSize = tileSize; // The V-Buffer is sphere-capped, while the camera frustum is not. // We always start from the near plane of the camera. @@ -242,7 +242,7 @@ static internal int RoundToNearestInt(float f) return (int)(f + 0.5f); } - static internal Vector3Int ComputeVolumetricViewportSize(HDCamera hdCamera) + static internal Vector3Int ComputeVolumetricViewportSize(HDCamera hdCamera, ref float tileSize) { var controller = hdCamera.volumeStack.GetComponent(); Debug.Assert(controller != null); @@ -256,24 +256,31 @@ static internal Vector3Int ComputeVolumetricViewportSize(HDCamera hdCamera) int h = RoundToNearestInt(viewportHeight * screenFraction); int d = sliceCount; + if (controller.screenResolutionPercentage.value == (1.0f/8.0f) * 100) + tileSize = 8; + else + tileSize = 1.0f / screenFraction; // Does not account for rounding + return new Vector3Int(w, h, d); } - static internal VBufferParameters ComputeVolumetricBufferParameters(HDCamera hdCamera, int frameIndex) + static internal VBufferParameters ComputeVolumetricBufferParameters(HDCamera hdCamera) { var controller = hdCamera.volumeStack.GetComponent(); Debug.Assert(controller != null); - Vector3Int viewportSize = ComputeVolumetricViewportSize(hdCamera); + float tileSize = 0; + Vector3Int viewportSize = ComputeVolumetricViewportSize(hdCamera, ref tileSize); return new VBufferParameters(viewportSize, controller.depthExtent.value, hdCamera.camera.nearClipPlane, hdCamera.camera.farClipPlane, hdCamera.camera.fieldOfView, - controller.sliceDistributionUniformity.value, frameIndex); + controller.sliceDistributionUniformity.value, + tileSize); } - static internal void ReinitializeVolumetricBufferParams(HDCamera hdCamera, int frameIndex) + static internal void ReinitializeVolumetricBufferParams(HDCamera hdCamera) { if (!Fog.IsVolumetricFogEnabled(hdCamera)) return; @@ -292,7 +299,7 @@ static internal void ReinitializeVolumetricBufferParams(HDCamera hdCamera, int f { // Initialize. // Start with the same parameters for both frames. Then update them one by one every frame. - var parameters = ComputeVolumetricBufferParameters(hdCamera, frameIndex); + var parameters = ComputeVolumetricBufferParameters(hdCamera); hdCamera.vBufferParams = new VBufferParameters[2]; hdCamera.vBufferParams[0] = parameters; hdCamera.vBufferParams[1] = parameters; @@ -310,22 +317,12 @@ static internal void UpdateVolumetricBufferParams(HDCamera hdCamera, int frameIn Debug.Assert(hdCamera.vBufferParams != null); Debug.Assert(hdCamera.vBufferParams.Length == 2); - var currentParams = ComputeVolumetricBufferParameters(hdCamera, frameIndex); + var currentParams = ComputeVolumetricBufferParameters(hdCamera); var currIdx = (frameIndex + 0) & 1; var prevIdx = (frameIndex + 1) & 1; - if (hdCamera.vBufferParams[currIdx].frameIndex != frameIndex) - { - // Swap the two buffers. - hdCamera.vBufferParams[prevIdx] = hdCamera.vBufferParams[currIdx]; - hdCamera.vBufferParams[currIdx] = currentParams; - } - else - { - // Multiple updates per frame. Do not swap. - hdCamera.vBufferParams[currIdx] = currentParams; - } + hdCamera.vBufferParams[currIdx] = currentParams; // Handle case of first frame. When we are on the first frame, we reuse the value of original frame. if (hdCamera.vBufferParams[prevIdx].viewportSize.x == 0.0f && hdCamera.vBufferParams[prevIdx].viewportSize.y == 0.0f) @@ -407,7 +404,7 @@ static internal void DestroyVolumetricHistoryBuffers(HDCamera hdCamera) hdCamera.volumetricHistoryBuffers = null; } - // Must be called AFTER UpdateVolumetricBufferParams (which swaps and updates the parameters). + // Must be called AFTER UpdateVolumetricBufferParams. static internal void ResizeVolumetricHistoryBuffers(HDCamera hdCamera, int frameIndex) { if (hdCamera.volumetricHistoryBuffers == null) @@ -485,7 +482,7 @@ internal void DestroyVolumetricLightingBuffers() m_VisibleVolumeBounds = null; // free() } - // Must be called AFTER UpdateVolumetricBufferParams (which swaps and updates the parameters). + // Must be called AFTER UpdateVolumetricBufferParams. internal void ResizeVolumetricLightingBuffers(HDCamera hdCamera, int frameIndex) { if (!Fog.IsVolumetricFogEnabled(hdCamera)) @@ -557,11 +554,7 @@ void PushVolumetricLightingGlobalParams(HDCamera hdCamera, CommandBuffer cmd, in // The lighting & density buffers are shared by all cameras. // The history & feedback buffers are specific to the camera. // These 2 types of buffers can have different sizes. - // Additionally, history buffers can have different sizes, since they are not resized at the same time - // (every frame, we swap the buffers, and resize the feedback buffer but not the history buffer). - // The viewport size is the same for all of these buffers. - // All of these buffers may have sub-native-resolution viewports. - // The 3rd dimension (number of slices) is the same for all of these buffers. + // Additionally, history buffers can have different sizes, since they are not resized at the same time. Vector3Int lightingBufferSize = new Vector3Int(m_LightingBuffer.width, m_LightingBuffer.height, m_LightingBuffer.volumeDepth); Debug.Assert(m_LightingBuffer.width == m_DensityBuffer.width); @@ -591,6 +584,7 @@ void PushVolumetricLightingGlobalParams(HDCamera hdCamera, CommandBuffer cmd, in cmd.SetGlobalVector(HDShaderIDs._VBufferViewportSize, new Vector4(cvp.x, cvp.y, 1.0f / cvp.x, 1.0f / cvp.y)); cmd.SetGlobalInt( HDShaderIDs._VBufferSliceCount, sliceCount); cmd.SetGlobalFloat( HDShaderIDs._VBufferRcpSliceCount, 1.0f / sliceCount); + cmd.SetGlobalFloat( HDShaderIDs._VBufferTileSize, currFrameParams.tileSize); cmd.SetGlobalVector(HDShaderIDs._VBufferLightingViewportScale, currFrameParams.ComputeViewportScale(lightingBufferSize)); cmd.SetGlobalVector(HDShaderIDs._VBufferLightingViewportLimit, currFrameParams.ComputeViewportLimit(lightingBufferSize)); cmd.SetGlobalVector(HDShaderIDs._VBufferDistanceEncodingParams, currFrameParams.depthEncodingParams); @@ -686,20 +680,21 @@ VolumeVoxelizationParameters PrepareVolumeVoxelizationParameters(HDCamera hdCame { var parameters = new VolumeVoxelizationParameters(); + var currIdx = (frameIndex + 0) & 1; + var prevIdx = (frameIndex + 1) & 1; + + var currFrameParams = hdCamera.vBufferParams[currIdx]; + parameters.viewCount = hdCamera.viewCount; parameters.numBigTileX = GetNumTileBigTileX(hdCamera); parameters.numBigTileY = GetNumTileBigTileY(hdCamera); parameters.tiledLighting = HasLightToCull() && hdCamera.frameSettings.IsEnabled(FrameSettingsField.BigTilePrepass); - bool highQuality = volumetricLightingPreset == VolumetricLightingPreset.High; + bool optimal = currFrameParams.tileSize == 8; parameters.voxelizationCS = m_VolumeVoxelizationCS; - parameters.voxelizationKernel = (parameters.tiledLighting ? 1 : 0) | (highQuality ? 2 : 0); + parameters.voxelizationKernel = (parameters.tiledLighting ? 1 : 0) | (!optimal ? 2 : 0); - var currIdx = (frameIndex + 0) & 1; - var prevIdx = (frameIndex + 1) & 1; - - var currFrameParams = hdCamera.vBufferParams[currIdx]; var cvp = currFrameParams.viewportSize; parameters.resolution = new Vector4(cvp.x, cvp.y, 1.0f / cvp.x, 1.0f / cvp.y); @@ -833,6 +828,11 @@ VolumetricLightingParameters PrepareVolumetricLightingParameters(HDCamera hdCame { var parameters = new VolumetricLightingParameters(); + var currIdx = (frameIndex + 0) & 1; + var prevIdx = (frameIndex + 1) & 1; + + var currFrameParams = hdCamera.vBufferParams[currIdx]; + // Get the interpolated anisotropy value. var fog = hdCamera.volumeStack.GetComponent(); @@ -840,17 +840,13 @@ VolumetricLightingParameters PrepareVolumetricLightingParameters(HDCamera hdCame parameters.tiledLighting = hdCamera.frameSettings.IsEnabled(FrameSettingsField.BigTilePrepass); parameters.enableReprojection = hdCamera.IsVolumetricReprojectionEnabled(); bool enableAnisotropy = fog.anisotropy.value != 0; - bool highQuality = volumetricLightingPreset == VolumetricLightingPreset.High; + bool optimal = currFrameParams.tileSize == 8; parameters.volumetricLightingCS = m_VolumetricLightingCS; - parameters.volumetricLightingKernel = (parameters.tiledLighting ? 1 : 0) | (parameters.enableReprojection ? 2 : 0) | (enableAnisotropy ? 4 : 0) | (highQuality ? 8 : 0); + parameters.volumetricLightingKernel = (parameters.tiledLighting ? 1 : 0) | (parameters.enableReprojection ? 2 : 0) | (enableAnisotropy ? 4 : 0) | (!optimal ? 8 : 0); parameters.volumetricFilteringKernelX = 16; parameters.volumetricFilteringKernelY = 17; - var currIdx = (frameIndex + 0) & 1; - var prevIdx = (frameIndex + 1) & 1; - - var currFrameParams = hdCamera.vBufferParams[currIdx]; var cvp = currFrameParams.viewportSize; parameters.resolution = new Vector4(cvp.x, cvp.y, 1.0f / cvp.x, 1.0f / cvp.y); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs index 990269b1b6a..a29828a3e44 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs @@ -387,7 +387,7 @@ internal void Update(FrameSettings currentFrameSettings, HDRenderPipeline hdrp, { // Have to do this every frame in case the settings have changed. // The condition inside controls whether we perform init/deinit or not. - HDRenderPipeline.ReinitializeVolumetricBufferParams(this, hdrp.GetFrameCount()); + HDRenderPipeline.ReinitializeVolumetricBufferParams(this); bool isCurrentColorPyramidRequired = frameSettings.IsEnabled(FrameSettingsField.Refraction) || frameSettings.IsEnabled(FrameSettingsField.Distortion); bool isHistoryColorPyramidRequired = frameSettings.IsEnabled(FrameSettingsField.SSR) || antialiasing == AntialiasingMode.TemporalAntialiasing; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index e423d6d7258..196ce641aa2 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -385,7 +385,8 @@ RenderGraphResource VolumeVoxelizationPass( RenderGraph renderGraph, passData.visibleVolumeDataBuffer = visibleVolumeDataBuffer; passData.bigTileLightListBuffer = bigTileLightListBuffer; - Vector3Int viewportSize = ComputeVolumetricViewportSize(hdCamera); + float tileSize = 0; + Vector3Int viewportSize = ComputeVolumetricViewportSize(hdCamera, ref tileSize); passData.densityBuffer = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(viewportSize.x, viewportSize.y, false, false) { @@ -438,7 +439,8 @@ RenderGraphResource VolumetricLightingPass(RenderGraph renderGraph, HDCamera hdC passData.bigTileLightListBuffer = bigTileLightListBuffer; passData.densityBuffer = builder.ReadTexture(densityBuffer); - Vector3Int viewportSize = ComputeVolumetricViewportSize(hdCamera); + float tileSize = 0; + Vector3Int viewportSize = ComputeVolumetricViewportSize(hdCamera, ref tileSize); passData.lightingBuffer = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(viewportSize.x, viewportSize.y, false, false) { 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 e74e16bb9a3..b995702c915 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs @@ -497,6 +497,7 @@ static class HDShaderIDs public static readonly int _VBufferSliceCount = Shader.PropertyToID("_VBufferSliceCount"); public static readonly int _VBufferRcpSliceCount = Shader.PropertyToID("_VBufferRcpSliceCount"); public static readonly int _VBufferRcpInstancedViewCount = Shader.PropertyToID("_VBufferRcpInstancedViewCount"); + public static readonly int _VBufferTileSize = Shader.PropertyToID("_VBufferTileSize"); public static readonly int _VBufferLightingViewportScale = Shader.PropertyToID("_VBufferLightingViewportScale"); public static readonly int _VBufferLightingViewportLimit = Shader.PropertyToID("_VBufferLightingViewportLimit"); public static readonly int _VBufferDistanceEncodingParams = Shader.PropertyToID("_VBufferDistanceEncodingParams"); diff --git a/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl b/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl index e425c54a758..9d8327a399a 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl @@ -32,7 +32,7 @@ #if defined(SHADER_STAGE_RAY_TRACING) // FXC Supports the naïve "recursive" concatenation, while DXC and C do not https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms -// However, FXC does not support the proper pattern (the one bellow), so we only override it in the case of ray tracing subshaders for the moment. +// However, FXC does not support the proper pattern (the one bellow), so we only override it in the case of ray tracing subshaders for the moment. // Note that this should be used for all shaders when DX12 used DXC for vert/frag shaders (which it does not for the moment) #undef MERGE_NAME #define MERGE_NAME_CONCAT(Name, ...) Name ## __VA_ARGS__ @@ -243,9 +243,10 @@ CBUFFER_START(UnityGlobal) uint _VBufferSliceCount; float _VBufferRcpSliceCount; float _VBufferRcpInstancedViewCount; // Used to remap VBuffer coordinates for XR + float _VBufferTileSize; - float _ContactShadowOpacity; float3 _VBufferLightingViewportScale; // Necessary to support sub-allocation of the RT system + float _ContactShadowOpacity; float3 _VBufferLightingViewportLimit; // Necessary to support sub-allocation of the RT system float4 _VBufferDistanceEncodingParams; // See the call site for description From e3f48e76b290a3739886ebcdffdaf6300557b364 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Wed, 26 Feb 2020 17:01:55 -0800 Subject: [PATCH 29/63] Changelog --- com.unity.render-pipelines.high-definition/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index 43ada70a274..00ab4d12eac 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -70,6 +70,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Added support for Thin Refraction Model and Lit's Clear Coat in Path Tracing. - Added the Tint parameter to Sky Colored Fog. - Added support for Quality Levels to Subsurface Scattering. +- Added support for arbitrary resolution scaling of Volumetric Lighting based on the Volume Framework. ### Fixed - Update documentation of HDRISky-Backplate, precise how to have Ambient Occlusion on the Backplate From 7180a7908b528c99b223af8e882e759aafedcbbb Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Wed, 26 Feb 2020 17:07:08 -0800 Subject: [PATCH 30/63] Stretch the limits --- .../Runtime/Lighting/AtmosphericScattering/Fog.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/Fog.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/Fog.cs index b339ced85c8..86281120f38 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/Fog.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/Fog.cs @@ -68,7 +68,7 @@ public class Fog : VolumeComponent /// Resolution of the volumetric buffer (3D texture) along the X and Y axes relative to the resolution of the frame buffer. [Tooltip("Resolution of the volumetric buffer (3D texture) along the X and Y axes relative to the resolution of the frame buffer. " + "Setting it to 12.5% (1/8) means the number of voxels per slice is 1/8^2 = 1/64 = 1.5625% of the resolution of the frame buffer.")] - public ClampedFloatParameter screenResolutionPercentage = new ClampedFloatParameter((1.0f/8.0f) * 100, (1.0f/12.0f) * 100, 100); + public ClampedFloatParameter screenResolutionPercentage = new ClampedFloatParameter((1.0f/8.0f) * 100, (1.0f/16.0f) * 100, 100); /// Number of slices of the volumetric buffer (3D texture) along the camera's focal axis. [Tooltip("Number of slices of the volumetric buffer (3D texture) along the camera's focal axis.")] public ClampedIntParameter volumeSliceCount = new ClampedIntParameter(64, 1, 1024); From 94f6ebf2361d0f52beb0f2dc4d3eab12423521d5 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Wed, 26 Feb 2020 17:11:39 -0800 Subject: [PATCH 31/63] Fix bug (order matters) --- .../Runtime/Lighting/VolumetricLighting/VBuffer.hlsl | 2 +- .../Lighting/VolumetricLighting/VolumeVoxelization.compute | 2 +- .../Lighting/VolumetricLighting/VolumetricLighting.compute | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VBuffer.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VBuffer.hlsl index a6fd641a23f..8db97933abf 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VBuffer.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VBuffer.hlsl @@ -38,7 +38,7 @@ float4 SampleVBuffer(TEXTURE3D_PARAM(VBuffer, clampSampler), } else { - coordIsInsideFrustum = true; // No clipping + coordIsInsideFrustum = true; // No clipping, only clamping } #if defined(UNITY_STEREO_INSTANCING_ENABLED) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumeVoxelization.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumeVoxelization.compute index 420eeeae444..40b1546c461 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumeVoxelization.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumeVoxelization.compute @@ -339,7 +339,7 @@ void VolumeVoxelization(uint3 dispatchThreadId : SV_DispatchThreadID, // Note that if VBUFFER_TILE_SIZE is not an integer, a voxel may straddle a tile boundary. // This means different voxel subsamples may belong to different tiles. // We accept this error, and simply use the coordinates of the corner of the voxel. - uint2 tileCoord = (uint2)(groupOffset * (VBUFFER_TILE_SIZE / TILE_SIZE_BIG_TILE)); + uint2 tileCoord = (uint2)(groupOffset * VBUFFER_TILE_SIZE / TILE_SIZE_BIG_TILE); uint tileIndex = tileCoord.x + _NumTileBigTileX * tileCoord.y; // Reminder: our voxels are sphere-capped right frustums (truncated right pyramids). diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute index ec3f28345ea..c5cf42dd7d0 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute @@ -677,7 +677,7 @@ void VolumetricLighting(uint3 dispatchThreadId : SV_DispatchThreadID, // Note that if VBUFFER_TILE_SIZE is not an integer, a voxel may straddle a tile boundary. // This means different voxel subsamples may belong to different tiles. // We accept this error, and simply use the coordinates of the corner of the voxel. - uint2 tileCoord = (uint2)(groupOffset * (VBUFFER_TILE_SIZE / TILE_SIZE_BIG_TILE)); + uint2 tileCoord = (uint2)(groupOffset * VBUFFER_TILE_SIZE / TILE_SIZE_BIG_TILE); uint tileIndex = tileCoord.x + _NumTileBigTileX * tileCoord.y; // Reminder: our voxels are sphere-capped right frustums (truncated right pyramids). From 2438833dd9079774ced11e7c55d09875da6ffdce Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Wed, 26 Feb 2020 17:23:35 -0800 Subject: [PATCH 32/63] Comments --- .../VolumetricLighting/VolumetricLighting.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs index c91b53798ca..884e97d8836 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs @@ -97,11 +97,11 @@ public VBufferParameters(Vector3Int viewportSize, float depthExtent, float camNe // The V-Buffer is sphere-capped, while the camera frustum is not. // We always start from the near plane of the camera. - float aspectRatio = viewportSize.x / (float)viewportSize.y; + float aspectRatio = viewportSize.x / (float)viewportSize.y; float farPlaneHeight = 2.0f * Mathf.Tan(0.5f * camVFoV) * camFar; - float farPlaneWidth = farPlaneHeight * aspectRatio; + float farPlaneWidth = farPlaneHeight * aspectRatio; float farPlaneMaxDim = Mathf.Max(farPlaneWidth, farPlaneHeight); - float farPlaneDist = Mathf.Sqrt(camFar * camFar + 0.25f * farPlaneMaxDim * farPlaneMaxDim); + float farPlaneDist = Mathf.Sqrt(camFar * camFar + 0.25f * farPlaneMaxDim * farPlaneMaxDim); float nearDist = camNear; float farDist = Math.Min(nearDist + depthExtent, farPlaneDist); @@ -734,8 +734,6 @@ static void VolumeVoxelizationPass( in VolumeVoxelizationParameters parameters, ComputeBuffer bigTileLightList, CommandBuffer cmd) { - // Before we set the buffer, we must make sure - cmd.SetComputeIntParam(parameters.voxelizationCS, HDShaderIDs._NumTileBigTileX, parameters.numBigTileX); cmd.SetComputeIntParam(parameters.voxelizationCS, HDShaderIDs._NumTileBigTileY, parameters.numBigTileY); if (parameters.tiledLighting) @@ -920,8 +918,8 @@ static void FilterVolumetricLighting(in VolumetricLightingParameters parameters, cmd.SetComputeTextureParam(parameters.volumetricLightingCS, parameters.volumetricFilteringKernelX, HDShaderIDs._VBufferLighting, outputBuffer); // Write cmd.DispatchCompute(parameters.volumetricLightingCS, parameters.volumetricFilteringKernelX, ((int)parameters.resolution.x + 7) / 8, ((int)parameters.resolution.y + 7) / 8, parameters.viewCount); - cmd.SetComputeTextureParam(parameters.volumetricLightingCS, parameters.volumetricFilteringKernelY, HDShaderIDs._VBufferFeedback, outputBuffer); // Read - cmd.SetComputeTextureParam(parameters.volumetricLightingCS, parameters.volumetricFilteringKernelY, HDShaderIDs._VBufferLighting, inputBuffer); // Write + cmd.SetComputeTextureParam(parameters.volumetricLightingCS, parameters.volumetricFilteringKernelY, HDShaderIDs._VBufferFeedback, outputBuffer); // Read + cmd.SetComputeTextureParam(parameters.volumetricLightingCS, parameters.volumetricFilteringKernelY, HDShaderIDs._VBufferLighting, inputBuffer); // Write cmd.DispatchCompute(parameters.volumetricLightingCS, parameters.volumetricFilteringKernelY, ((int)parameters.resolution.x + 7) / 8, ((int)parameters.resolution.y + 7) / 8, parameters.viewCount); } } From 4ca5145057d56db7996176e6b0573431b5b25f41 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Wed, 26 Feb 2020 17:26:48 -0800 Subject: [PATCH 33/63] Remove volumetric quality presets --- .../Editor/RenderPipeline/HDRenderPipelineUI.cs | 7 ------- .../Settings/SerializedRenderPipelineSettings.cs | 2 -- .../VolumetricLighting/VolumetricLighting.cs | 14 -------------- .../Settings/RenderPipelineSettings.cs | 2 -- 4 files changed, 25 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.cs b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.cs index c3e0e3539f0..1b6bc81c720 100644 --- a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.cs +++ b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.cs @@ -858,13 +858,6 @@ static void Drawer_SectionLightingUnsorted(SerializedHDRenderPipelineAsset seria EditorGUILayout.PropertyField(serialized.renderPipelineSettings.supportSSAO, Styles.supportSSAOContent); EditorGUILayout.PropertyField(serialized.renderPipelineSettings.supportVolumetrics, Styles.supportVolumetricContent); - using (new EditorGUI.DisabledScope(serialized.renderPipelineSettings.supportVolumetrics.hasMultipleDifferentValues - || !serialized.renderPipelineSettings.supportVolumetrics.boolValue)) - { - ++EditorGUI.indentLevel; - EditorGUILayout.PropertyField(serialized.renderPipelineSettings.increaseResolutionOfVolumetrics, Styles.volumetricResolutionContent); - --EditorGUI.indentLevel; - } EditorGUILayout.Space(); //to separate with following sub sections } diff --git a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/SerializedRenderPipelineSettings.cs b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/SerializedRenderPipelineSettings.cs index ead7cc2bec3..af2cff6a272 100644 --- a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/SerializedRenderPipelineSettings.cs +++ b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/SerializedRenderPipelineSettings.cs @@ -24,7 +24,6 @@ class SerializedRenderPipelineSettings public SerializedScalableSetting sssSampleBudget; [UnityEngine.Serialization.FormerlySerializedAs("supportVolumetric")] public SerializedProperty supportVolumetrics; - public SerializedProperty increaseResolutionOfVolumetrics; public SerializedProperty supportLightLayers; public SerializedProperty lightLayerName0; public SerializedProperty lightLayerName1; @@ -77,7 +76,6 @@ public SerializedRenderPipelineSettings(SerializedProperty root) supportSubsurfaceScattering = root.Find((RenderPipelineSettings s) => s.supportSubsurfaceScattering); sssSampleBudget = new SerializedScalableSetting(root.Find((RenderPipelineSettings s) => s.sssSampleBudget)); supportVolumetrics = root.Find((RenderPipelineSettings s) => s.supportVolumetrics); - increaseResolutionOfVolumetrics = root.Find((RenderPipelineSettings s) => s.increaseResolutionOfVolumetrics); supportLightLayers = root.Find((RenderPipelineSettings s) => s.supportLightLayers); lightLayerName0 = root.Find((RenderPipelineSettings s) => s.lightLayerName0); lightLayerName1 = root.Find((RenderPipelineSettings s) => s.lightLayerName1); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs index 884e97d8836..635f2fa3574 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs @@ -74,14 +74,6 @@ struct DensityVolumeList public List density; } - enum VolumetricLightingPreset - { - Off, - Medium, - High, - Count - } - struct VBufferParameters { public Vector3Int viewportSize; @@ -171,8 +163,6 @@ static Vector4 ComputeLogarithmicDepthDecodingParams(float nearPlane, float farP public partial class HDRenderPipeline { - VolumetricLightingPreset volumetricLightingPreset = VolumetricLightingPreset.Off; - ComputeShader m_VolumeVoxelizationCS = null; ComputeShader m_VolumetricLightingCS = null; @@ -219,10 +209,6 @@ void InitializeVolumetricLighting() if (!m_SupportVolumetrics) return; - volumetricLightingPreset = asset.currentPlatformRenderPipelineSettings.increaseResolutionOfVolumetrics - ? VolumetricLightingPreset.High - : VolumetricLightingPreset.Medium; - m_VolumeVoxelizationCS = defaultResources.shaders.volumeVoxelizationCS; m_VolumetricLightingCS = defaultResources.shaders.volumetricLightingCS; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/RenderPipelineSettings.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/RenderPipelineSettings.cs index 96f7b9cfce2..1fde52e1b7f 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/RenderPipelineSettings.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/RenderPipelineSettings.cs @@ -129,8 +129,6 @@ public struct LightSettings public IntScalableSetting sssSampleBudget; /// Support volumetric lighting. public bool supportVolumetrics; - /// High quality volumetric lighting. - public bool increaseResolutionOfVolumetrics; /// Support light layers. public bool supportLightLayers; /// Name for light layer 0. From 6907c80e59b648988fa988ef53b750c0fd8ed0e6 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Wed, 26 Feb 2020 17:29:19 -0800 Subject: [PATCH 34/63] Changelog --- com.unity.render-pipelines.high-definition/CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index 00ab4d12eac..c58ad55c110 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -70,7 +70,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Added support for Thin Refraction Model and Lit's Clear Coat in Path Tracing. - Added the Tint parameter to Sky Colored Fog. - Added support for Quality Levels to Subsurface Scattering. -- Added support for arbitrary resolution scaling of Volumetric Lighting based on the Volume Framework. +- Added support for arbitrary resolution scaling of Volumetric Lighting to the Fog volume component. ### Fixed - Update documentation of HDRISky-Backplate, precise how to have Ambient Occlusion on the Backplate @@ -494,6 +494,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Hide the Probes section in the Renderer editos because it was unused. - Moved BeginCameraRendering callback right before culling. - Replaced "High Quality" Subsurface Scattering with a set of Quality Levels. +- Replaced "High Quality" Volumetric Lighting with "Screen Resolution Percentage" and "Volume Slice Count" on the Fog volume component. ## [7.1.1] - 2019-09-05 From 5e428f91e2f77c64c1de7e59b0f8607b5a3e5636 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Wed, 26 Feb 2020 17:59:19 -0800 Subject: [PATCH 35/63] Reorder --- .../VolumetricLighting/VolumetricLighting.cs | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs index 635f2fa3574..b10c77d6cd8 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs @@ -202,27 +202,6 @@ public partial class HDRenderPipeline Matrix4x4[] m_PixelCoordToViewDirWS; - void InitializeVolumetricLighting() - { - m_SupportVolumetrics = asset.currentPlatformRenderPipelineSettings.supportVolumetrics; - - if (!m_SupportVolumetrics) - return; - - m_VolumeVoxelizationCS = defaultResources.shaders.volumeVoxelizationCS; - m_VolumetricLightingCS = defaultResources.shaders.volumetricLightingCS; - - m_PackedCoeffs = new Vector4[7]; - m_PhaseZH = new ZonalHarmonicsL2(); - m_PhaseZH.coeffs = new float[3]; - - m_xySeq = new Vector2[7]; - - m_PixelCoordToViewDirWS = new Matrix4x4[ShaderConfig.s_XrMaxViews]; - - CreateVolumetricLightingBuffers(); - } - static internal int RoundToNearestInt(float f) { return (int)(f + 0.5f); @@ -491,6 +470,27 @@ internal void ResizeVolumetricLightingBuffers(HDCamera hdCamera, int frameIndex) currentParams.viewportSize.z); } + void InitializeVolumetricLighting() + { + m_SupportVolumetrics = asset.currentPlatformRenderPipelineSettings.supportVolumetrics; + + if (!m_SupportVolumetrics) + return; + + m_VolumeVoxelizationCS = defaultResources.shaders.volumeVoxelizationCS; + m_VolumetricLightingCS = defaultResources.shaders.volumetricLightingCS; + + m_PackedCoeffs = new Vector4[7]; + m_PhaseZH = new ZonalHarmonicsL2(); + m_PhaseZH.coeffs = new float[3]; + + m_xySeq = new Vector2[7]; + + m_PixelCoordToViewDirWS = new Matrix4x4[ShaderConfig.s_XrMaxViews]; + + CreateVolumetricLightingBuffers(); + } + void CleanupVolumetricLighting() { // Note: No need to test for support volumetric here, we do saferelease and null assignation From a8c17a43e660e0aa44877a435adb96996c8e8cf7 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Thu, 27 Feb 2020 11:30:13 -0800 Subject: [PATCH 36/63] Solve the mystery of RTs going NULL --- .../VolumetricLighting/VolumetricLighting.cs | 47 ++++++++++++------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs index b10c77d6cd8..1971d05ec7f 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs @@ -202,6 +202,15 @@ public partial class HDRenderPipeline Matrix4x4[] m_PixelCoordToViewDirWS; + static internal void SafeDestroy(ref RenderTexture rt) + { + if (rt != null) + { + rt.Release(); // The texture itself is not destroyed: https://docs.unity3d.com/ScriptReference/RenderTexture.Release.html + Object.DestroyImmediate(rt); // Destroy() may not be called from the Edit mode + } + } + static internal int RoundToNearestInt(float f) { return (int)(f + 0.5f); @@ -372,18 +381,27 @@ static internal void DestroyVolumetricHistoryBuffers(HDCamera hdCamera) // Must be called AFTER UpdateVolumetricBufferParams. static internal void ResizeVolumetricHistoryBuffers(HDCamera hdCamera, int frameIndex) { - if (hdCamera.volumetricHistoryBuffers == null) + if (!hdCamera.IsVolumetricReprojectionEnabled()) return; Debug.Assert(hdCamera.vBufferParams != null); Debug.Assert(hdCamera.vBufferParams.Length == 2); - Debug.Assert(hdCamera.volumetricHistoryBuffers.Length == 2); + Debug.Assert(hdCamera.volumetricHistoryBuffers != null); var currIdx = (frameIndex + 0) & 1; var prevIdx = (frameIndex + 1) & 1; var currentParams = hdCamera.vBufferParams[currIdx]; + // Render texture contents can become "lost" on certain events, like loading a new level, + // system going to a screensaver mode, in and out of fullscreen and so on. + // https://docs.unity3d.com/ScriptReference/RenderTexture.html + if (hdCamera.volumetricHistoryBuffers[0] == null || hdCamera.volumetricHistoryBuffers[1] == null) + { + DestroyVolumetricHistoryBuffers(hdCamera); + CreateVolumetricHistoryBuffers(hdCamera, hdCamera.vBufferParams.Length); // Basically, assume it's 2 + } + // We only resize the feedback buffer (#0), not the history buffer (#1). // We must NOT resize the buffer from the previous frame (#1), as that would invalidate its contents. ResizeVolumetricBuffer(ref hdCamera.volumetricHistoryBuffers[currIdx], currentParams.viewportSize.x, @@ -425,20 +443,10 @@ internal void CreateVolumetricLightingBuffers() Debug.Assert(success); } - static internal void SafeRelease(RenderTexture rt) - { - if (rt != null) - { - rt.Release(); - } - - rt = null; - } - internal void DestroyVolumetricLightingBuffers() { - SafeRelease(m_LightingBuffer); - SafeRelease(m_DensityBuffer); + SafeDestroy(ref m_LightingBuffer); + SafeDestroy(ref m_DensityBuffer); CoreUtils.SafeRelease(m_VisibleVolumeDataBuffer); CoreUtils.SafeRelease(m_VisibleVolumeBoundsBuffer); @@ -454,8 +462,15 @@ internal void ResizeVolumetricLightingBuffers(HDCamera hdCamera, int frameIndex) return; Debug.Assert(hdCamera.vBufferParams != null); - Debug.Assert(m_DensityBuffer != null); - Debug.Assert(m_LightingBuffer != null); + + // Render texture contents can become "lost" on certain events, like loading a new level, + // system going to a screensaver mode, in and out of fullscreen and so on. + // https://docs.unity3d.com/ScriptReference/RenderTexture.html + if (m_DensityBuffer == null || m_LightingBuffer == null) + { + DestroyVolumetricLightingBuffers(); + CreateVolumetricLightingBuffers(); + } var currIdx = (frameIndex + 0) & 1; var prevIdx = (frameIndex + 1) & 1; From 7f45eab745cfaaaef4566f5420d9828aad0d7ad7 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Thu, 27 Feb 2020 11:37:40 -0800 Subject: [PATCH 37/63] More robust bad history detection --- .../Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs | 3 +++ .../Runtime/RenderPipeline/Camera/HDCamera.cs | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs index 1971d05ec7f..81b625bc724 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs @@ -361,6 +361,8 @@ static internal void CreateVolumetricHistoryBuffers(HDCamera hdCamera, int buffe bool success = hdCamera.volumetricHistoryBuffers[i].Create(); Debug.Assert(success); } + + hdCamera.volumetricHistoryIsValid = false; } static internal void DestroyVolumetricHistoryBuffers(HDCamera hdCamera) @@ -376,6 +378,7 @@ static internal void DestroyVolumetricHistoryBuffers(HDCamera hdCamera) } hdCamera.volumetricHistoryBuffers = null; + hdCamera.volumetricHistoryIsValid = false; } // Must be called AFTER UpdateVolumetricBufferParams. diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs index a29828a3e44..88b0207d225 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs @@ -406,7 +406,6 @@ internal void Update(FrameSettings currentFrameSettings, HDRenderPipeline hdrp, { // Reinit the system. colorPyramidHistoryIsValid = false; - volumetricHistoryIsValid = false; HDRenderPipeline.DestroyVolumetricHistoryBuffers(this); From dd4cd00ac048721f849daa51be367eae8e8bbb73 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Thu, 27 Feb 2020 12:06:06 -0800 Subject: [PATCH 38/63] Update test scenes for High Quality --- .../2008_Light_Volumetrics_Volume.asset | 10 ++++++++++ .../5001_Fog_FogFallback/Volume_Base.asset | 10 ++++++++++ .../Scene Settings Profile.asset | 10 ++++++++++ .../Scene Settings Profile.asset | 10 ++++++++++ .../Sky and Fog Settings Profile.asset | 10 ++++++++++ 5 files changed, 50 insertions(+) diff --git a/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/2x_Lighting/2008_Light_Volumetrics/2008_Light_Volumetrics_Volume.asset b/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/2x_Lighting/2008_Light_Volumetrics/2008_Light_Volumetrics_Volume.asset index e1166fcdef7..7f5daca687c 100644 --- a/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/2x_Lighting/2008_Light_Volumetrics/2008_Light_Volumetrics_Volume.asset +++ b/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/2x_Lighting/2008_Light_Volumetrics/2008_Light_Volumetrics_Volume.asset @@ -104,6 +104,16 @@ MonoBehaviour: m_Value: 0.75 min: 0 max: 1 + screenResolutionPercentage: + m_OverrideState: 1 + m_Value: 25 + min: 6.25 + max: 100 + volumeSliceCount: + m_OverrideState: 1 + m_Value: 128 + min: 1 + max: 1024 --- !u!114 &11400000 MonoBehaviour: m_ObjectHideFlags: 0 diff --git a/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/5x_SkyAndFog/5001_Fog_FogFallback/Volume_Base.asset b/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/5x_SkyAndFog/5001_Fog_FogFallback/Volume_Base.asset index bebc4807d79..c23d19c35dd 100644 --- a/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/5x_SkyAndFog/5001_Fog_FogFallback/Volume_Base.asset +++ b/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/5x_SkyAndFog/5001_Fog_FogFallback/Volume_Base.asset @@ -198,6 +198,16 @@ MonoBehaviour: m_Value: 0.75 min: 0 max: 1 + screenResolutionPercentage: + m_OverrideState: 1 + m_Value: 25 + min: 6.25 + max: 100 + volumeSliceCount: + m_OverrideState: 1 + m_Value: 128 + min: 1 + max: 1024 --- !u!114 &3474294613101294443 MonoBehaviour: m_ObjectHideFlags: 3 diff --git a/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/5x_SkyAndFog/5002_Fog_DensityVolumes/Scene Settings Profile.asset b/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/5x_SkyAndFog/5002_Fog_DensityVolumes/Scene Settings Profile.asset index aaf923a2a14..0fecf7ac517 100644 --- a/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/5x_SkyAndFog/5002_Fog_DensityVolumes/Scene Settings Profile.asset +++ b/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/5x_SkyAndFog/5002_Fog_DensityVolumes/Scene Settings Profile.asset @@ -81,6 +81,16 @@ MonoBehaviour: m_Value: 0.75 min: 0 max: 1 + screenResolutionPercentage: + m_OverrideState: 1 + m_Value: 25 + min: 6.25 + max: 100 + volumeSliceCount: + m_OverrideState: 1 + m_Value: 128 + min: 1 + max: 1024 --- !u!114 &11400000 MonoBehaviour: m_ObjectHideFlags: 0 diff --git a/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/5x_SkyAndFog/5003_Fog_DensityVolumesShadows/Scene Settings Profile.asset b/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/5x_SkyAndFog/5003_Fog_DensityVolumesShadows/Scene Settings Profile.asset index 5c62f69d04a..e3d3d9ec426 100644 --- a/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/5x_SkyAndFog/5003_Fog_DensityVolumesShadows/Scene Settings Profile.asset +++ b/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/5x_SkyAndFog/5003_Fog_DensityVolumesShadows/Scene Settings Profile.asset @@ -254,3 +254,13 @@ MonoBehaviour: m_Value: 1 min: 0 max: 1 + screenResolutionPercentage: + m_OverrideState: 1 + m_Value: 25 + min: 6.25 + max: 100 + volumeSliceCount: + m_OverrideState: 1 + m_Value: 128 + min: 1 + max: 1024 diff --git a/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/5x_SkyAndFog/5008_FogFiltering/Sky and Fog Settings Profile.asset b/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/5x_SkyAndFog/5008_FogFiltering/Sky and Fog Settings Profile.asset index b0cb6de3bc0..53e4a07064e 100644 --- a/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/5x_SkyAndFog/5008_FogFiltering/Sky and Fog Settings Profile.asset +++ b/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/5x_SkyAndFog/5008_FogFiltering/Sky and Fog Settings Profile.asset @@ -81,6 +81,16 @@ MonoBehaviour: m_Value: 0.75 min: 0 max: 1 + screenResolutionPercentage: + m_OverrideState: 1 + m_Value: 25 + min: 6.25 + max: 100 + volumeSliceCount: + m_OverrideState: 1 + m_Value: 128 + min: 1 + max: 1024 filter: m_OverrideState: 1 m_Value: 1 From 541063a990e4aaa5624cd50ecedde99eed1b6a88 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Thu, 27 Feb 2020 13:46:07 -0800 Subject: [PATCH 39/63] More bug fixes --- .../VolumeVoxelization.compute | 19 ++++++++------- .../VolumetricLighting.compute | 19 ++++++++------- .../VolumetricLighting/VolumetricLighting.cs | 24 +++++++++---------- .../RenderPipeline/HDStringConstants.cs | 2 +- .../ShaderLibrary/ShaderVariables.hlsl | 2 +- 5 files changed, 36 insertions(+), 30 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumeVoxelization.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumeVoxelization.compute index 40b1546c461..0d96a66570f 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumeVoxelization.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumeVoxelization.compute @@ -16,10 +16,7 @@ #ifdef VL_PRESET_OPTIMAL // E.g. for 1080p: (1920/8)x(1080/8)x(64) = 2,073,600 voxels - #define VBUFFER_TILE_SIZE 8 -#else - // No compile-time optimizations, no scalarization. - #define VBUFFER_TILE_SIZE _VBufferTileSize + #define VBUFFER_VOXEL_SIZE 8 #endif #define GROUP_SIZE_1D 8 @@ -336,11 +333,17 @@ void VolumeVoxelization(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 groupOffset = groupId * GROUP_SIZE_1D; uint2 voxelCoord = groupOffset + groupThreadId; - // Note that if VBUFFER_TILE_SIZE is not an integer, a voxel may straddle a tile boundary. +#ifdef VL_PRESET_OPTIMAL + // The entire thread group is within the same light tile. + uint2 tileCoord = groupOffset * VBUFFER_VOXEL_SIZE / TILE_SIZE_BIG_TILE; +#else + // No compile-time optimizations, no scalarization. + // Note that if _VBufferVoxelSize is not an integer, a voxel may straddle a tile boundary. // This means different voxel subsamples may belong to different tiles. - // We accept this error, and simply use the coordinates of the corner of the voxel. - uint2 tileCoord = (uint2)(groupOffset * VBUFFER_TILE_SIZE / TILE_SIZE_BIG_TILE); - uint tileIndex = tileCoord.x + _NumTileBigTileX * tileCoord.y; + // We accept this error, and simply use the coordinates of the center of the voxel. + uint2 tileCoord = (uint2)((voxelCoord + 0.5) * _VBufferVoxelSize / TILE_SIZE_BIG_TILE); +#endif + uint tileIndex = tileCoord.x + _NumTileBigTileX * tileCoord.y; // Reminder: our voxels are sphere-capped right frustums (truncated right pyramids). // The curvature of the front and back faces is quite gentle, so we can use diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute index c5cf42dd7d0..8816db66205 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute @@ -37,10 +37,7 @@ #ifdef VL_PRESET_OPTIMAL // E.g. for 1080p: (1920/8)x(1080/8)x(64) = 2,073,600 voxels - #define VBUFFER_TILE_SIZE 8 -#else - - #define VBUFFER_TILE_SIZE _VBufferTileSize + #define VBUFFER_VOXEL_SIZE 8 #endif #define GROUP_SIZE_1D 8 @@ -674,11 +671,17 @@ void VolumetricLighting(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 groupOffset = groupId * GROUP_SIZE_1D; uint2 voxelCoord = groupOffset + groupThreadId; - // Note that if VBUFFER_TILE_SIZE is not an integer, a voxel may straddle a tile boundary. +#ifdef VL_PRESET_OPTIMAL + // The entire thread group is within the same light tile. + uint2 tileCoord = groupOffset * VBUFFER_VOXEL_SIZE / TILE_SIZE_BIG_TILE; +#else + // No compile-time optimizations, no scalarization. + // Note that if _VBufferVoxelSize is not an integer, a voxel may straddle a tile boundary. // This means different voxel subsamples may belong to different tiles. - // We accept this error, and simply use the coordinates of the corner of the voxel. - uint2 tileCoord = (uint2)(groupOffset * VBUFFER_TILE_SIZE / TILE_SIZE_BIG_TILE); - uint tileIndex = tileCoord.x + _NumTileBigTileX * tileCoord.y; + // We accept this error, and simply use the coordinates of the center of the voxel. + uint2 tileCoord = (uint2)((voxelCoord + 0.5) * _VBufferVoxelSize / TILE_SIZE_BIG_TILE); +#endif + uint tileIndex = tileCoord.x + _NumTileBigTileX * tileCoord.y; // Reminder: our voxels are sphere-capped right frustums (truncated right pyramids). // The curvature of the front and back faces is quite gentle, so we can use diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs index 81b625bc724..b873be1235f 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs @@ -77,14 +77,14 @@ struct DensityVolumeList struct VBufferParameters { public Vector3Int viewportSize; - public float tileSize; + public float voxelSize; public Vector4 depthEncodingParams; public Vector4 depthDecodingParams; - public VBufferParameters(Vector3Int viewportSize, float depthExtent, float camNear, float camFar, float camVFoV, float sliceDistributionUniformity, float tileSize) + public VBufferParameters(Vector3Int viewportSize, float depthExtent, float camNear, float camFar, float camVFoV, float sliceDistributionUniformity, float voxelSize) { this.viewportSize = viewportSize; - this.tileSize = tileSize; + this.voxelSize = voxelSize; // The V-Buffer is sphere-capped, while the camera frustum is not. // We always start from the near plane of the camera. @@ -216,7 +216,7 @@ static internal int RoundToNearestInt(float f) return (int)(f + 0.5f); } - static internal Vector3Int ComputeVolumetricViewportSize(HDCamera hdCamera, ref float tileSize) + static internal Vector3Int ComputeVolumetricViewportSize(HDCamera hdCamera, ref float voxelSize) { var controller = hdCamera.volumeStack.GetComponent(); Debug.Assert(controller != null); @@ -231,9 +231,9 @@ static internal Vector3Int ComputeVolumetricViewportSize(HDCamera hdCamera, ref int d = sliceCount; if (controller.screenResolutionPercentage.value == (1.0f/8.0f) * 100) - tileSize = 8; + voxelSize = 8; else - tileSize = 1.0f / screenFraction; // Does not account for rounding + voxelSize = 1.0f / screenFraction; // Does not account for rounding (same function, above) return new Vector3Int(w, h, d); } @@ -243,15 +243,15 @@ static internal VBufferParameters ComputeVolumetricBufferParameters(HDCamera hdC var controller = hdCamera.volumeStack.GetComponent(); Debug.Assert(controller != null); - float tileSize = 0; - Vector3Int viewportSize = ComputeVolumetricViewportSize(hdCamera, ref tileSize); + float voxelSize = 0; + Vector3Int viewportSize = ComputeVolumetricViewportSize(hdCamera, ref voxelSize); return new VBufferParameters(viewportSize, controller.depthExtent.value, hdCamera.camera.nearClipPlane, hdCamera.camera.farClipPlane, hdCamera.camera.fieldOfView, controller.sliceDistributionUniformity.value, - tileSize); + voxelSize); } static internal void ReinitializeVolumetricBufferParams(HDCamera hdCamera) @@ -588,7 +588,7 @@ void PushVolumetricLightingGlobalParams(HDCamera hdCamera, CommandBuffer cmd, in cmd.SetGlobalVector(HDShaderIDs._VBufferViewportSize, new Vector4(cvp.x, cvp.y, 1.0f / cvp.x, 1.0f / cvp.y)); cmd.SetGlobalInt( HDShaderIDs._VBufferSliceCount, sliceCount); cmd.SetGlobalFloat( HDShaderIDs._VBufferRcpSliceCount, 1.0f / sliceCount); - cmd.SetGlobalFloat( HDShaderIDs._VBufferTileSize, currFrameParams.tileSize); + cmd.SetGlobalFloat( HDShaderIDs._VBufferVoxelSize, currFrameParams.voxelSize); cmd.SetGlobalVector(HDShaderIDs._VBufferLightingViewportScale, currFrameParams.ComputeViewportScale(lightingBufferSize)); cmd.SetGlobalVector(HDShaderIDs._VBufferLightingViewportLimit, currFrameParams.ComputeViewportLimit(lightingBufferSize)); cmd.SetGlobalVector(HDShaderIDs._VBufferDistanceEncodingParams, currFrameParams.depthEncodingParams); @@ -694,7 +694,7 @@ VolumeVoxelizationParameters PrepareVolumeVoxelizationParameters(HDCamera hdCame parameters.numBigTileY = GetNumTileBigTileY(hdCamera); parameters.tiledLighting = HasLightToCull() && hdCamera.frameSettings.IsEnabled(FrameSettingsField.BigTilePrepass); - bool optimal = currFrameParams.tileSize == 8; + bool optimal = currFrameParams.voxelSize == 8; parameters.voxelizationCS = m_VolumeVoxelizationCS; parameters.voxelizationKernel = (parameters.tiledLighting ? 1 : 0) | (!optimal ? 2 : 0); @@ -842,7 +842,7 @@ VolumetricLightingParameters PrepareVolumetricLightingParameters(HDCamera hdCame parameters.tiledLighting = hdCamera.frameSettings.IsEnabled(FrameSettingsField.BigTilePrepass); parameters.enableReprojection = hdCamera.IsVolumetricReprojectionEnabled(); bool enableAnisotropy = fog.anisotropy.value != 0; - bool optimal = currFrameParams.tileSize == 8; + bool optimal = currFrameParams.voxelSize == 8; parameters.volumetricLightingCS = m_VolumetricLightingCS; parameters.volumetricLightingKernel = (parameters.tiledLighting ? 1 : 0) | (parameters.enableReprojection ? 2 : 0) | (enableAnisotropy ? 4 : 0) | (!optimal ? 8 : 0); 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 b995702c915..13b40784bfc 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs @@ -497,7 +497,7 @@ static class HDShaderIDs public static readonly int _VBufferSliceCount = Shader.PropertyToID("_VBufferSliceCount"); public static readonly int _VBufferRcpSliceCount = Shader.PropertyToID("_VBufferRcpSliceCount"); public static readonly int _VBufferRcpInstancedViewCount = Shader.PropertyToID("_VBufferRcpInstancedViewCount"); - public static readonly int _VBufferTileSize = Shader.PropertyToID("_VBufferTileSize"); + public static readonly int _VBufferVoxelSize = Shader.PropertyToID("_VBufferVoxelSize"); public static readonly int _VBufferLightingViewportScale = Shader.PropertyToID("_VBufferLightingViewportScale"); public static readonly int _VBufferLightingViewportLimit = Shader.PropertyToID("_VBufferLightingViewportLimit"); public static readonly int _VBufferDistanceEncodingParams = Shader.PropertyToID("_VBufferDistanceEncodingParams"); diff --git a/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl b/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl index 9d8327a399a..1755967758e 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl @@ -243,7 +243,7 @@ CBUFFER_START(UnityGlobal) uint _VBufferSliceCount; float _VBufferRcpSliceCount; float _VBufferRcpInstancedViewCount; // Used to remap VBuffer coordinates for XR - float _VBufferTileSize; + float _VBufferVoxelSize; // In pixels float3 _VBufferLightingViewportScale; // Necessary to support sub-allocation of the RT system float _ContactShadowOpacity; From 1bb82d2320a4f9c024e84fc0cf37bf163906f25d Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Thu, 27 Feb 2020 14:00:07 -0800 Subject: [PATCH 40/63] More accurate comment --- .../Lighting/VolumetricLighting/VolumeVoxelization.compute | 4 ++-- .../Lighting/VolumetricLighting/VolumetricLighting.compute | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumeVoxelization.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumeVoxelization.compute index 0d96a66570f..25000c890d5 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumeVoxelization.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumeVoxelization.compute @@ -338,8 +338,8 @@ void VolumeVoxelization(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 tileCoord = groupOffset * VBUFFER_VOXEL_SIZE / TILE_SIZE_BIG_TILE; #else // No compile-time optimizations, no scalarization. - // Note that if _VBufferVoxelSize is not an integer, a voxel may straddle a tile boundary. - // This means different voxel subsamples may belong to different tiles. + // If _VBufferVoxelSize is not a power of 2 or > TILE_SIZE_BIG_TILE, a voxel may straddle + // a tile boundary. This means different voxel subsamples may belong to different tiles. // We accept this error, and simply use the coordinates of the center of the voxel. uint2 tileCoord = (uint2)((voxelCoord + 0.5) * _VBufferVoxelSize / TILE_SIZE_BIG_TILE); #endif diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute index 8816db66205..87f27995f1e 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute @@ -676,8 +676,8 @@ void VolumetricLighting(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 tileCoord = groupOffset * VBUFFER_VOXEL_SIZE / TILE_SIZE_BIG_TILE; #else // No compile-time optimizations, no scalarization. - // Note that if _VBufferVoxelSize is not an integer, a voxel may straddle a tile boundary. - // This means different voxel subsamples may belong to different tiles. + // If _VBufferVoxelSize is not a power of 2 or > TILE_SIZE_BIG_TILE, a voxel may straddle + // a tile boundary. This means different voxel subsamples may belong to different tiles. // We accept this error, and simply use the coordinates of the center of the voxel. uint2 tileCoord = (uint2)((voxelCoord + 0.5) * _VBufferVoxelSize / TILE_SIZE_BIG_TILE); #endif From 571f52204fe8478ffd687506dc3ae104225b1c34 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Thu, 27 Feb 2020 14:08:10 -0800 Subject: [PATCH 41/63] Do not reinvent the wheel --- .../Lighting/VolumetricLighting/VolumetricLighting.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs index b873be1235f..b0dde3fdf16 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs @@ -211,11 +211,6 @@ static internal void SafeDestroy(ref RenderTexture rt) } } - static internal int RoundToNearestInt(float f) - { - return (int)(f + 0.5f); - } - static internal Vector3Int ComputeVolumetricViewportSize(HDCamera hdCamera, ref float voxelSize) { var controller = hdCamera.volumeStack.GetComponent(); @@ -226,8 +221,8 @@ static internal Vector3Int ComputeVolumetricViewportSize(HDCamera hdCamera, ref float screenFraction = controller.screenResolutionPercentage.value * 0.01f; int sliceCount = controller.volumeSliceCount.value; - int w = RoundToNearestInt(viewportWidth * screenFraction); - int h = RoundToNearestInt(viewportHeight * screenFraction); + int w = Mathf.RoundToInt(viewportWidth * screenFraction); + int h = Mathf.RoundToInt(viewportHeight * screenFraction); int d = sliceCount; if (controller.screenResolutionPercentage.value == (1.0f/8.0f) * 100) From 049822408f22f6d4a39c6a1151039a4150031272 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Tue, 3 Mar 2020 15:24:44 -0800 Subject: [PATCH 42/63] Fix broken test 1351 --- .../1351_Fabric/M_SilkDetailNormalCutout_Graph.mat | 5 +++-- .../Linear/WindowsEditor/Direct3D11/1351_Fabric.png | 4 ++-- .../Linear/WindowsEditor/Direct3D11/1351_Fabric.png.meta | 6 ++++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/1x_Materials/1351_Fabric/M_SilkDetailNormalCutout_Graph.mat b/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/1x_Materials/1351_Fabric/M_SilkDetailNormalCutout_Graph.mat index 87520e8b86e..34a418e53b3 100644 --- a/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/1x_Materials/1351_Fabric/M_SilkDetailNormalCutout_Graph.mat +++ b/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/1x_Materials/1351_Fabric/M_SilkDetailNormalCutout_Graph.mat @@ -159,7 +159,7 @@ Material: - _DetailNormalScale: 1 - _DetailSmoothnessScale: 1 - _DiffusionProfile: 0 - - _DiffusionProfileHash: 0 + - _DiffusionProfileHash: 2.0715158 - _DisplacementLockObjectScale: 1 - _DisplacementLockTilingScale: 1 - _DisplacementMode: 0 @@ -281,7 +281,8 @@ Material: m_Colors: - _BaseColor: {r: 0.8773585, g: 0.4262638, b: 0.4262638, a: 1} - _Color: {r: 0.8773585, g: 0.42626378, b: 0.42626378, a: 1} - - _DiffusionProfileAsset: {r: 0, g: 0, b: 0, a: 0} + - _DiffusionProfileAsset: {r: 9.002416e+32, g: -2.4912824e+12, b: 3.1050093e+32, + a: 268232420} - _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} diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1351_Fabric.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1351_Fabric.png index 00656af1334..c7809a608b5 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1351_Fabric.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1351_Fabric.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0b74e3fd7d9042bc4e20fc8f000d855961c44fe25b78ff882a1d79fb3bb3b78e -size 497656 +oid sha256:cb8a12c920996468ee2704198021a2664b46ae20c1ca368f660e4ac56895affc +size 495642 diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1351_Fabric.png.meta b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1351_Fabric.png.meta index ff7687db5ac..2981a5edc9f 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1351_Fabric.png.meta +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/1351_Fabric.png.meta @@ -1,9 +1,9 @@ fileFormatVersion: 2 -guid: 95bc01f7f6272964ca98c669a304d2c7 +guid: 1e32eec183ac87e47a95de55e6f7d7d8 TextureImporter: internalIDToNameTable: [] externalObjects: {} - serializedVersion: 9 + serializedVersion: 10 mipmaps: mipMapMode: 0 enableMipMap: 0 @@ -23,6 +23,7 @@ TextureImporter: isReadable: 1 streamingMipmaps: 0 streamingMipmapsPriority: 0 + vTOnly: 0 grayScaleToAlpha: 0 generateCubemap: 6 cubemapConvolution: 0 @@ -57,6 +58,7 @@ TextureImporter: maxTextureSizeSet: 0 compressionQualitySet: 0 textureFormatSet: 0 + ignorePngGamma: 0 platformSettings: - serializedVersion: 3 buildTarget: DefaultTexturePlatform From 2db068cc5ca0b75d89810aa97de567e531b8b7ed Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Tue, 3 Mar 2020 15:58:53 -0800 Subject: [PATCH 43/63] Attempt to migrate HQ SSS settings --- .../Settings/SerializedRenderPipelineSettings.cs | 14 ++++++++++++-- .../HDRenderPipelineAsset.Migration.cs | 10 +++++++--- .../Settings/FrameSettings.Migration.cs | 6 +++--- .../Settings/RenderPipelineSettings.cs | 5 +++++ 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/SerializedRenderPipelineSettings.cs b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/SerializedRenderPipelineSettings.cs index ead7cc2bec3..cb8bd1cb9ea 100644 --- a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/SerializedRenderPipelineSettings.cs +++ b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/SerializedRenderPipelineSettings.cs @@ -1,4 +1,5 @@ -using UnityEditor.Rendering; +using System; +using UnityEngine.Serialization; using UnityEngine.Rendering.HighDefinition; namespace UnityEditor.Rendering.HighDefinition @@ -22,7 +23,7 @@ class SerializedRenderPipelineSettings public SerializedProperty supportSSAO; public SerializedProperty supportSubsurfaceScattering; public SerializedScalableSetting sssSampleBudget; - [UnityEngine.Serialization.FormerlySerializedAs("supportVolumetric")] + [FormerlySerializedAs("supportVolumetric")] public SerializedProperty supportVolumetrics; public SerializedProperty increaseResolutionOfVolumetrics; public SerializedProperty supportLightLayers; @@ -67,6 +68,11 @@ class SerializedRenderPipelineSettings public SerializedScalableSetting lodBias; public SerializedScalableSetting maximumLODLevel; + #pragma warning disable 618 // Type or member is obsolete + [FormerlySerializedAs("enableUltraQualitySSS"), FormerlySerializedAs("increaseSssSampleCount"), Obsolete("For data migration")] + SerializedProperty m_ObsoleteincreaseSssSampleCount; + #pragma warning restore 618 + public SerializedRenderPipelineSettings(SerializedProperty root) { this.root = root; @@ -118,6 +124,10 @@ public SerializedRenderPipelineSettings(SerializedProperty root) lodBias = new SerializedScalableSetting(root.Find((RenderPipelineSettings s) => s.lodBias)); maximumLODLevel = new SerializedScalableSetting(root.Find((RenderPipelineSettings s) => s.maximumLODLevel)); lightingQualitySettings = new SerializedLightingQualitySettings(root.Find((RenderPipelineSettings s) => s.lightingQualitySettings)); + + #pragma warning disable 618 // Type or member is obsolete + m_ObsoleteincreaseSssSampleCount = root.Find((RenderPipelineSettings s) => s.m_ObsoleteincreaseSssSampleCount); + #pragma warning restore 618 } } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipelineAsset.Migration.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipelineAsset.Migration.cs index e4a70a01d90..b11101ba63f 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipelineAsset.Migration.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipelineAsset.Migration.cs @@ -102,9 +102,13 @@ enum Version }), MigrationStep.New(Version.AddedAdaptiveSSS, (HDRenderPipelineAsset data) => { - FrameSettings.MigrateSubsurfaceParams(ref data.m_RenderingPathDefaultCameraFrameSettings); - FrameSettings.MigrateSubsurfaceParams(ref data.m_RenderingPathDefaultBakedOrCustomReflectionFrameSettings); - FrameSettings.MigrateSubsurfaceParams(ref data.m_RenderingPathDefaultRealtimeReflectionFrameSettings); + #pragma warning disable 618 // Type or member is obsolete + bool previouslyHighQuality = data.m_RenderPipelineSettings.m_ObsoleteincreaseSssSampleCount; + #pragma warning restore 618 + + FrameSettings.MigrateSubsurfaceParams(ref data.m_RenderingPathDefaultCameraFrameSettings, previouslyHighQuality); + FrameSettings.MigrateSubsurfaceParams(ref data.m_RenderingPathDefaultBakedOrCustomReflectionFrameSettings, previouslyHighQuality); + FrameSettings.MigrateSubsurfaceParams(ref data.m_RenderingPathDefaultRealtimeReflectionFrameSettings, previouslyHighQuality); }) ); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.Migration.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.Migration.cs index ce4b4e137a0..67c9f8b594d 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.Migration.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.Migration.cs @@ -417,15 +417,15 @@ internal static void MigrateToSeparateColorGradingAndTonemapping(ref FrameSettin cameraFrameSettings.SetEnabled(FrameSettingsField.Tonemapping, true); } - internal static void MigrateSubsurfaceParams(ref FrameSettings fs) + internal static void MigrateSubsurfaceParams(ref FrameSettings fs, bool previouslyHighQuality) { // SSS moved from 25 to 46. fs.SetEnabled((FrameSettingsField)25, false); fs.SetEnabled(FrameSettingsField.SubsurfaceScattering, true); // Set the defaults. - fs.sssQualityMode = SssQualityMode.FromQualitySettings; + fs.sssQualityMode = previouslyHighQuality ? SssQualityMode.OverrideQualitySettings : SssQualityMode.FromQualitySettings; fs.sssQualityLevel = 0; - fs.sssCustomSampleBudget = (int)DefaultSssSampleBudgetForQualityLevel.Low; + fs.sssCustomSampleBudget = previouslyHighQuality ? 55 : (int)DefaultSssSampleBudgetForQualityLevel.Low; } } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/RenderPipelineSettings.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/RenderPipelineSettings.cs index 96f7b9cfce2..0bd0f7de74b 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/RenderPipelineSettings.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/RenderPipelineSettings.cs @@ -215,5 +215,10 @@ public struct LightSettings /// Global lighting quality settings. public GlobalLightingQualitySettings lightingQualitySettings; + + #pragma warning disable 618 // Type or member is obsolete + [Obsolete("For data migration")] + internal bool m_ObsoleteincreaseSssSampleCount; + #pragma warning restore 618 } } From 30f2c5a2d1050cb43c2b3581f25f05b15aab2f8d Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Wed, 4 Mar 2020 14:38:25 -0800 Subject: [PATCH 44/63] Remove all branches --- .../SubsurfaceScattering.compute | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute index c0e5f9728d1..e8c0ab3cca3 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute @@ -110,7 +110,7 @@ float4 LoadSample(int2 pixelCoord, int2 cacheOffset) int2 cacheCoord = pixelCoord - cacheOffset; bool isInCache = max((uint)cacheCoord.x, (uint)cacheCoord.y) < TEXTURE_CACHE_SIZE_1D; - UNITY_BRANCH if (isInCache) + if (isInCache) { return LoadSampleFromCacheMemory(cacheCoord); } @@ -252,7 +252,7 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, uint2 pixelCoord = groupOffset + groupCoord; int2 cacheOffset = (int2)groupOffset - TEXTURE_CACHE_BORDER; - UNITY_BRANCH if (groupThreadId == 0) + if (groupThreadId == 0) { uint stencilRef = STENCILUSAGE_SUBSURFACE_SCATTERING; @@ -275,7 +275,7 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, // Wait for the LDS. GroupMemoryBarrierWithGroupSync(); - UNITY_BRANCH if (!processGroup) { return; } + if (!processGroup) { return; } float3 centerIrradiance = LOAD_TEXTURE2D_X(_IrradianceSource, pixelCoord).rgb; float centerDepth = 0; @@ -283,7 +283,7 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, bool passedStencilTest = TestLightingForSSS(centerIrradiance); // Save some bandwidth by only loading depth values for SSS pixels. - UNITY_BRANCH if (passedStencilTest) + if (passedStencilTest) { centerDepth = LOAD_TEXTURE2D_X(_DepthTexture, pixelCoord).r; centerViewZ = LinearEyeDepth(centerDepth, _ZBufferParams); @@ -297,7 +297,7 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, uint numBorderQuadsPerWave = TEXTURE_CACHE_SIZE_1D / 2 - 1; uint halfCacheWidthInQuads = TEXTURE_CACHE_SIZE_1D / 4; - UNITY_BRANCH if (quadIndex < numBorderQuadsPerWave) + if (quadIndex < numBorderQuadsPerWave) { // Fetch another texel into the LDS. uint2 startQuad = halfCacheWidthInQuads * DeinterleaveQuad(waveIndex); @@ -334,7 +334,7 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, float viewZ2 = 0; // Save some bandwidth by only loading depth values for SSS pixels. - UNITY_BRANCH if (TestLightingForSSS(irradiance2)) + if (TestLightingForSSS(irradiance2)) { viewZ2 = LinearEyeDepth(LOAD_TEXTURE2D_X(_DepthTexture, pixelCoord2).r, _ZBufferParams); } @@ -347,7 +347,7 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, GroupMemoryBarrierWithGroupSync(); #endif - UNITY_BRANCH if (!passedStencilTest) { return; } + if (!passedStencilTest) { return; } PositionInputs posInput = GetPositionInput(pixelCoord, _ScreenSize.zw); @@ -385,7 +385,7 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, uint texturingMode = GetSubsurfaceScatteringTexturingMode(profileIndex); float3 albedo = ApplySubsurfaceScatteringTexturingMode(texturingMode, sssData.diffuseColor); - UNITY_BRANCH if (distScale == 0 || sampleCount < 1) + if (distScale == 0 || sampleCount < 1) { #if SSS_DEBUG_LOD float3 green = float3(0, 1, 0); From c2a99fbf7d7e26741d81b1984b551678a091643e Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Wed, 4 Mar 2020 14:47:50 -0800 Subject: [PATCH 45/63] Optimize a bit --- .../SubsurfaceScattering.compute | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute index e8c0ab3cca3..3e58fb3ed4b 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute @@ -73,7 +73,7 @@ StructuredBuffer _CoarseStencilBuffer; // 6656 bytes used. It appears that the reserved LDS space must be a multiple of 512 bytes. #if SSS_USE_LDS_CACHE groupshared float2 textureCache0[TEXTURE_CACHE_SIZE_2D]; // {irradiance.rg} -groupshared float2 textureCache1[TEXTURE_CACHE_SIZE_2D]; // {irradiance.b, linearDepth} +groupshared float2 textureCache1[TEXTURE_CACHE_SIZE_2D]; // {irradiance.b, deviceDepth} #endif groupshared bool processGroup; @@ -100,7 +100,7 @@ float4 LoadSampleFromVideoMemory(int2 pixelCoord) float3 irradiance = LOAD_TEXTURE2D_X(_IrradianceSource, pixelCoord).rgb; float depth = LOAD_TEXTURE2D_X(_DepthTexture, pixelCoord).r; - return float4(irradiance, LinearEyeDepth(depth, _ZBufferParams)); + return float4(irradiance, depth); } // Returns {irradiance, linearDepth}. @@ -110,17 +110,23 @@ float4 LoadSample(int2 pixelCoord, int2 cacheOffset) int2 cacheCoord = pixelCoord - cacheOffset; bool isInCache = max((uint)cacheCoord.x, (uint)cacheCoord.y) < TEXTURE_CACHE_SIZE_1D; + float4 value; + if (isInCache) { - return LoadSampleFromCacheMemory(cacheCoord); + value = LoadSampleFromCacheMemory(cacheCoord); } else #endif { // Always load both irradiance and depth. // Avoid dependent texture reads at the cost of extra bandwidth. - return LoadSampleFromVideoMemory(pixelCoord); + value = LoadSampleFromVideoMemory(pixelCoord); } + + value.a = LinearEyeDepth(value.a, _ZBufferParams); + + return value; } // Computes f(r, s)/p(r, s), s.t. r = sqrt(xy^2 + z^2). @@ -158,7 +164,7 @@ float3 ComputeBilateralWeight(float xy2, float z, float mmPerUnit, float3 S, flo #endif } -void EvaluateSample(uint i, uint n, uint profileIndex, float2 centerCoord, int2 cacheOffset, +void EvaluateSample(uint i, uint n, float2 centerCoord, int2 cacheOffset, float3 S, float d, float3 centerPosVS, float mmPerUnit, float pixelsPerMm, float phase, float3 tangentX, float3 tangentY, float4x4 projMatrix, inout float3 totalIrradiance, inout float3 totalWeight) @@ -279,20 +285,18 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, float3 centerIrradiance = LOAD_TEXTURE2D_X(_IrradianceSource, pixelCoord).rgb; float centerDepth = 0; - float centerViewZ = 0; bool passedStencilTest = TestLightingForSSS(centerIrradiance); // Save some bandwidth by only loading depth values for SSS pixels. if (passedStencilTest) { centerDepth = LOAD_TEXTURE2D_X(_DepthTexture, pixelCoord).r; - centerViewZ = LinearEyeDepth(centerDepth, _ZBufferParams); } #if SSS_USE_LDS_CACHE uint2 cacheCoord = groupCoord + TEXTURE_CACHE_BORDER; // Populate the central region of the LDS cache. - StoreSampleToCacheMemory(float4(centerIrradiance, centerViewZ), cacheCoord); + StoreSampleToCacheMemory(float4(centerIrradiance, centerDepth), cacheCoord); uint numBorderQuadsPerWave = TEXTURE_CACHE_SIZE_1D / 2 - 1; uint halfCacheWidthInQuads = TEXTURE_CACHE_SIZE_1D / 4; @@ -331,16 +335,16 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, uint2 cacheCoord2 = 2 * (startQuad + quadCoord) + DeinterleaveQuad(laneIndex); int2 pixelCoord2 = (int2)(groupOffset + cacheCoord2) - TEXTURE_CACHE_BORDER; float3 irradiance2 = LOAD_TEXTURE2D_X(_IrradianceSource, pixelCoord2).rgb; - float viewZ2 = 0; + float depth2 = 0; // Save some bandwidth by only loading depth values for SSS pixels. if (TestLightingForSSS(irradiance2)) { - viewZ2 = LinearEyeDepth(LOAD_TEXTURE2D_X(_DepthTexture, pixelCoord2).r, _ZBufferParams); + depth2 = LOAD_TEXTURE2D_X(_DepthTexture, pixelCoord2).r; } // Populate the border region of the LDS cache. - StoreSampleToCacheMemory(float4(irradiance2, viewZ2), cacheCoord2); + StoreSampleToCacheMemory(float4(irradiance2, depth2), cacheCoord2); } // Wait for the LDS. @@ -447,7 +451,7 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, for (uint i = 0; i < n; i++) { // Integrate over the image or tangent plane in the view space. - EvaluateSample(i, n, profileIndex, pixelCoord + 0.5, cacheOffset, + EvaluateSample(i, n, pixelCoord + 0.5, cacheOffset, S, d, centerPosVS, mmPerUnit, pixelsPerMm, phase, tangentX, tangentY, projMatrix, totalIrradiance, totalWeight); From 0af4763a9d50973da8845430d1caadcc06f8b484 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Wed, 4 Mar 2020 16:48:48 -0800 Subject: [PATCH 46/63] 7x WF --- .../SubsurfaceScattering/SubsurfaceScattering.compute | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute index 3e58fb3ed4b..8aa296f9fcc 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute @@ -164,7 +164,7 @@ float3 ComputeBilateralWeight(float xy2, float z, float mmPerUnit, float3 S, flo #endif } -void EvaluateSample(uint i, uint n, float2 centerCoord, int2 cacheOffset, +void EvaluateSample(uint i, uint n, int2 pixelCoord, int2 cacheOffset, float3 S, float d, float3 centerPosVS, float mmPerUnit, float pixelsPerMm, float phase, float3 tangentX, float3 tangentY, float4x4 projMatrix, inout float3 totalIrradiance, inout float3 totalWeight) @@ -200,7 +200,8 @@ void EvaluateSample(uint i, uint n, float2 centerCoord, int2 cacheOffset, position = (int2)(positionNDC * _ScreenSize.xy); xy2 = dot(relPosVS.xy, relPosVS.xy); #else - position = (int2)(centerCoord + vec * pixelsPerMm); + // floor((pixelCoord + 0.5) + vec * pixelsPerMm) + position = pixelCoord + (int2)(0.5 + vec * pixelsPerMm); xy2 = r * r; #endif @@ -451,7 +452,7 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, for (uint i = 0; i < n; i++) { // Integrate over the image or tangent plane in the view space. - EvaluateSample(i, n, pixelCoord + 0.5, cacheOffset, + EvaluateSample(i, n, pixelCoord, cacheOffset, S, d, centerPosVS, mmPerUnit, pixelsPerMm, phase, tangentX, tangentY, projMatrix, totalIrradiance, totalWeight); From e49fb4b3980722b15e7537316cb8e54cc001e0bd Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Thu, 5 Mar 2020 15:28:50 -0800 Subject: [PATCH 47/63] Fix the rounding error --- .../SubsurfaceScattering/SubsurfaceScattering.compute | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute index 8aa296f9fcc..e6d7c136e07 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute @@ -201,7 +201,9 @@ void EvaluateSample(uint i, uint n, int2 pixelCoord, int2 cacheOffset, xy2 = dot(relPosVS.xy, relPosVS.xy); #else // floor((pixelCoord + 0.5) + vec * pixelsPerMm) - position = pixelCoord + (int2)(0.5 + vec * pixelsPerMm); + // position = pixelCoord + floor(0.5 + vec * pixelsPerMm); + // Note that (int) truncates towards 0, while floor() truncates towards -Inf! + position = pixelCoord + (int2)floor(0.5 + vec * pixelsPerMm); xy2 = r * r; #endif From 7c4ad79cadb9f3c81638b5cc099d9c335a08859b Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Thu, 5 Mar 2020 15:33:23 -0800 Subject: [PATCH 48/63] Fix the rounding error --- .../Material/SubsurfaceScattering/SubsurfaceScattering.compute | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute index e6d7c136e07..eb07c4265e8 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute @@ -202,8 +202,9 @@ void EvaluateSample(uint i, uint n, int2 pixelCoord, int2 cacheOffset, #else // floor((pixelCoord + 0.5) + vec * pixelsPerMm) // position = pixelCoord + floor(0.5 + vec * pixelsPerMm); + // position = pixelCoord + round(vec * pixelsPerMm); // Note that (int) truncates towards 0, while floor() truncates towards -Inf! - position = pixelCoord + (int2)floor(0.5 + vec * pixelsPerMm); + position = pixelCoord + (int2)round((pixelsPerMm * r) * float2(cosPsi, sinPsi)); xy2 = r * r; #endif From e4f4dd737e40510e767df86e5ab0aa1de6231f07 Mon Sep 17 00:00:00 2001 From: EvgeniiG <7ee2cc898cca1b5fc49df740c2081dfc681e0a28> Date: Thu, 5 Mar 2020 17:20:12 -0800 Subject: [PATCH 49/63] Remove garbage allocation --- .../VolumetricLighting/VolumetricLighting.cs | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs index b0dde3fdf16..b16e7b701c6 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs @@ -300,11 +300,12 @@ static internal void UpdateVolumetricBufferParams(HDCamera hdCamera, int frameIn } } - static internal void ResizeVolumetricBuffer(ref RenderTexture rt, int viewportWidth, int viewportHeight, int viewportDepth) + // Do not access 'rt.name', it allocates memory every time... + // Have to manually cache and pass the name. + static internal void ResizeVolumetricBuffer(ref RenderTexture rt, string name, int viewportWidth, int viewportHeight, int viewportDepth) { Debug.Assert(rt != null); - string name = rt.name; int width = rt.width; int height = rt.height; int depth = rt.volumeDepth; @@ -400,11 +401,13 @@ static internal void ResizeVolumetricHistoryBuffers(HDCamera hdCamera, int frame CreateVolumetricHistoryBuffers(hdCamera, hdCamera.vBufferParams.Length); // Basically, assume it's 2 } + string[] names = new string[2]{ "VBufferHistory0", "VBufferHistory1" }; + // We only resize the feedback buffer (#0), not the history buffer (#1). // We must NOT resize the buffer from the previous frame (#1), as that would invalidate its contents. - ResizeVolumetricBuffer(ref hdCamera.volumetricHistoryBuffers[currIdx], currentParams.viewportSize.x, - currentParams.viewportSize.y, - currentParams.viewportSize.z); + ResizeVolumetricBuffer(ref hdCamera.volumetricHistoryBuffers[currIdx], names[currIdx], currentParams.viewportSize.x, + currentParams.viewportSize.y, + currentParams.viewportSize.z); } internal void CreateVolumetricLightingBuffers() @@ -475,12 +478,12 @@ internal void ResizeVolumetricLightingBuffers(HDCamera hdCamera, int frameIndex) var currentParams = hdCamera.vBufferParams[currIdx]; - ResizeVolumetricBuffer(ref m_DensityBuffer, currentParams.viewportSize.x, - currentParams.viewportSize.y, - currentParams.viewportSize.z); - ResizeVolumetricBuffer(ref m_LightingBuffer, currentParams.viewportSize.x, - currentParams.viewportSize.y, - currentParams.viewportSize.z); + ResizeVolumetricBuffer(ref m_DensityBuffer, "VBufferDensity", currentParams.viewportSize.x, + currentParams.viewportSize.y, + currentParams.viewportSize.z); + ResizeVolumetricBuffer(ref m_LightingBuffer, "VBufferLighting", currentParams.viewportSize.x, + currentParams.viewportSize.y, + currentParams.viewportSize.z); } void InitializeVolumetricLighting() From 0ae669bca675075dc6cacb81438585438547ad78 Mon Sep 17 00:00:00 2001 From: Evgenii Date: Tue, 24 Mar 2020 10:21:33 -0700 Subject: [PATCH 50/63] Fix typos --- .../Runtime/Lighting/SurfaceShading.hlsl | 2 +- .../Runtime/Material/DiffusionProfile/DiffusionProfile.hlsl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/SurfaceShading.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Lighting/SurfaceShading.hlsl index 034c177433f..306da80bd4b 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/SurfaceShading.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/SurfaceShading.hlsl @@ -140,7 +140,7 @@ float3 EvaluateTransmittance_Punctual(LightLoopContext lightLoopContext, float dt = max(0, thicknessInMillimeters - bsdfData.thickness); float3 S = _ShapeParamsAndMaxScatterDists[bsdfData.diffusionProfileIndex].rgb; - float3 exp_13 = exp2(((LOG2_E * (-1.0/3.0)) * dt) * S); // Exp[-S * r / 3] + float3 exp_13 = exp2(((LOG2_E * (-1.0/3.0)) * dt) * S); // Exp[-S * dt / 3] // Approximate the decrease of transmittance by e^(-1/3 * dt * S). return bsdfData.transmittance * exp_13; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfile.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfile.hlsl index 6e597f7b6b9..1078eacff9b 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfile.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfile.hlsl @@ -23,7 +23,7 @@ float3 ComputeTransmittanceDisney(float3 S, float3 volumeAlbedo, float thickness float3 EvalBurleyDiffusionProfile(float r, float3 S) { float3 exp_13 = exp2(((LOG2_E * (-1.0/3.0)) * r) * S); // Exp[-S * r / 3] - float3 expSum = exp_13 * (1 + exp_13 + exp_13); // Exp[-S * r / 3] + Exp[-S * r] + float3 expSum = exp_13 * (1 + exp_13 * exp_13); // Exp[-S * r / 3] + Exp[-S * r] return (S * rcp(8 * PI)) * expSum; // S / (8 * Pi) * (Exp[-S * r / 3] + Exp[-S * r]) } @@ -49,7 +49,7 @@ void SampleBurleyDiffusionProfile(float u, float rcpS, out float r, out float rc // exp_13 = Exp[-x/3] = Exp[-1/3 * 3 * Log[c / (4 * u)]] // exp_13 = Exp[-Log[c / (4 * u)]] = (4 * u) / c // exp_1 = Exp[-x] = exp_13 * exp_13 * exp_13 - // expSum = exp_1 + exp_13 = exp_13 * (1 + exp_13 + exp_13) + // expSum = exp_1 + exp_13 = exp_13 * (1 + exp_13 * exp_13) // rcpExp = rcp(expSum) = c^3 / ((4 * u) * (c^2 + 16 * u^2)) float rcpExp = ((c * c) * c) * rcp((4 * u) * ((c * c) + (4 * u) * (4 * u))); From 3b4ca2b43f17c43698364c44c5d8c1ce9cc71910 Mon Sep 17 00:00:00 2001 From: Evgenii Date: Mon, 30 Mar 2020 11:41:00 -0700 Subject: [PATCH 51/63] Copy the SSS value --- .../Runtime/RenderPipeline/Settings/FrameSettings.Migration.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.Migration.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.Migration.cs index 67c9f8b594d..405a76fcf0b 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.Migration.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.Migration.cs @@ -420,8 +420,7 @@ internal static void MigrateToSeparateColorGradingAndTonemapping(ref FrameSettin internal static void MigrateSubsurfaceParams(ref FrameSettings fs, bool previouslyHighQuality) { // SSS moved from 25 to 46. - fs.SetEnabled((FrameSettingsField)25, false); - fs.SetEnabled(FrameSettingsField.SubsurfaceScattering, true); + fs.SetEnabled(FrameSettingsField.SubsurfaceScattering, fs.bitDatas[25]); // Set the defaults. fs.sssQualityMode = previouslyHighQuality ? SssQualityMode.OverrideQualitySettings : SssQualityMode.FromQualitySettings; fs.sssQualityLevel = 0; From e0cb0aa79981e732261bfbb420078e37046eddf0 Mon Sep 17 00:00:00 2001 From: Evgenii Date: Mon, 30 Mar 2020 11:43:40 -0700 Subject: [PATCH 52/63] Revert HDRP asset changes --- com.unity.testing.hdrp/RP_Assets/HDRP_Test_Def.asset | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/com.unity.testing.hdrp/RP_Assets/HDRP_Test_Def.asset b/com.unity.testing.hdrp/RP_Assets/HDRP_Test_Def.asset index 6d7f8836aa7..9faf9907e43 100644 --- a/com.unity.testing.hdrp/RP_Assets/HDRP_Test_Def.asset +++ b/com.unity.testing.hdrp/RP_Assets/HDRP_Test_Def.asset @@ -234,12 +234,12 @@ MonoBehaviour: supportRayTracing: 0 lightLoopSettings: cookieAtlasSize: 4096 - cookieFormat: 74 + cookieAtlasFormat: 74 pointCookieSize: 512 cubeCookieTexArraySize: 16 cookieAtlasLastValidMip: 0 - cookieTexArraySize: 1 - planarReflectionAtlasSize: 8192 + cookieAreaTextureArraySize: 16 + planarReflectionAtlasSize: 2048 reflectionProbeCacheSize: 128 reflectionCubemapSize: 128 reflectionCacheCompressed: 0 @@ -293,7 +293,6 @@ MonoBehaviour: postProcessSettings: m_LutSize: 32 lutFormat: 48 - bufferFormat: 74 dynamicResolutionSettings: enabled: 0 maxPercentage: 100 From e7cdff52ae944614fb52da0a7b0629c02d4b1351 Mon Sep 17 00:00:00 2001 From: Evgenii Date: Mon, 30 Mar 2020 12:08:29 -0700 Subject: [PATCH 53/63] Fix default UI value --- .../Settings/FrameSettingsUI.Drawers.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/FrameSettingsUI.Drawers.cs b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/FrameSettingsUI.Drawers.cs index 4f6b13b1e5e..4ebb6ec79e3 100644 --- a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/FrameSettingsUI.Drawers.cs +++ b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/FrameSettingsUI.Drawers.cs @@ -281,25 +281,33 @@ static void Drawer_SectionLightingSettings(SerializedFrameSettings serialized, E // SSS area.AmmendInfo( - FrameSettingsField.SubsurfaceScattering, overrideable: () => hdrpSettings.supportSubsurfaceScattering + FrameSettingsField.SubsurfaceScattering, + overridedDefaultValue: hdrpSettings.supportSubsurfaceScattering, + overrideable: () => hdrpSettings.supportSubsurfaceScattering ); area.AmmendInfo( FrameSettingsField.SssQualityMode, overridedDefaultValue: SssQualityMode.FromQualitySettings, customGetter: () => serialized.sssQualityMode.GetEnumValue(), - customSetter: v => serialized.sssQualityMode.SetEnumValue((SssQualityMode)v) + customSetter: v => serialized.sssQualityMode.SetEnumValue((SssQualityMode)v), + customOverrideable: () => hdrpSettings.supportSubsurfaceScattering + && (serialized.IsEnabled(FrameSettingsField.SubsurfaceScattering) ?? false) ); area.AmmendInfo(FrameSettingsField.SssQualityLevel, overridedDefaultValue: ScalableLevel3ForFrameSettingsUIOnly.Low, customGetter: () => (ScalableLevel3ForFrameSettingsUIOnly)serialized.sssQualityLevel.intValue, // 3 levels customSetter: v => serialized.sssQualityLevel.intValue = Math.Max(0, Math.Min((int)v, 2)), // Levels 0-2 - customOverrideable: () => (serialized.IsEnabled(FrameSettingsField.SubsurfaceScattering) ?? false) && serialized.sssQualityMode.GetEnumValue() == SssQualityMode.FromQualitySettings + customOverrideable: () => hdrpSettings.supportSubsurfaceScattering + && (serialized.IsEnabled(FrameSettingsField.SubsurfaceScattering) ?? false) + && (serialized.sssQualityMode.GetEnumValue() == SssQualityMode.FromQualitySettings) ); area.AmmendInfo(FrameSettingsField.SssCustomSampleBudget, overridedDefaultValue: (int)DefaultSssSampleBudgetForQualityLevel.Low, customGetter: () => serialized.sssCustomSampleBudget.intValue, customSetter: v => serialized.sssCustomSampleBudget.intValue = Math.Max(1, Math.Min((int)v, (int)DefaultSssSampleBudgetForQualityLevel.Max)), - customOverrideable: () => (serialized.IsEnabled(FrameSettingsField.SubsurfaceScattering) ?? false) && serialized.sssQualityMode.GetEnumValue() != SssQualityMode.FromQualitySettings + customOverrideable: () => hdrpSettings.supportSubsurfaceScattering + && (serialized.IsEnabled(FrameSettingsField.SubsurfaceScattering) ?? false) + && (serialized.sssQualityMode.GetEnumValue() != SssQualityMode.FromQualitySettings) ); area.AmmendInfo(FrameSettingsField.Volumetrics, overrideable: () => hdrpSettings.supportVolumetrics); From f594d90927eac144ab0ae40fa6b681039b48a524 Mon Sep 17 00:00:00 2001 From: Evgenii Date: Mon, 30 Mar 2020 12:12:05 -0700 Subject: [PATCH 54/63] Pass the right asset --- .../Runtime/RenderPipeline/HDRenderPipeline.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 37b8807ffaa..0833ab2775a 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -2533,7 +2533,7 @@ out ScriptableCullingParameters cullingParams FrameSettings.AggregateFrameSettings(ref currentFrameSettings, camera, additionalCameraData, m_Asset, m_DefaultAsset); // With the Frame Settings now properly set up, we can resolve the sample budget. - currentFrameSettings.sssResolvedSampleBudget = currentFrameSettings.GetResolvedSssSampleBudget(m_DefaultAsset); + currentFrameSettings.sssResolvedSampleBudget = currentFrameSettings.GetResolvedSssSampleBudget(m_Asset); // Specific pass to simply display the content of the camera buffer if users have fill it themselves (like video player) if (additionalCameraData.fullscreenPassthrough) From f1e066115d8d5de40c551543ea81f376f5914dc9 Mon Sep 17 00:00:00 2001 From: Evgenii Date: Mon, 30 Mar 2020 13:58:43 -0700 Subject: [PATCH 55/63] Update ref img 1215 --- .../Direct3D11/None/1215_Lit_SubSurfaceScattering.png | 4 ++-- .../Direct3D11/None/1215_Lit_SubSurfaceScattering.png.meta | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/1215_Lit_SubSurfaceScattering.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/1215_Lit_SubSurfaceScattering.png index ea70334ca4c..b3b58e2cd43 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/1215_Lit_SubSurfaceScattering.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/1215_Lit_SubSurfaceScattering.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:be148ed922104444adfbc8cf8026ada7b546b78c6941e04dff918f35f2d5dc81 -size 91196 +oid sha256:a3f9d4b917de71ce7975f857edc6a7b081c133f9efe80c33284377fded3b26c4 +size 89840 diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/1215_Lit_SubSurfaceScattering.png.meta b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/1215_Lit_SubSurfaceScattering.png.meta index 4a351f34369..a0d6e8f1cd2 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/1215_Lit_SubSurfaceScattering.png.meta +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/1215_Lit_SubSurfaceScattering.png.meta @@ -1,9 +1,9 @@ fileFormatVersion: 2 -guid: 22413fc8a9c75b14a86f46a73590cdf1 +guid: 2a98c309f549e6144ac1d607cf4ffc41 TextureImporter: internalIDToNameTable: [] externalObjects: {} - serializedVersion: 10 + serializedVersion: 11 mipmaps: mipMapMode: 0 enableMipMap: 0 @@ -59,6 +59,7 @@ TextureImporter: compressionQualitySet: 0 textureFormatSet: 0 ignorePngGamma: 0 + applyGammaDecoding: 0 platformSettings: - serializedVersion: 3 buildTarget: DefaultTexturePlatform From 99e7433f704bbae12a63aa924b9d22e0442649d7 Mon Sep 17 00:00:00 2001 From: Sebastien Lagarde Date: Tue, 31 Mar 2020 15:02:02 +0200 Subject: [PATCH 56/63] update reference screenshots --- .../Direct3D11/None/9601_SkinnedMeshBatching-Off.png | 4 ++-- .../Direct3D11/None/9602_SkinnedMeshBatching-On.png | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/9601_SkinnedMeshBatching-Off.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/9601_SkinnedMeshBatching-Off.png index 89324747869..796080e05b9 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/9601_SkinnedMeshBatching-Off.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/9601_SkinnedMeshBatching-Off.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a59fa4fbe1783906b3e6f1ac0b316a3de1e82e7a1597d37cb35ce6944c163a1f -size 96371 +oid sha256:93b977fa41d3352f010a85e027e7760675815af1a895681cba50361ca8134d9e +size 96532 diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/9602_SkinnedMeshBatching-On.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/9602_SkinnedMeshBatching-On.png index e3324449df3..ad7de125342 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/9602_SkinnedMeshBatching-On.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/9602_SkinnedMeshBatching-On.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c2b4326166e742e4e84c5a50fbb80e542554a81d1ed1a42bc78c6a321c1251c9 -size 96359 +oid sha256:0504525f33b86e13f588212df92db086d299524a39dc2b9d5f96176c9a5183bf +size 96522 From 95fed2e57a3f0e4a49511bb2d93f982d64ac0b23 Mon Sep 17 00:00:00 2001 From: Sebastien Lagarde Date: Tue, 31 Mar 2020 15:04:21 +0200 Subject: [PATCH 57/63] Update CHANGELOG.md --- .../CHANGELOG.md | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index 4287452ec40..b39b3ac9eae 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -582,7 +582,30 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Removing unused alpha threshold depth prepass and post pass for fabric shader graph. - Transform result from CIE XYZ to sRGB color space in EvalSensitivity for iridescence. - Moved BeginCameraRendering callback right before culling. - +- Changed the visibility of the Indirect Lighting Controller component to public. +- Renamed the cubemap used for diffuse convolution to a more explicit name for the memory profiler. +- Improved behaviour of transmission color on transparent surfaces in path tracing. +- Light dimmer can now get values higher than one and was renamed to multiplier in the UI. +- Removed info box requesting volume component for Visual Environment and updated the documentation with the relevant information. +- Improved light selection oracle for light sampling in path tracing. +- Stripped ray tracing subsurface passes with ray tracing is not enabled. +- Remove LOD cross fade code for ray tracing shaders +- Removed legacy VR code +- Add range-based clipping to box lights (case 1178780) +- Improve area light culling (case 1085873) +- Light Hierarchy debug mode can now adjust Debug Exposure for visualizing high exposure scenes. +- Rejecting history for ray traced reflections based on a threshold evaluated on the neighborhood of the sampled history. +- Renamed "Environment" to "Reflection Probes" in tile/cluster debug menu. +- Utilities namespace is obsolete, moved its content to UnityEngine.Rendering (case 1204677) +- Obsolete Utilities namespace was removed, instead use UnityEngine.Rendering (case 1204677) +- Moved most of the compute shaders to the multi_compile API instead of multiple kernels. +- Use multi_compile API for deferred compute shader with shadow mask. +- Remove the raytracing rendering queue system to make recursive raytraced material work when raytracing is disabled +- Changed a few resources used by ray tracing shaders to be global resources (using register space1) for improved CPU performance. +- All custom pass volumes are now executed for one injection point instead of the first one. +- Hidden unsupported choice in emission in Materials +- Temporal Anti aliasing improvements. +- Optimized PrepareLightsForGPU (cost reduced by over 25%) and PrepareGPULightData (around twice as fast now). ## [7.1.1] - 2019-09-05 From ff74ed818b9503ca8d66133a179fc26b8923225d Mon Sep 17 00:00:00 2001 From: Sebastien Lagarde Date: Tue, 31 Mar 2020 15:05:23 +0200 Subject: [PATCH 58/63] Update CHANGELOG.md --- .../CHANGELOG.md | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index b39b3ac9eae..37becccf924 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -582,29 +582,29 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Removing unused alpha threshold depth prepass and post pass for fabric shader graph. - Transform result from CIE XYZ to sRGB color space in EvalSensitivity for iridescence. - Moved BeginCameraRendering callback right before culling. -- Changed the visibility of the Indirect Lighting Controller component to public. -- Renamed the cubemap used for diffuse convolution to a more explicit name for the memory profiler. -- Improved behaviour of transmission color on transparent surfaces in path tracing. -- Light dimmer can now get values higher than one and was renamed to multiplier in the UI. -- Removed info box requesting volume component for Visual Environment and updated the documentation with the relevant information. -- Improved light selection oracle for light sampling in path tracing. -- Stripped ray tracing subsurface passes with ray tracing is not enabled. -- Remove LOD cross fade code for ray tracing shaders -- Removed legacy VR code -- Add range-based clipping to box lights (case 1178780) -- Improve area light culling (case 1085873) -- Light Hierarchy debug mode can now adjust Debug Exposure for visualizing high exposure scenes. -- Rejecting history for ray traced reflections based on a threshold evaluated on the neighborhood of the sampled history. -- Renamed "Environment" to "Reflection Probes" in tile/cluster debug menu. -- Utilities namespace is obsolete, moved its content to UnityEngine.Rendering (case 1204677) -- Obsolete Utilities namespace was removed, instead use UnityEngine.Rendering (case 1204677) -- Moved most of the compute shaders to the multi_compile API instead of multiple kernels. -- Use multi_compile API for deferred compute shader with shadow mask. -- Remove the raytracing rendering queue system to make recursive raytraced material work when raytracing is disabled -- Changed a few resources used by ray tracing shaders to be global resources (using register space1) for improved CPU performance. -- All custom pass volumes are now executed for one injection point instead of the first one. -- Hidden unsupported choice in emission in Materials -- Temporal Anti aliasing improvements. +- Changed the visibility of the Indirect Lighting Controller component to public. +- Renamed the cubemap used for diffuse convolution to a more explicit name for the memory profiler. +- Improved behaviour of transmission color on transparent surfaces in path tracing. +- Light dimmer can now get values higher than one and was renamed to multiplier in the UI. +- Removed info box requesting volume component for Visual Environment and updated the documentation with the relevant information. +- Improved light selection oracle for light sampling in path tracing. +- Stripped ray tracing subsurface passes with ray tracing is not enabled. +- Remove LOD cross fade code for ray tracing shaders +- Removed legacy VR code +- Add range-based clipping to box lights (case 1178780) +- Improve area light culling (case 1085873) +- Light Hierarchy debug mode can now adjust Debug Exposure for visualizing high exposure scenes. +- Rejecting history for ray traced reflections based on a threshold evaluated on the neighborhood of the sampled history. +- Renamed "Environment" to "Reflection Probes" in tile/cluster debug menu. +- Utilities namespace is obsolete, moved its content to UnityEngine.Rendering (case 1204677) +- Obsolete Utilities namespace was removed, instead use UnityEngine.Rendering (case 1204677) +- Moved most of the compute shaders to the multi_compile API instead of multiple kernels. +- Use multi_compile API for deferred compute shader with shadow mask. +- Remove the raytracing rendering queue system to make recursive raytraced material work when raytracing is disabled +- Changed a few resources used by ray tracing shaders to be global resources (using register space1) for improved CPU performance. +- All custom pass volumes are now executed for one injection point instead of the first one. +- Hidden unsupported choice in emission in Materials +- Temporal Anti aliasing improvements. - Optimized PrepareLightsForGPU (cost reduced by over 25%) and PrepareGPULightData (around twice as fast now). ## [7.1.1] - 2019-09-05 From 2959232af86cc139184e57bacbec5c25e170df04 Mon Sep 17 00:00:00 2001 From: Evgenii Date: Wed, 1 Apr 2020 12:59:09 -0700 Subject: [PATCH 59/63] Switch to RTHandles --- .../VolumetricLighting/VolumetricLighting.cs | 110 +++++++----------- .../Runtime/RenderPipeline/Camera/HDCamera.cs | 2 +- .../HDRenderPipeline.LightLoop.cs | 13 ++- 3 files changed, 51 insertions(+), 74 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs index ea92ffc7979..4ce0a499e7a 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs @@ -70,7 +70,7 @@ public static Vector3 AlbedoFromMeanFreePathAndScattering(float meanFreePath, Ve struct DensityVolumeList { - public List bounds; + public List bounds; public List density; } @@ -81,7 +81,8 @@ struct VBufferParameters public Vector4 depthEncodingParams; public Vector4 depthDecodingParams; - public VBufferParameters(Vector3Int viewportSize, float depthExtent, float camNear, float camFar, float camVFoV, float sliceDistributionUniformity, float voxelSize) + public VBufferParameters(Vector3Int viewportSize, float depthExtent, float camNear, float camFar, float camVFoV, + float sliceDistributionUniformity, float voxelSize) { this.viewportSize = viewportSize; this.voxelSize = voxelSize; @@ -176,8 +177,8 @@ public partial class HDRenderPipeline ComputeBuffer m_VisibleVolumeDataBuffer = null; // These two buffers do not depend on the frameID and are therefore shared by all views. - RenderTexture m_DensityBuffer; - RenderTexture m_LightingBuffer; + RTHandle m_DensityBuffer; + RTHandle m_LightingBuffer; // Is the feature globally disabled? bool m_SupportVolumetrics = false; @@ -303,32 +304,26 @@ static internal void UpdateVolumetricBufferParams(HDCamera hdCamera, int frameIn // Do not access 'rt.name', it allocates memory every time... // Have to manually cache and pass the name. - static internal void ResizeVolumetricBuffer(ref RenderTexture rt, string name, int viewportWidth, int viewportHeight, int viewportDepth) + static internal void ResizeVolumetricBuffer(ref RTHandle rt, string name, int viewportWidth, int viewportHeight, int viewportDepth) { Debug.Assert(rt != null); - int width = rt.width; - int height = rt.height; - int depth = rt.volumeDepth; + int width = rt.rt.width; + int height = rt.rt.height; + int depth = rt.rt.volumeDepth; bool realloc = (width < viewportWidth) || (height < viewportHeight) || (depth < viewportDepth); if (realloc) { - rt.Release(); + RTHandles.Release(rt); width = Math.Max(width, viewportWidth); height = Math.Max(height, viewportHeight); depth = Math.Max(depth, viewportDepth); - rt = new RenderTexture(width: width, height: height, depth: 0, format: GraphicsFormat.R16G16B16A16_SFloat, mipCount: 0); // 8888_sRGB is not precise enough - rt.name = name; - rt.dimension = TextureDimension.Tex3D; - rt.volumeDepth = depth; - rt.enableRandomWrite = true; - - bool success = rt.Create(); - Debug.Assert(success); + rt = RTHandles.Alloc(width, height, depth, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, // 8888_sRGB is not precise enough + dimension: TextureDimension.Tex3D, enableRandomWrite: true, name: name); } } @@ -339,7 +334,7 @@ static internal void CreateVolumetricHistoryBuffers(HDCamera hdCamera, int buffe Debug.Assert(hdCamera.volumetricHistoryBuffers == null); - hdCamera.volumetricHistoryBuffers = new RenderTexture[bufferCount]; + hdCamera.volumetricHistoryBuffers = new RTHandle[bufferCount]; // Allocation happens early in the frame. So we shouldn't rely on 'hdCamera.vBufferParams'. // Allocate the smallest possible 3D texture. @@ -348,15 +343,8 @@ static internal void CreateVolumetricHistoryBuffers(HDCamera hdCamera, int buffe for (int i = 0; i < bufferCount; i++) { - hdCamera.volumetricHistoryBuffers[i] = new RenderTexture(width: minSize, height: minSize, depth: 0, format: GraphicsFormat.R16G16B16A16_SFloat, mipCount: 0); // 8888_sRGB is not precise enough - hdCamera.volumetricHistoryBuffers[i].name = string.Format("VBufferHistory{0}", i); - hdCamera.volumetricHistoryBuffers[i].dimension = TextureDimension.Tex3D; - hdCamera.volumetricHistoryBuffers[i].volumeDepth = minSize; - hdCamera.volumetricHistoryBuffers[i].enableRandomWrite = true; - hdCamera.volumetricHistoryBuffers[i].Create(); - - bool success = hdCamera.volumetricHistoryBuffers[i].Create(); - Debug.Assert(success); + hdCamera.volumetricHistoryBuffers[i] = RTHandles.Alloc(minSize, minSize, minSize, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, // 8888_sRGB is not precise enough + dimension: TextureDimension.Tex3D, enableRandomWrite: true, name: string.Format("VBufferHistory{0}", i)); } hdCamera.volumetricHistoryIsValid = false; @@ -371,7 +359,7 @@ static internal void DestroyVolumetricHistoryBuffers(HDCamera hdCamera) for (int i = 0; i < bufferCount; i++) { - hdCamera.volumetricHistoryBuffers[i].Release(); + RTHandles.Release(hdCamera.volumetricHistoryBuffers[i]); } hdCamera.volumetricHistoryBuffers = null; @@ -426,29 +414,17 @@ internal void CreateVolumetricLightingBuffers() // We will perform rescaling manually, in a custom manner, based on volume parameters. const int minSize = 4; - m_DensityBuffer = new RenderTexture(width: minSize, height: minSize, depth: 0, format: GraphicsFormat.R16G16B16A16_SFloat, mipCount: 0); // 8888_sRGB is not precise enough - m_DensityBuffer.name = "VBufferDensity"; - m_DensityBuffer.dimension = TextureDimension.Tex3D; - m_DensityBuffer.volumeDepth = minSize; - m_DensityBuffer.enableRandomWrite = true; - - bool success = m_DensityBuffer.Create(); - Debug.Assert(success); - - m_LightingBuffer = new RenderTexture(width: minSize, height: minSize, depth: 0, format: GraphicsFormat.R16G16B16A16_SFloat, mipCount: 0); // 8888_sRGB is not precise enough - m_LightingBuffer.name = "VBufferLighting"; - m_LightingBuffer.dimension = TextureDimension.Tex3D; - m_LightingBuffer.volumeDepth = minSize; - m_LightingBuffer.enableRandomWrite = true; + m_DensityBuffer = RTHandles.Alloc(minSize, minSize, minSize, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, // 8888_sRGB is not precise enough + dimension: TextureDimension.Tex3D, enableRandomWrite: true, name: "VBufferDensity"); - success = m_LightingBuffer.Create(); - Debug.Assert(success); + m_LightingBuffer = RTHandles.Alloc(minSize, minSize, minSize, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, // 8888_sRGB is not precise enough + dimension: TextureDimension.Tex3D, enableRandomWrite: true, name: "VBufferLighting"); } internal void DestroyVolumetricLightingBuffers() { - SafeDestroy(ref m_LightingBuffer); - SafeDestroy(ref m_DensityBuffer); + RTHandles.Release(m_LightingBuffer); + RTHandles.Release(m_DensityBuffer); CoreUtils.SafeRelease(m_VisibleVolumeDataBuffer); CoreUtils.SafeRelease(m_VisibleVolumeBoundsBuffer); @@ -560,18 +536,18 @@ void PushVolumetricLightingGlobalParams(HDCamera hdCamera, CommandBuffer cmd, in // The history & feedback buffers are specific to the camera. // These 2 types of buffers can have different sizes. // Additionally, history buffers can have different sizes, since they are not resized at the same time. - Vector3Int lightingBufferSize = new Vector3Int(m_LightingBuffer.width, m_LightingBuffer.height, m_LightingBuffer.volumeDepth); + Vector3Int lightingBufferSize = new Vector3Int(m_LightingBuffer.rt.width, m_LightingBuffer.rt.height, m_LightingBuffer.rt.volumeDepth); - Debug.Assert(m_LightingBuffer.width == m_DensityBuffer.width); - Debug.Assert(m_LightingBuffer.height == m_DensityBuffer.height); + Debug.Assert(m_LightingBuffer.rt.width == m_DensityBuffer.rt.width); + Debug.Assert(m_LightingBuffer.rt.height == m_DensityBuffer.rt.height); Vector3Int historyBufferSize = Vector3Int.zero; if (hdCamera.IsVolumetricReprojectionEnabled()) { - RenderTexture historyRT = hdCamera.volumetricHistoryBuffers[prevIdx]; + RTHandle historyRT = hdCamera.volumetricHistoryBuffers[prevIdx]; - historyBufferSize = new Vector3Int(historyRT.width, historyRT.height, historyRT.volumeDepth); + historyBufferSize = new Vector3Int(historyRT.rt.width, historyRT.rt.height, historyRT.rt.volumeDepth); // Handle case of first frame. When we are on the first frame, we reuse the value of original frame. if (historyBufferSize.x == 0.0f && historyBufferSize.y == 0.0f) @@ -733,7 +709,7 @@ VolumeVoxelizationParameters PrepareVolumeVoxelizationParameters(HDCamera hdCame } static void VolumeVoxelizationPass( in VolumeVoxelizationParameters parameters, - RenderTexture densityBuffer, + RTHandle densityBuffer, ComputeBuffer visibleVolumeBoundsBuffer, ComputeBuffer visibleVolumeDataBuffer, ComputeBuffer bigTileLightList, @@ -744,16 +720,16 @@ static void VolumeVoxelizationPass( in VolumeVoxelizationParameters parameters, if (parameters.tiledLighting) cmd.SetComputeBufferParam(parameters.voxelizationCS, parameters.voxelizationKernel, HDShaderIDs.g_vBigTileLightList, bigTileLightList); - cmd.SetComputeTextureParam(parameters.voxelizationCS, parameters.voxelizationKernel, HDShaderIDs._VBufferDensity, densityBuffer); - cmd.SetComputeBufferParam(parameters.voxelizationCS, parameters.voxelizationKernel, HDShaderIDs._VolumeBounds, visibleVolumeBoundsBuffer); - cmd.SetComputeBufferParam(parameters.voxelizationCS, parameters.voxelizationKernel, HDShaderIDs._VolumeData, visibleVolumeDataBuffer); + cmd.SetComputeTextureParam(parameters.voxelizationCS, parameters.voxelizationKernel, HDShaderIDs._VBufferDensity, densityBuffer); + cmd.SetComputeBufferParam( parameters.voxelizationCS, parameters.voxelizationKernel, HDShaderIDs._VolumeBounds, visibleVolumeBoundsBuffer); + cmd.SetComputeBufferParam( parameters.voxelizationCS, parameters.voxelizationKernel, HDShaderIDs._VolumeData, visibleVolumeDataBuffer); cmd.SetComputeTextureParam(parameters.voxelizationCS, parameters.voxelizationKernel, HDShaderIDs._VolumeMaskAtlas, parameters.volumeAtlas); // TODO: set the constant buffer data only once. - cmd.SetComputeMatrixArrayParam(parameters.voxelizationCS, HDShaderIDs._VBufferCoordToViewDirWS, parameters.pixelCoordToViewDirWS); - cmd.SetComputeFloatParam(parameters.voxelizationCS, HDShaderIDs._VBufferUnitDepthTexelSpacing, parameters.unitDepthTexelSpacing); - cmd.SetComputeIntParam(parameters.voxelizationCS, HDShaderIDs._NumVisibleDensityVolumes, parameters.numVisibleVolumes); - cmd.SetComputeVectorParam(parameters.voxelizationCS, HDShaderIDs._VolumeMaskDimensions, parameters.volumeAtlasDimensions); + cmd.SetComputeMatrixArrayParam(parameters.voxelizationCS, HDShaderIDs._VBufferCoordToViewDirWS, parameters.pixelCoordToViewDirWS); + cmd.SetComputeFloatParam( parameters.voxelizationCS, HDShaderIDs._VBufferUnitDepthTexelSpacing, parameters.unitDepthTexelSpacing); + cmd.SetComputeIntParam( parameters.voxelizationCS, HDShaderIDs._NumVisibleDensityVolumes, parameters.numVisibleVolumes); + cmd.SetComputeVectorParam( parameters.voxelizationCS, HDShaderIDs._VolumeMaskDimensions, parameters.volumeAtlasDimensions); // The shader defines GROUP_SIZE_1D = 8. cmd.DispatchCompute(parameters.voxelizationCS, parameters.voxelizationKernel, ((int)parameters.resolution.x + 7) / 8, ((int)parameters.resolution.y + 7) / 8, parameters.viewCount); @@ -908,12 +884,12 @@ VolumetricLightingParameters PrepareVolumetricLightingParameters(HDCamera hdCame } static void VolumetricLightingPass( in VolumetricLightingParameters parameters, - RenderTexture densityBuffer, - RenderTexture lightingBuffer, - RenderTexture historyRT, - RenderTexture feedbackRT, - ComputeBuffer bigTileLightList, - CommandBuffer cmd) + RTHandle densityBuffer, + RTHandle lightingBuffer, + RTHandle historyRT, + RTHandle feedbackRT, + ComputeBuffer bigTileLightList, + CommandBuffer cmd) { cmd.SetComputeIntParam(parameters.volumetricLightingCS, HDShaderIDs._NumTileBigTileX, parameters.numBigTileX); cmd.SetComputeIntParam(parameters.volumetricLightingCS, HDShaderIDs._NumTileBigTileY, parameters.numBigTileY); @@ -942,7 +918,7 @@ static void VolumetricLightingPass( in VolumetricLightingParameters parameters, cmd.DispatchCompute(parameters.volumetricLightingCS, parameters.volumetricLightingKernel, ((int)parameters.resolution.x + 7) / 8, ((int)parameters.resolution.y + 7) / 8, parameters.viewCount); } - static void FilterVolumetricLighting(in VolumetricLightingParameters parameters, RenderTexture outputBuffer, RenderTexture inputBuffer, CommandBuffer cmd) + static void FilterVolumetricLighting(in VolumetricLightingParameters parameters, RTHandle outputBuffer, RTHandle inputBuffer, CommandBuffer cmd) { using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.VolumetricLightingFiltering))) { @@ -966,7 +942,7 @@ void VolumetricLightingPass(HDCamera hdCamera, CommandBuffer cmd, int frameIndex using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.VolumetricLighting))) { - RenderTexture feedbackRT = null, historyRT = null; + RTHandle feedbackRT = null, historyRT = null; if (parameters.enableReprojection) { diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs index 344f4c56cdd..9740a3e6e1e 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs @@ -187,7 +187,7 @@ internal struct ShadowHistoryUsage internal Rect finalViewport; // This will have the correct viewport position and the size will be full resolution (ie : not taking dynamic rez into account) internal int colorPyramidHistoryMipCount = 0; internal VBufferParameters[] vBufferParams; // Double-buffered; needed even if reprojection is off - internal RenderTexture[] volumetricHistoryBuffers; // Double-buffered; only used for reprojection + internal RTHandle[] volumetricHistoryBuffers; // Double-buffered; only used for reprojection // Currently the frame count is not increase every render, for ray tracing shadow filtering. We need to have a number that increases every render internal uint cameraFrameCount = 0; internal bool animateMaterials; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index 1cb64728818..0f5eb807ce7 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -472,11 +472,11 @@ TextureHandle VolumetricLightingPass(RenderGraph renderGraph, HDCamera hdCamera, }, HDShaderIDs._VBufferLighting)); if (passData.parameters.enableReprojection) { - // Cannot import a RenderTexture => WILL BE HORRIBLY BROKEN. - //passData.feedbackBuffer = builder.WriteTexture(renderGraph.ImportTexture(hdCamera.volumetricHistoryBuffers[0])); - //passData.historyBuffer = builder.ReadTexture(renderGraph.ImportTexture(hdCamera.volumetricHistoryBuffers[1])); - passData.feedbackBuffer = passData.lightingBuffer; - passData.historyBuffer = passData.densityBuffer; + var currIdx = (frameIndex + 0) & 1; + var prevIdx = (frameIndex + 1) & 1; + + passData.feedbackBuffer = builder.WriteTexture(renderGraph.ImportTexture(hdCamera.volumetricHistoryBuffers[currIdx])); + passData.historyBuffer = builder.ReadTexture(renderGraph.ImportTexture(hdCamera.volumetricHistoryBuffers[prevIdx])); } HDShadowManager.ReadShadowResult(shadowResult, builder); @@ -486,10 +486,11 @@ TextureHandle VolumetricLightingPass(RenderGraph renderGraph, HDCamera hdCamera, { RTHandle densityBufferRT = ctx.resources.GetTexture(data.densityBuffer); RTHandle lightinBufferRT = ctx.resources.GetTexture(data.lightingBuffer); + VolumetricLightingPass( data.parameters, densityBufferRT, lightinBufferRT, - data.parameters.enableReprojection ? ctx.resources.GetTexture(data.historyBuffer) : null, + data.parameters.enableReprojection ? ctx.resources.GetTexture(data.historyBuffer) : null, data.parameters.enableReprojection ? ctx.resources.GetTexture(data.feedbackBuffer) : null, data.bigTileLightListBuffer, ctx.cmd); From 043cfd79f809ec02cda6ca0e352c478a8879e61b Mon Sep 17 00:00:00 2001 From: Evgenii Date: Wed, 1 Apr 2020 13:20:39 -0700 Subject: [PATCH 60/63] Rename textures used by the fog filtering pass --- .../Lighting/VolumetricLighting/VolumetricLighting.cs | 8 ++++---- .../VolumetricLightingFiltering.compute | 8 ++++---- .../Runtime/RenderPipeline/HDStringConstants.cs | 2 ++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs index 4ce0a499e7a..2a64939f8ef 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs @@ -923,12 +923,12 @@ static void FilterVolumetricLighting(in VolumetricLightingParameters parameters, using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.VolumetricLightingFiltering))) { // The shader defines GROUP_SIZE_1D = 8. - cmd.SetComputeTextureParam(parameters.volumetricLightingFilteringCS, parameters.volumetricFilteringKernelX, HDShaderIDs._VBufferFeedback, inputBuffer); // Read - cmd.SetComputeTextureParam(parameters.volumetricLightingFilteringCS, parameters.volumetricFilteringKernelX, HDShaderIDs._VBufferLighting, outputBuffer); // Write + cmd.SetComputeTextureParam(parameters.volumetricLightingFilteringCS, parameters.volumetricFilteringKernelX, HDShaderIDs._VBufferFilteringInput, inputBuffer); // Read + cmd.SetComputeTextureParam(parameters.volumetricLightingFilteringCS, parameters.volumetricFilteringKernelX, HDShaderIDs._VBufferFilteringOutput, outputBuffer); // Write cmd.DispatchCompute(parameters.volumetricLightingFilteringCS, parameters.volumetricFilteringKernelX, ((int)parameters.resolution.x + 7) / 8, ((int)parameters.resolution.y + 7) / 8, parameters.viewCount); - cmd.SetComputeTextureParam(parameters.volumetricLightingFilteringCS, parameters.volumetricFilteringKernelY, HDShaderIDs._VBufferFeedback, outputBuffer); // Read - cmd.SetComputeTextureParam(parameters.volumetricLightingFilteringCS, parameters.volumetricFilteringKernelY, HDShaderIDs._VBufferLighting, inputBuffer); // Write + cmd.SetComputeTextureParam(parameters.volumetricLightingFilteringCS, parameters.volumetricFilteringKernelY, HDShaderIDs._VBufferFilteringInput, outputBuffer); // Read + cmd.SetComputeTextureParam(parameters.volumetricLightingFilteringCS, parameters.volumetricFilteringKernelY, HDShaderIDs._VBufferFilteringOutput, inputBuffer); // Write cmd.DispatchCompute(parameters.volumetricLightingFilteringCS, parameters.volumetricFilteringKernelY, ((int)parameters.resolution.x + 7) / 8, ((int)parameters.resolution.y + 7) / 8, parameters.viewCount); } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLightingFiltering.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLightingFiltering.compute index 167b54b4015..4b674ece566 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLightingFiltering.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLightingFiltering.compute @@ -20,8 +20,8 @@ // Inputs & outputs //-------------------------------------------------------------------------------------------------- -RW_TEXTURE3D(float4, _VBufferLighting); -RW_TEXTURE3D(float4, _VBufferFeedback); +RW_TEXTURE3D(float4, _VBufferFilteringInput); +RW_TEXTURE3D(float4, _VBufferFilteringOutput); #define SIGMA_FILTER 2.0 @@ -69,7 +69,7 @@ void FilterVolumetricLighting(uint3 dispatchThreadId : SV_DispatchThreadID, // Compute the next tapping coordinate int3 tapCoord = int3(voxelCoord.x, voxelCoord.y, voxelCoord.z) + vec * idx; // Tap the value we should be tapping from - float4 currentValue = _VBufferFeedback[tapCoord]; + float4 currentValue = _VBufferFilteringInput[tapCoord]; // Compute the weight for this tap float weight = Gaussian(abs(idx), SIGMA_FILTER); @@ -85,6 +85,6 @@ void FilterVolumetricLighting(uint3 dispatchThreadId : SV_DispatchThreadID, sumW += weight; } // Normalize and output - _VBufferLighting[voxelCoord] = value / sumW; + _VBufferFilteringOutput[voxelCoord] = value / sumW; } } 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 6b88079b730..9242991890e 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs @@ -523,6 +523,8 @@ static class HDShaderIDs public static readonly int _VBufferLighting = Shader.PropertyToID("_VBufferLighting"); public static readonly int _VBufferHistory = Shader.PropertyToID("_VBufferHistory"); public static readonly int _VBufferFeedback = Shader.PropertyToID("_VBufferFeedback"); + public static readonly int _VBufferFilteringInput = Shader.PropertyToID("_VBufferFilteringInput"); + public static readonly int _VBufferFilteringOutput = Shader.PropertyToID("_VBufferFilteringOutput"); public static readonly int _VBufferHistoryIsValid = Shader.PropertyToID("_VBufferHistoryIsValid"); public static readonly int _VBufferSampleOffset = Shader.PropertyToID("_VBufferSampleOffset"); public static readonly int _VolumeBounds = Shader.PropertyToID("_VolumeBounds"); From 57bb67dfca15163f099dd7eed4c3fae58a5ca907 Mon Sep 17 00:00:00 2001 From: Evgenii Date: Fri, 17 Apr 2020 20:13:20 -0700 Subject: [PATCH 61/63] Fix reprojection --- .../VolumetricLighting/VolumetricLighting.compute | 4 ++-- .../Lighting/VolumetricLighting/VolumetricLighting.cs | 11 +++++++---- .../VolumetricLighting/VolumetricLighting.cs.hlsl | 7 +++++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute index d76fac89429..adbecb31e75 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute @@ -548,8 +548,8 @@ void FillVolumetricLightingBuffer(LightLoopContext context, uint featureFlags, _VBufferPrevViewportSize, _VBufferHistoryViewportScale, _VBufferHistoryViewportLimit, - _VBufferPrevDepthEncodingParams, - _VBufferPrevDepthDecodingParams, + _VBufferPrevDistanceEncodingParams, + _VBufferPrevDistanceDecodingParams, false, true) * float4(GetInversePreviousExposureMultiplier().xxx, 1); bool reprojSuccess = (_VBufferHistoryIsValid != 0) && (reprojValue.a != 0); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs index 8004fa96804..60d4a5d2fe6 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs @@ -58,11 +58,14 @@ unsafe struct ShaderVariablesVolumetric public fixed float _AmbientProbeCoeffs[7 * 4]; // 3 bands of SH, packed, rescaled and convolved with the phase function public float _VBufferVoxelSize; + public float _HaveToPad; + public float _OtherwiseTheBuffer; + public float _IsFilledWithGarbage; public Vector4 _VBufferPrevViewportSize; public Vector4 _VBufferHistoryViewportScale; public Vector4 _VBufferHistoryViewportLimit; - public Vector4 _VBufferPrevDepthEncodingParams; - public Vector4 _VBufferPrevDepthDecodingParams; + public Vector4 _VBufferPrevDistanceEncodingParams; + public Vector4 _VBufferPrevDistanceDecodingParams; // TODO: Remove if equals to the ones in global CB? public uint _NumTileBigTileX; @@ -743,8 +746,8 @@ unsafe void UpdateShaderVariableslVolumetrics(ref ShaderVariablesVolumetric cb, cb._VBufferPrevViewportSize = new Vector4(pvp.x, pvp.y, 1.0f / pvp.x, 1.0f / pvp.y); cb._VBufferHistoryViewportScale = prevParams.ComputeViewportScale(historyBufferSize); cb._VBufferHistoryViewportLimit = prevParams.ComputeViewportLimit(historyBufferSize); - cb._VBufferPrevDepthEncodingParams = prevParams.depthEncodingParams; - cb._VBufferPrevDepthDecodingParams = prevParams.depthDecodingParams; + cb._VBufferPrevDistanceEncodingParams = prevParams.depthEncodingParams; + cb._VBufferPrevDistanceDecodingParams = prevParams.depthDecodingParams; cb._NumTileBigTileX = (uint)GetNumTileBigTileX(hdCamera); cb._NumTileBigTileY = (uint)GetNumTileBigTileY(hdCamera); } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs.hlsl index 4195c830f4b..9f64f8bf410 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs.hlsl @@ -32,11 +32,14 @@ CBUFFER_START(ShaderVariablesVolumetric) float4 _VolumeMaskDimensions; float4 _AmbientProbeCoeffs[7]; float _VBufferVoxelSize; + float _HaveToPad; + float _OtherwiseTheBuffer; + float _IsFilledWithGarbage; float4 _VBufferPrevViewportSize; float4 _VBufferHistoryViewportScale; float4 _VBufferHistoryViewportLimit; - float4 _VBufferPrevDepthEncodingParams; - float4 _VBufferPrevDepthDecodingParams; + float4 _VBufferPrevDistanceEncodingParams; + float4 _VBufferPrevDistanceDecodingParams; uint _NumTileBigTileX; uint _NumTileBigTileY; CBUFFER_END From e37974351794a206e909262dcb960742872e8353 Mon Sep 17 00:00:00 2001 From: Sebastien Lagarde Date: Sat, 18 Apr 2020 15:04:30 +0200 Subject: [PATCH 62/63] Fix shader warning + typo+ --- .../AtmosphericScattering/AtmosphericScattering.hlsl | 6 +++--- .../Runtime/Sky/SkyManager.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/AtmosphericScattering.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/AtmosphericScattering.hlsl index c37867f7781..dabaf8b19cd 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/AtmosphericScattering.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/AtmosphericScattering.hlsl @@ -279,10 +279,10 @@ void EvaluateAtmosphericScattering(PositionInputs posInput, float3 V, out float3 { float4 value = SampleVBuffer(TEXTURE3D_ARGS(_VBufferLighting, s_linear_clamp_sampler), posInput.positionNDC, - fogFragDist, + fogFragDist, _VBufferViewportSize, - _VBufferLightingViewportScale, - _VBufferLightingViewportLimit, + _VBufferLightingViewportScale.xyz, + _VBufferLightingViewportLimit.xyz, _VBufferDistanceEncodingParams, _VBufferDistanceDecodingParams, true, false); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs b/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs index 5cc402f4117..de6b404b536 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs @@ -906,7 +906,7 @@ public void RenderSky(HDCamera hdCamera, Light sunLight, RTHandle colorBuffer, R public void RenderOpaqueAtmosphericScattering(CommandBuffer cmd, HDCamera hdCamera, RTHandle colorBuffer, - RenderTexture volumetricLighting, + RTHandle volumetricLighting, RTHandle intermediateBuffer, RTHandle depthBuffer, Matrix4x4 pixelCoordToViewDirWS, bool isMSAA) From 96e76a4d2fac9fdedb4a1ce7fcbadff8055e5ec8 Mon Sep 17 00:00:00 2001 From: Sebastien Lagarde Date: Sat, 18 Apr 2020 15:08:26 +0200 Subject: [PATCH 63/63] fix another shader warning --- .../Lighting/VolumetricLighting/VolumetricLighting.compute | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute index adbecb31e75..7874d5c8ad8 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.compute @@ -546,8 +546,8 @@ void FillVolumetricLightingBuffer(LightLoopContext context, uint featureFlags, _PrevCamPosRWS, UNITY_MATRIX_PREV_VP, _VBufferPrevViewportSize, - _VBufferHistoryViewportScale, - _VBufferHistoryViewportLimit, + _VBufferHistoryViewportScale.xyz, + _VBufferHistoryViewportLimit.xyz, _VBufferPrevDistanceEncodingParams, _VBufferPrevDistanceDecodingParams, false, true) * float4(GetInversePreviousExposureMultiplier().xxx, 1);