105 lines
3.4 KiB
Plaintext
105 lines
3.4 KiB
Plaintext
/*
|
|
* Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
*
|
|
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
|
* property and proprietary rights in and to this material, related
|
|
* documentation and any modifications thereto. Any use, reproduction,
|
|
* disclosure or distribution of this material and related documentation
|
|
* without an express license agreement from NVIDIA CORPORATION or
|
|
* its affiliates is strictly prohibited.
|
|
*/
|
|
|
|
#include "/Engine/Private/Common.ush"
|
|
#include "/Engine/Private/DeferredShadingCommon.ush"
|
|
#include "/Engine/Private/BRDF.ush"
|
|
#include "/Engine/Private/FastMath.ush"
|
|
#include "/Engine/Private/ScreenPass.ush"
|
|
|
|
|
|
#ifndef DIFFUSE_SPECULAR_ALBEDO
|
|
#define DIFFUSE_SPECULAR_ALBEDO 0
|
|
#endif
|
|
|
|
SCREEN_PASS_TEXTURE_VIEWPORT(InputViewPort)
|
|
SCREEN_PASS_TEXTURE_VIEWPORT(OutputViewPort)
|
|
|
|
#include "/Engine/Private/PositionReconstructionCommon.ush"
|
|
|
|
float3 EnvBRDFApproxRTG(float3 SpecularColor, float alpha, float NoV)
|
|
{
|
|
NoV = abs(NoV);
|
|
// [Ray Tracing Gems, Chapter 32]
|
|
float4 X;
|
|
X.x = 1.f;
|
|
X.y = NoV;
|
|
X.z = NoV * NoV;
|
|
X.w = NoV * X.z;
|
|
|
|
float4 Y;
|
|
Y.x = 1.f;
|
|
Y.y = alpha;
|
|
Y.z = alpha * alpha;
|
|
Y.w = alpha * Y.z;
|
|
|
|
float2x2 M1 = float2x2(0.99044f, -1.28514f, 1.29678f, -0.755907f);
|
|
float3x3 M2 = float3x3(1.f, 2.92338f, 59.4188f, 20.3225f, -27.0302f, 222.592f, 121.563f, 626.13f, 316.627f);
|
|
|
|
float2x2 M3 = float2x2(0.0365463f, 3.32707, 9.0632f, -9.04756);
|
|
float3x3 M4 = float3x3(1.f, 3.59685f, -1.36772f, 9.04401f, -16.3174f, 9.22949f, 5.56589f, 19.7886f, -20.2123f);
|
|
|
|
float bias = dot(mul(M1, X.xy), Y.xy) * rcp(dot(mul(M2, X.xyw), Y.xyw));
|
|
float scale = dot(mul(M3, X.xy), Y.xy) * rcp(dot(mul(M4, X.xzw), Y.xyw));
|
|
|
|
// This is a hack for specular reflectance of 0
|
|
bias *= saturate(SpecularColor.g * 50);
|
|
|
|
return mad(SpecularColor, max(0, scale), max(0, bias));
|
|
}
|
|
|
|
void GBufferResolvePixelShader(
|
|
float2 InUV : TEXCOORD0,
|
|
float4 SvPosition : SV_Position
|
|
#if DIFFUSE_SPECULAR_ALBEDO
|
|
, out float4 OutDiffuseAlbedo : SV_Target0
|
|
, out float4 OutSpecularAlbedo : SV_Target1
|
|
, out float4 OutNormal : SV_Target2
|
|
, out float OutRoughness : SV_Target3
|
|
, out float OutDepth : SV_Target4
|
|
#endif
|
|
)
|
|
{
|
|
FGBufferData GBuffer = GetGBufferDataUint(uint2(SvPosition.xy + InputViewPort_ViewportMin), true);
|
|
#if DIFFUSE_SPECULAR_ALBEDO
|
|
|
|
float3 DiffuseColor = GBuffer.DiffuseColor;
|
|
float3 SpecularColor = GBuffer.SpecularColor;
|
|
|
|
if (UseSubsurfaceProfile(GBuffer.ShadingModelID))
|
|
{
|
|
// this is a bit odd, but the diffuse signal is multiplied by this without any conversion tied to metalness
|
|
// See apply code in PostprocessSubsurface
|
|
DiffuseColor = GBuffer.StoredBaseColor;
|
|
|
|
// the correct value here is a bit debatable, as the skin computes with one value, then applies with another
|
|
SpecularColor = ComputeF0(GBuffer.Specular, GBuffer.StoredBaseColor, GBuffer.Metallic);
|
|
//SpecularColor = 1.0;
|
|
}
|
|
|
|
|
|
float3 WorldPos = ReconstructWorldPositionFromDepth(ViewportUVToBufferUV(InUV), GBuffer.Depth);
|
|
float3 RayDirection = normalize(WorldPos - LWCHackToFloat(PrimaryView.WorldCameraOrigin));
|
|
|
|
float NoV = saturate(dot(-RayDirection, GBuffer.WorldNormal));
|
|
float x = NoV * NoV;
|
|
NoV = x / (x + (1 - NoV) * (1 - NoV));
|
|
float3 F = EnvBRDFApproxRTG(SpecularColor, Square(GBuffer.Roughness), NoV * 0.75f);
|
|
|
|
OutDiffuseAlbedo = float4(DiffuseColor, 1.0f);
|
|
OutSpecularAlbedo = float4(F, 1.0f);
|
|
OutNormal = float4(GBuffer.WorldNormal, GBuffer.Roughness);
|
|
OutRoughness = GBuffer.Roughness;
|
|
OutDepth = GBuffer.Depth;
|
|
#endif
|
|
}
|
|
|