Skip to content
Merged
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 36 additions & 2 deletions com.unity.render-pipelines.core/ShaderLibrary/CommonLighting.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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
Expand All @@ -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)
{
Expand Down
2 changes: 1 addition & 1 deletion com.unity.render-pipelines.high-definition/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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**.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public bool specularAA
// }

[SerializeField]
SpecularOcclusionMode m_SpecularOcclusionMode;
SpecularOcclusionMode m_SpecularOcclusionMode = SpecularOcclusionMode.FromAO;
public SpecularOcclusionMode specularOcclusionMode
{
get => m_SpecularOcclusionMode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down