diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/LinuxEditor/Vulkan/None/1210_Lit_BentNormal.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/LinuxEditor/Vulkan/None/1210_Lit_BentNormal.png index 51d7c1faaa8..427e89e5b72 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/LinuxEditor/Vulkan/None/1210_Lit_BentNormal.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/LinuxEditor/Vulkan/None/1210_Lit_BentNormal.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bdaa894b3cd3a8a6ae48d3cfc20d2068920db6aefc00f40621149647cfc4a9ee -size 174564 +oid sha256:ef77d89a884c94e69c0981c576f7538b8305e69ac0e6d3e33a548207f38ac82c +size 153225 diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/OSXEditor/Metal/None/1210_Lit_BentNormal.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/OSXEditor/Metal/None/1210_Lit_BentNormal.png index a4789b62f38..d5c04b086da 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/OSXEditor/Metal/None/1210_Lit_BentNormal.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/OSXEditor/Metal/None/1210_Lit_BentNormal.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:43d968134620179d1a0998174fe208aff8922959dad93d77538cdebb2fbc63db -size 152713 +oid sha256:2a277bafebf1d50f506144f0c18a4448dd3eca2215cf092ba1eb61ff61ee7aff +size 152947 diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/1210_Lit_BentNormal.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/1210_Lit_BentNormal.png index 0bd6dcb3171..0802ee6697b 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/1210_Lit_BentNormal.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/1210_Lit_BentNormal.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:22a865a7db80ef101242ce4f23cf3d846ec542cac7422810ed7424a7351c7f7c -size 153072 +oid sha256:255b0c7bb1445a57659c17f3d7bcc4a05bd5970f19aadaa6c73b0da7e9e83096 +size 153148 diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/1210_Lit_BentNormal.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/1210_Lit_BentNormal.png index 7e770153d4a..6b320949612 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/1210_Lit_BentNormal.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/1210_Lit_BentNormal.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:638dbedea46a9b053d04bf35f5269631246ab215a606c091f2720e9a1f2867a8 -size 153160 +oid sha256:f60718ffd796662561b9ac0a3d48fa55d3943b09c2ca942e420c6ece8882e9b7 +size 153158 diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Vulkan/None/1210_Lit_BentNormal.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Vulkan/None/1210_Lit_BentNormal.png index 8cb522aeaf4..427e89e5b72 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Vulkan/None/1210_Lit_BentNormal.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Vulkan/None/1210_Lit_BentNormal.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7deb071c27433c51b50c915065817b466252555d2e3b9428593eb2acf3183e55 -size 152903 +oid sha256:ef77d89a884c94e69c0981c576f7538b8305e69ac0e6d3e33a548207f38ac82c +size 153225 diff --git a/com.unity.render-pipelines.core/ShaderLibrary/CommonLighting.hlsl b/com.unity.render-pipelines.core/ShaderLibrary/CommonLighting.hlsl index 05617ac44f4..c9dbf658d2f 100644 --- a/com.unity.render-pipelines.core/ShaderLibrary/CommonLighting.hlsl +++ b/com.unity.render-pipelines.core/ShaderLibrary/CommonLighting.hlsl @@ -245,7 +245,7 @@ real3 GTAOMultiBounce(real visibility, real3 albedo) return max(x, ((x * a + b) * x + c) * x); } -// Based on Oat and Sander's 2008 technique +// Based on Oat and Sander's 2007 technique // Area/solidAngle of intersection of two cone real SphericalCapIntersectionSolidArea(real cosC1, real cosC2, real cosB) { @@ -279,7 +279,7 @@ real SphericalCapIntersectionSolidArea(real cosC1, real cosC2, real cosB) // ref: Practical Realtime Strategies for Accurate Indirect Occlusion // http://blog.selfshadow.com/publications/s2016-shading-course/#course_content // Original Cone-Cone method with cosine weighted assumption (p129 s2016_pbs_activision_occlusion) -real GetSpecularOcclusionFromBentAO(real3 V, real3 bentNormalWS, real3 normalWS, real ambientOcclusion, real roughness) +real GetSpecularOcclusionFromBentAO_ConeCone(real3 V, real3 bentNormalWS, real3 normalWS, real ambientOcclusion, real roughness) { // Retrieve cone angle // Ambient occlusion is cosine weighted, thus use following equation. See slide 129 @@ -290,6 +290,40 @@ real GetSpecularOcclusionFromBentAO(real3 V, real3 bentNormalWS, real3 normalWS, return SphericalCapIntersectionSolidArea(cosAv, cosAs, cosB) / (TWO_PI * (1.0 - cosAs)); } +real GetSpecularOcclusionFromBentAO(real3 V, real3 bentNormalWS, real3 normalWS, real ambientOcclusion, real roughness) +{ + // Pseudo code: + //SphericalGaussian NDF = WarpedGGXDistribution(normalWS, roughness, V); + //SphericalGaussian Visibility = VisibilityConeSG(bentNormalWS, ambientOcclusion); + //SphericalGaussian UpperHemisphere = UpperHemisphereSG(normalWS); + //return saturate( InnerProduct(NDF, Visibility) / InnerProduct(NDF, UpperHemisphere) ); + + // 1. Approximate visibility cone with a spherical gaussian of amplitude A=1 + // For a cone angle X, we can determine sharpness so that all point inside the cone have a value > Y + // sharpness = (log(Y) - log(A)) / (cos(X) - 1) + // For AO cone, cos(X) = sqrt(1 - ambientOcclusion) + // -> for Y = 0.1, sharpness = -1.0 / (sqrt(1-ao) - 1) + float vs = -1.0f / (sqrt(1.0f - ambientOcclusion) - 1.0f); + + // 2. Approximate upper hemisphere with sharpness = 0.8 and amplitude = 1 + float us = 0.8f; + + // 3. Compute warped SG Axis of GGX distribution + // Ref: All-Frequency Rendering of Dynamic, Spatially-Varying Reflectance + // https://www.microsoft.com/en-us/research/wp-content/uploads/2009/12/sg.pdf + float NoV = dot(V, normalWS); + float3 NDFAxis = (2 * NoV * normalWS - V) * (0.5f / max(roughness * roughness * NoV, 0.001f)); + + float umLength1 = length(NDFAxis + vs * bentNormalWS); + float umLength2 = length(NDFAxis + us * normalWS); + float d1 = 1 - exp(-2 * umLength1); + float d2 = 1 - exp(-2 * umLength2); + + float expFactor1 = exp(umLength1 - umLength2 + us - vs); + + return saturate(expFactor1 * (d1 * umLength2) / (d2 * umLength1)); +} + // Ref: Steve McAuley - Energy-Conserving Wrapped Diffuse real ComputeWrappedDiffuseLighting(real NdotL, real w) { diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index ef3fe3286b0..f4b9de12707 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Significantly improved performance of APV probe debug. - Removed DLSS keyword in settings search when NVIDIA package is not installed. (case 1358409) - Fixed light anchor min distance value + properties not working with prefabs (case 1345509). +- Fixed specular occlusion sharpness and over darkening at grazing angles. ### changed - Visual Environment ambient mode is now Dynamic by default. @@ -390,7 +391,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Fixed wrong ordering in FrameSettings (Normalize Reflection Probes) - Fixed ThreadMapDetail to saturate AO & smoothness strength inputs to prevent out-of-bounds values set by users (1357740) - Allow negative wind speed parameter. -- Viewport and scaling of Custom post process when TAAU or DLSS are enabled (case 1352407). ### Changed - Changed Window/Render Pipeline/HD Render Pipeline Wizard to Window/Rendering/HDRP Wizard diff --git a/com.unity.render-pipelines.high-definition/Documentation~/Upgrading-from-2021.1-to-2021.2.md b/com.unity.render-pipelines.high-definition/Documentation~/Upgrading-from-2021.1-to-2021.2.md index e40182b802d..0fa05b8584e 100644 --- a/com.unity.render-pipelines.high-definition/Documentation~/Upgrading-from-2021.1-to-2021.2.md +++ b/com.unity.render-pipelines.high-definition/Documentation~/Upgrading-from-2021.1-to-2021.2.md @@ -39,6 +39,11 @@ HDRP 2021.2 has various tessellation shader code to enable tessellation support * HDRP has improved support of motion vectors for tessellation. Only `previousPositionRWS` is part of the varyings. HDRP also added the `MotionVectorTessellation()` function. For more information, see the `MotionVectorVertexShaderCommon.hlsl` file. * HDRP now evaluates the `tessellationFactor` in the vertex shader and passes it to the hull shader as an interpolator. For more information, see the `VaryingMesh.hlsl` and `VertMesh.hlsl` files. +### Specular Occlusion + +The algorithm for computing specular occlusion from bent normals and ambient occlusion has been changed to improve visual results. +To use the old algorithm, function calls to `GetSpecularOcclusionFromBentAO` should be replaced by calls to `GetSpecularOcclusionFromBentAO_ConeCone` + ## Density Volumes Density Volumes are now known as **Local Volumetric Fog**. diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/TargetData/LightingData.cs b/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/TargetData/LightingData.cs index cd4b56e5a72..0a3878e4caf 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/TargetData/LightingData.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/TargetData/LightingData.cs @@ -74,7 +74,7 @@ public bool specularAA // } [SerializeField] - SpecularOcclusionMode m_SpecularOcclusionMode; + SpecularOcclusionMode m_SpecularOcclusionMode = SpecularOcclusionMode.FromAO; public SpecularOcclusionMode specularOcclusionMode { get => m_SpecularOcclusionMode; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLit.shader b/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLit.shader index e2d674f788f..a28294fda2b 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLit.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLit.shader @@ -244,7 +244,7 @@ Shader "HDRP/LayeredLit" // Following are builtin properties - [Enum(Off, 0, From Ambient Occlusion, 1, From Bent Normals, 2)] _SpecularOcclusionMode("Specular Occlusion Mode", Int) = 1 + [Enum(Off, 0, From Ambient Occlusion, 1, From AO and Bent Normals, 2)] _SpecularOcclusionMode("Specular Occlusion Mode", Int) = 1 [HDR] _EmissiveColor("EmissiveColor", Color) = (0, 0, 0) // Used only to serialize the LDR and HDR emissive color in the material UI, @@ -453,7 +453,7 @@ Shader "HDRP/LayeredLit" #pragma shader_feature_fragment _ENABLESPECULAROCCLUSION // Non-local #pragma shader_feature_fragment _ _SPECULAR_OCCLUSION_NONE _SPECULAR_OCCLUSION_FROM_BENT_NORMAL_MAP // Non-local #pragma shader_feature_raytracing _ENABLESPECULAROCCLUSION // Non-local - #pragma shader_feature_raytracing _ SPECULAR_OCCLUSION_NONE _SPECULAR_OCCLUSION_FROM_BENT_NORMAL_MAP // Non-local + #pragma shader_feature_raytracing _ _SPECULAR_OCCLUSION_NONE _SPECULAR_OCCLUSION_FROM_BENT_NORMAL_MAP // Non-local #ifdef _ENABLESPECULAROCCLUSION #define _SPECULAR_OCCLUSION_FROM_BENT_NORMAL_MAP diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitTessellation.shader b/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitTessellation.shader index ae4b4ceb97b..d79b23c3be1 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitTessellation.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitTessellation.shader @@ -244,7 +244,7 @@ Shader "HDRP/LayeredLitTessellation" // Following are builtin properties - [Enum(Off, 0, From Ambient Occlusion, 1, From Bent Normals, 2)] _SpecularOcclusionMode("Specular Occlusion Mode", Int) = 1 + [Enum(Off, 0, From Ambient Occlusion, 1, From AO and Bent Normals, 2)] _SpecularOcclusionMode("Specular Occlusion Mode", Int) = 1 [HDR] _EmissiveColor("EmissiveColor", Color) = (0, 0, 0) // Used only to serialize the LDR and HDR emissive color in the material UI, diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.shader b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.shader index a44fb3837b6..5501967ffcf 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.shader @@ -77,7 +77,7 @@ Shader "HDRP/Lit" // Following options are for the GUI inspector and different from the input parameters above // These option below will cause different compilation flag. - [Enum(Off, 0, From Ambient Occlusion, 1, From Bent Normals, 2)] _SpecularOcclusionMode("Specular Occlusion Mode", Int) = 1 + [Enum(Off, 0, From Ambient Occlusion, 1, From AO and Bent Normals, 2)] _SpecularOcclusionMode("Specular Occlusion Mode", Int) = 1 [HDR] _EmissiveColor("EmissiveColor", Color) = (0, 0, 0) // Used only to serialize the LDR and HDR emissive color in the material UI, diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitData.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitData.hlsl index 31cef50350c..729fa81e0b2 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitData.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitData.hlsl @@ -17,9 +17,6 @@ #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl" #endif -//#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/SphericalCapPivot/SPTDistribution.hlsl" -//#define SPECULAR_OCCLUSION_USE_SPTD - //#define PROJECTED_SPACE_NDF_FILTERING // Struct that gather UVMapping info of all layers + common calculation @@ -286,11 +283,7 @@ void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs p // If user provide bent normal then we process a better term #if defined(_BENTNORMALMAP) && defined(_SPECULAR_OCCLUSION_FROM_BENT_NORMAL_MAP) // If we have bent normal and ambient occlusion, process a specular occlusion - #ifdef SPECULAR_OCCLUSION_USE_SPTD - surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAOPivot(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness)); - #else surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness)); -#endif // Don't do spec occ from Ambient if there is no mask mask #elif defined(_MASKMAP) && !defined(_SPECULAR_OCCLUSION_NONE) surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness)); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitProperties.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitProperties.hlsl index d20882376c4..9eed7799baf 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitProperties.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitProperties.hlsl @@ -22,6 +22,8 @@ TEXTURE2D(_MaskMap); SAMPLER(sampler_MaskMap); TEXTURE2D(_BentNormalMap); // Reuse sampler from normal map SAMPLER(sampler_BentNormalMap); +TEXTURE2D(_BentNormalMapOS); +SAMPLER(sampler_BentNormalMapOS); TEXTURE2D(_NormalMap); SAMPLER(sampler_NormalMap); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitTessellation.shader b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitTessellation.shader index 0ceec482239..ce88d3f398f 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitTessellation.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitTessellation.shader @@ -77,7 +77,7 @@ Shader "HDRP/LitTessellation" // Following options are for the GUI inspector and different from the input parameters above // These option below will cause different compilation flag. - [Enum(Off, 0, From Ambient Occlusion, 1, From Bent Normals, 2)] _SpecularOcclusionMode("Specular Occlusion Mode", Int) = 1 + [Enum(Off, 0, From Ambient Occlusion, 1, From AO and Bent Normals, 2)] _SpecularOcclusionMode("Specular Occlusion Mode", Int) = 1 [HDR] _EmissiveColor("EmissiveColor", Color) = (0, 0, 0) // Used only to serialize the LDR and HDR emissive color in the material UI,