You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
optimized shaders to use SvPosition where possible, following change could remove some unused interpolator [CL 2697164 by Martin Mittring in Main branch]
187 lines
5.7 KiB
Plaintext
187 lines
5.7 KiB
Plaintext
//-----------------------------------------------------------------------------
|
|
// File: PostProcessLpvIndirect.usf
|
|
//
|
|
// Summary: Light propagation volume postprocessing
|
|
//
|
|
// Created: 11/03/2013
|
|
//
|
|
// Author: mailto:benwood@microsoft.com
|
|
//
|
|
// Copyright (C) Microsoft. All rights reserved.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#define ENABLE_LPV_SPECULAR 1
|
|
|
|
// Directional occlusion
|
|
#define DEBUG_USE_RAW_AO 0
|
|
#define LPV_OCCLUSION_EDGE_FADE 0
|
|
#define ENABLE_DIRECTIONAL_OCCLUSION 1
|
|
|
|
#define LuminanceVec float3(0.299f,0.587f,0.114f)
|
|
|
|
#include "Common.usf"
|
|
#include "PostProcessCommon.usf"
|
|
#include "DeferredLightingCommon.usf"
|
|
#include "Random.usf"
|
|
#include "LPVFinalPass.usf"
|
|
|
|
float3 LpvSpecularHighQuality( float3 WorldPosition, float3 R, float Roughness )
|
|
{
|
|
float Smooth = 1.0f-Roughness;
|
|
float offset = Smooth * Smooth * Smooth * Smooth * 8.0f;
|
|
|
|
// Decreased roughness results in longer ray offsets and higher frequency reflections
|
|
float3 specularOut = LPVSpecular( WorldPosition, R, offset );
|
|
// To prevent artifacts from very long ray lookups, we do multiple lookups and combine
|
|
// with a weighting favouring brighter/further samples
|
|
[branch]
|
|
if ( offset > 5.0f ) // TODO: Use AO to block rays
|
|
{
|
|
float3 spec1 = LPVSpecular( WorldPosition, R, offset * 0.5 );
|
|
float l1 = dot( spec1, LuminanceVec ) * 0.25;
|
|
float l2 = dot( specularOut, LuminanceVec ) * 0.75;
|
|
float weight = l2/((l1+l2)+0.0001f);
|
|
specularOut = lerp( spec1, specularOut, weight );
|
|
}
|
|
[branch]
|
|
if ( offset > 1.0f )
|
|
{
|
|
float3 spec1 = ( LPVDiffuse( WorldPosition, R ) / LpvRead.DiffuseIntensity ) * LpvRead.SpecularIntensity; // FIX A BUG. This is horrible!
|
|
float l1 = dot( spec1, LuminanceVec ) * 0.25;
|
|
float l2 = dot( specularOut, LuminanceVec ) * 0.75;
|
|
float weight = l2/((l1+l2)+0.0001f);
|
|
specularOut = lerp( spec1, specularOut, weight );
|
|
}
|
|
return specularOut;
|
|
}
|
|
|
|
void MainPS(in noperspective float4 UVAndScreenPos : TEXCOORD0, float4 SVPos: SV_POSITION, out float4 OutColor : SV_Target0
|
|
#if APPLY_SEPARATE_SPECULAR_RT
|
|
,out float4 OutSpecular : SV_Target1
|
|
#endif
|
|
)
|
|
{
|
|
float2 UV = UVAndScreenPos.xy;
|
|
|
|
FScreenSpaceData ScreenSpaceData = GetScreenSpaceData(UV);
|
|
FGBufferData GBuffer = ScreenSpaceData.GBuffer;
|
|
|
|
OutColor = 0;
|
|
#if APPLY_SEPARATE_SPECULAR_RT
|
|
OutSpecular = 0;
|
|
#endif
|
|
|
|
BRANCH if (GBuffer.ShadingModelID == SHADINGMODELID_UNLIT )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// screen position in [-1, 1] screen space
|
|
float2 ScreenSpacePos = UVAndScreenPos.zw;
|
|
|
|
float3 ScreenVectorU = mul(float4(ScreenSpacePos, 1, 0), View.ScreenToWorld).xyz;
|
|
float3 ScreenVector = normalize(ScreenVectorU);
|
|
|
|
float SceneDepth = CalcSceneDepth(UV);
|
|
float3 WorldPosition = ScreenVectorU * SceneDepth + View.WorldCameraOrigin;
|
|
|
|
float3 grid = WorldToGrid( WorldPosition );
|
|
|
|
#if 0 // Potential optimisation - might give worse results if we're outside the grid though
|
|
float maxgrid = max(grid.x, max(grid.y, grid.z) );
|
|
float mingrid = min(grid.x, min(grid.y, grid.z) );
|
|
|
|
if ( maxgrid <32 && mingrid > 0)
|
|
#endif
|
|
{
|
|
float3 R = reflect( ScreenVector, GBuffer.WorldNormal );
|
|
|
|
float3 DiffuseColor = GBuffer.DiffuseColor;
|
|
float3 DiffuseNormal = GBuffer.WorldNormal;
|
|
float3 SubsurfaceColor = ExtractSubsurfaceColor(ScreenSpaceData.GBuffer);
|
|
float3 Diffuse = LPVDiffuse( WorldPosition, DiffuseNormal ) * DiffuseColor;
|
|
|
|
#if TRANSMISSIVE_LIGHTING_MODEL_LPV
|
|
BRANCH if( GBuffer.ShadingModelID != SHADINGMODELID_TRANSMISSIVE )
|
|
{
|
|
Diffuse += 0.00001f;
|
|
}
|
|
else
|
|
{
|
|
float3 SubsurfaceLighting = 0;
|
|
|
|
float3 BackScatter = ( LPVDiffuse( WorldPosition, -GBuffer.WorldNormal ) ) * GBuffer.Opacity;
|
|
SubsurfaceLighting += BackScatter * SubsurfaceColor;
|
|
|
|
Diffuse += SubsurfaceLighting * 1.0f ;
|
|
}
|
|
#endif
|
|
|
|
float3 LpvSpecular = 0;
|
|
|
|
[branch]
|
|
if ( dot( GBuffer.SpecularColor.xyz, GBuffer.SpecularColor.xyz ) >= 0.00001f )
|
|
{
|
|
LpvSpecular = LpvSpecularHighQuality( WorldPosition, R, GBuffer.Roughness );
|
|
}
|
|
|
|
// apply darkening from ambient occlusion (does not use PostprocessInput1 to set white texture if SSAO is off)
|
|
float AmbientOcclusion = GBuffer.GBufferAO * ScreenSpaceData.AmbientOcclusion;
|
|
OutColor = float4( Diffuse.xyz, 1 ) * AmbientOcclusion;
|
|
|
|
#if !ENABLE_LPV_SPECULAR
|
|
LpvSpecular = 0;
|
|
#endif
|
|
|
|
#if APPLY_SEPARATE_SPECULAR_RT
|
|
|
|
// Ambient occlusion already applied with Reflection Environment
|
|
// Note: we don't need to apply the BRDF, since it gets applied during reflection apply
|
|
// Alpha = 1.0f;
|
|
OutSpecular = float4( LpvSpecular, 1 );
|
|
|
|
#else // APPLY_SEPARATE_SPECULAR_RT
|
|
|
|
// Combine Specular (same behaviour as PostProcessAmbient)
|
|
OutColor.rgb += LpvSpecular;
|
|
|
|
#endif // APPLY_SEPARATE_SPECULAR_RT
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void DirectionalOcclusionPS(in noperspective float4 UVAndScreenPos : TEXCOORD0, float4 SVPos: SV_POSITION, out float4 OutColor : SV_Target0 )
|
|
{
|
|
OutColor = float4(1,1,1,1);
|
|
#if ENABLE_DIRECTIONAL_OCCLUSION
|
|
float2 UV = UVAndScreenPos.xy;
|
|
|
|
FScreenSpaceData ScreenSpaceData = GetScreenSpaceData(UV);
|
|
FGBufferData GBuffer = ScreenSpaceData.GBuffer;
|
|
|
|
BRANCH if (GBuffer.ShadingModelID != SHADINGMODELID_UNLIT )
|
|
{
|
|
float2 ScreenSpacePos = UVAndScreenPos.zw;
|
|
|
|
float3 ScreenVectorU = mul(float4(ScreenSpacePos, 1, 0), View.ScreenToWorld).xyz;
|
|
float3 ScreenVector = normalize(ScreenVectorU);
|
|
|
|
float SceneDepth = CalcSceneDepth(UV);
|
|
float3 WorldPosition = ScreenVectorU * SceneDepth + View.WorldCameraOrigin;
|
|
|
|
float3 grid = WorldToGrid( WorldPosition );
|
|
|
|
float3 R = reflect( ScreenVector, GBuffer.WorldNormal );
|
|
|
|
float3 DiffuseNormal = GBuffer.WorldNormal;
|
|
|
|
float3 SubsurfaceColor = ExtractSubsurfaceColor( ScreenSpaceData.GBuffer );
|
|
|
|
OutColor = LPVGetDirectionalOcclusion_DiffuseSpec( WorldPosition, R, GBuffer.Roughness, DiffuseNormal ).xyxy;
|
|
}
|
|
|
|
#endif // ENABLE_DIRECTIONAL_OCCLUSION
|
|
}
|