140 lines
5.1 KiB
HLSL
140 lines
5.1 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
SkyLightingDiffuseShared.usf
|
|
=============================================================================*/
|
|
|
|
#pragma once
|
|
|
|
#include "SkyLightingShared.ush"
|
|
#include "ClearCoatCommon.ush"
|
|
#include "ShadingEnergyConservation.ush"
|
|
#include "HairBsdf.ush"
|
|
#include "HairStrands/HairStrandsEnvironmentLightingCommon.ush"
|
|
|
|
#ifndef APPLY_SKY_SHADOWING
|
|
#define APPLY_SKY_SHADOWING 0
|
|
#endif
|
|
|
|
float3 ContrastAndNormalizeMulAdd;
|
|
float OcclusionExponent;
|
|
float OcclusionCombineMode;
|
|
// The following paramaters are declared in SkyLightingShared.usf
|
|
// float4 OcclusionTintAndMinOcclusion;
|
|
|
|
struct FSkyLightVisibilityData
|
|
{
|
|
float SkyDiffuseLookUpMul;
|
|
float3 SkyDiffuseLookUpAdd;
|
|
float3 SkyDiffuseLookUpNormal;
|
|
};
|
|
|
|
FSkyLightVisibilityData GetSkyLightVisibilityData(float3 SkyLightingNormal, const float3 WorldNormal, const float GBufferAO, float ScreenAO, const float3 BentNormal)
|
|
{
|
|
float SkyVisibility = 1;
|
|
float DotProductFactor = 1;
|
|
|
|
#if APPLY_SKY_SHADOWING
|
|
#define USE_DIRECTIONAL_OCCLUSION_ON_SKY_DIFFUSE 1
|
|
#if USE_DIRECTIONAL_OCCLUSION_ON_SKY_DIFFUSE
|
|
{
|
|
SkyVisibility = length(BentNormal);
|
|
float3 NormalizedBentNormal = BentNormal / (max(SkyVisibility, .00001f));
|
|
|
|
// Use more bent normal in corners
|
|
float BentNormalWeightFactor = SkyVisibility;
|
|
|
|
SkyLightingNormal = lerp(NormalizedBentNormal, WorldNormal, BentNormalWeightFactor);
|
|
DotProductFactor = lerp(dot(NormalizedBentNormal, WorldNormal), 1, BentNormalWeightFactor);
|
|
}
|
|
#else
|
|
{
|
|
SkyVisibility = length(BentNormal);
|
|
}
|
|
#endif
|
|
|
|
float ContrastCurve = 1 / (1 + exp(-ContrastAndNormalizeMulAdd.x * (SkyVisibility * 10 - 5)));
|
|
SkyVisibility = saturate(ContrastCurve * ContrastAndNormalizeMulAdd.y + ContrastAndNormalizeMulAdd.z);
|
|
|
|
// Apply DFAO controls
|
|
SkyVisibility = pow(SkyVisibility, OcclusionExponent);
|
|
SkyVisibility = lerp(SkyVisibility, 1, OcclusionTintAndMinOcclusion.w);
|
|
#endif
|
|
|
|
// Combine with other AO sources
|
|
if (OcclusionCombineMode == 0)
|
|
{
|
|
// Combine with min which nicely avoids over-occlusion in cases where strong DFAO is present along with strong SSAO (distant trees)
|
|
SkyVisibility = min(SkyVisibility, min(GBufferAO, ScreenAO));
|
|
}
|
|
else
|
|
{
|
|
// Combine with mul, which continues to add SSAO depth even indoors. SSAO will need to be tweaked to be less strong.
|
|
SkyVisibility = SkyVisibility * min(GBufferAO, ScreenAO);
|
|
}
|
|
|
|
// Apply AO to the sky diffuse and account for darkening due to the geometry term
|
|
// apply the Diffuse color to the lighting (including OcclusionTintAndMinOcclusion as it's considered another light, that fixes SubsurfaceProfile being too dark)
|
|
FSkyLightVisibilityData SkyVisData;
|
|
SkyVisData.SkyDiffuseLookUpMul = SkyVisibility * DotProductFactor;
|
|
SkyVisData.SkyDiffuseLookUpAdd = (1 - SkyVisibility) * OcclusionTintAndMinOcclusion.xyz;
|
|
SkyVisData.SkyDiffuseLookUpNormal = SkyLightingNormal;
|
|
return SkyVisData;
|
|
}
|
|
|
|
float3 SkyLightDiffuse(FGBufferData GBuffer, float AmbientOcclusion, float2 BufferUV, float2 ScreenPosition, float3 BentNormal, float3 DiffuseColor)
|
|
{
|
|
float2 UV = BufferUV;
|
|
float3 Lighting = 0;
|
|
|
|
float3 SkyLightingNormal = GetClearCoatBottomNormal(GBuffer, GBuffer.WorldNormal);
|
|
FSkyLightVisibilityData SkyVisData = GetSkyLightVisibilityData(SkyLightingNormal, GBuffer.WorldNormal, GBuffer.GBufferAO, AmbientOcclusion, BentNormal);
|
|
|
|
const float3 N = GBuffer.WorldNormal;
|
|
const float3 V = -normalize(mul(float3(ScreenPosition, 1), DFToFloat3x3(PrimaryView.ScreenToWorld)).xyz);
|
|
const float NoV = saturate(dot(V, N));
|
|
const FBxDFEnergyTerms EnergyTerms = ComputeGGXSpecEnergyTerms(GBuffer.Roughness, NoV, GBuffer.SpecularColor);
|
|
float3 DiffuseWeight = ComputeEnergyPreservation(EnergyTerms);
|
|
|
|
BRANCH
|
|
if (GBuffer.ShadingModelID == SHADINGMODELID_TWOSIDED_FOLIAGE)
|
|
{
|
|
float3 SubsurfaceLookup = GetSkySHDiffuse(-GBuffer.WorldNormal) * View.SkyLightColor.rgb;
|
|
float3 SubsurfaceColor = ExtractSubsurfaceColor(GBuffer);
|
|
Lighting += SkyVisData.SkyDiffuseLookUpMul * SubsurfaceLookup * SubsurfaceColor;
|
|
}
|
|
|
|
if (GBuffer.ShadingModelID == SHADINGMODELID_SUBSURFACE || GBuffer.ShadingModelID == SHADINGMODELID_PREINTEGRATED_SKIN)
|
|
{
|
|
float3 SubsurfaceColor = ExtractSubsurfaceColor(GBuffer);
|
|
// Add subsurface energy to diffuse
|
|
DiffuseColor += SubsurfaceColor;
|
|
}
|
|
|
|
BRANCH
|
|
if (GBuffer.ShadingModelID == SHADINGMODELID_HAIR)
|
|
{
|
|
float3 L = 0;
|
|
DiffuseColor = EvaluateEnvHair(GBuffer, V, N, L /*out*/);
|
|
DiffuseWeight = 1.0f;
|
|
SkyVisData.SkyDiffuseLookUpNormal = L;
|
|
}
|
|
|
|
if (GBuffer.ShadingModelID == SHADINGMODELID_CLOTH)
|
|
{
|
|
float3 ClothFuzz = ExtractSubsurfaceColor(GBuffer);
|
|
DiffuseColor += ClothFuzz * GBuffer.CustomData.a;
|
|
}
|
|
|
|
// Compute the preconvolved incoming lighting with the bent normal direction
|
|
float3 DiffuseLookup = GetSkySHDiffuse(SkyVisData.SkyDiffuseLookUpNormal) * View.SkyLightColor.rgb;
|
|
|
|
// And accumulate the lighting
|
|
Lighting += (SkyVisData.SkyDiffuseLookUpMul * DiffuseLookup + SkyVisData.SkyDiffuseLookUpAdd) * DiffuseColor * DiffuseWeight;
|
|
Lighting *= View.PreExposure;
|
|
|
|
//Lighting = (Texture2DSampleLevel(BentNormalAOTexture, BentNormalAOSampler, UV, 0).xyz);
|
|
|
|
return Lighting;
|
|
}
|