Files
UnrealEngineUWP/Engine/Shaders/PostProcessSubsurface.usf
Martin Mittring c5d87597d4 * optimized ScreenSpaceSubsurfaceScattering shader cost
[CL 2132652 by Martin Mittring in Main branch]
2014-07-03 18:15:01 -04:00

170 lines
4.1 KiB
Plaintext

// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
/*=============================================================================
PostProcessSubsurface.usf: Screenspace subsurface scattering shaders.
=============================================================================*/
#include "Common.usf"
#include "PostProcessCommon.usf"
#include "DeferredShadingCommon.usf"
/** RGBA8 linear texture containing random normals */
Texture2D SSProfilesTexture;
SamplerState SSProfilesTextureSampler;
// ------------------------------------------
// setup for "SeparableSSS.usf"
#define SSSS_HLSL_4 1
//#define SSSS_STREGTH_SOURCE 1 // todo: masking fom LightingModel or SSSColor
#define SSSS_STREGTH_SOURCE (GetScreenSpaceData(texcoord).GBuffer.ShadingModelID >= SHADINGMODELID_SUBSURFACE)
// 0:speculars leak into SSS / 1:requires alpha channel for scenecolor
// #define SSSS_SPECULAR_CORRECTION 1
// 0: faster
// 1: no color bleeding in z direction
#define SSSS_FOLLOW_SURFACE 1
// from https://github.com/iryoku/separable-sss/tree/master/Demo
// Jorge Jimenez http://www.iryoku.com/
#include "SeparableSSS.usf"
// ------------------------------------------
#if SSSS_SPECULAR_CORRECTION == 1
// requires alpha channel for scenecolor
#elif SSSS_SPECULAR_CORRECTION == 0
// speculars leak into SSS
#else
error
#endif
#if METHOD == 0
// horizontal
#elif METHOD == 1
// vertical
#elif METHOD == 2
// vertical and reconstruct specular
#else
error
#endif
// 0 / 1
#define VISUALIZE_KERNEL 0
// x:Radius
float4 SSSParams;
void SetupPS(in float4 UVAndScreenPos : TEXCOORD0, out float4 OutColor : SV_Target0)
{
float2 UV = UVAndScreenPos.xy;
OutColor = 0;
FScreenSpaceData ScreenSpaceData = GetScreenSpaceData(UV);
FLATTEN if(ScreenSpaceData.GBuffer.ShadingModelID >= SHADINGMODELID_SUBSURFACE)
{
float4 SceneColor4 = Texture2DSample(PostprocessInput0, PostprocessInput0Sampler, UV);
#if SSSS_SPECULAR_CORRECTION == 1
// we take out the specular highlights
float3 Lighting = LightAccumulator_ReconstructDiffuseLighting(SceneColor4);
#else
float3 Lighting = SceneColor4.rgb;
#endif
OutColor.rgb = Lighting;
}
}
// Gaussian in window -2/c0 .. 2/c0, 2d integral: 1
// @param XSquared x * x
float ComputeWindowedGaussian(float x, float c0)
{
x *= c0;
float XSquared = x * x;
return max(exp2(-XSquared) - 0.065f, 0) / 3.4324f * (c0 * c0);
}
// Subsurface function
// @param x > 0
float3 ColorOverDistance(float3 SubsurfaceColor, float x)
{
// larger means tighter gaussian
x *= 2.0f; // -1..1 to -2..2
float3 Color = SubsurfaceColor;
// to avoid stuff gets brighter
// Color /= dot(Color, 1);
float3 Hack = 1;//float3(0.8f, 0.5f, 0.35f);
return Hack * float3(
ComputeWindowedGaussian(x, Color.r),
ComputeWindowedGaussian(x, Color.g),
ComputeWindowedGaussian(x, Color.b) );
}
float3 SampleDiffuseLighting(float2 LocalUV)
{
#if VISUALIZE_KERNEL
float Aspect = ViewportSize.x / ViewportSize.y;
float2 Dxy = (LocalUV - float2(0.75f, 0.25f)) * float2(Aspect, 1);
if(dot(Dxy, Dxy) < 0.000006f) return 2;
if(dot(Dxy, Dxy) < 0.05f) return 0;
#endif
return Texture2DSample(PostprocessInput0, PostprocessInput0Sampler, LocalUV).rgb;
}
// input0 is created by the SetupPS shader
void MainPS(float4 UVAndScreenPos : TEXCOORD0, out float4 OutColor : SV_Target0)
{
float2 UV = UVAndScreenPos.xy;
FScreenSpaceData ScreenSpaceData = GetScreenSpaceData(UV);
// call into "SeparableSSS.usf"
// in world units
float sssWidth = SSSParams.x * 0.01f;
#if METHOD == 0
// first pass
float2 Direction = float2(1, 0);
#else
// second pass
float2 Direction = float2(0, 1);
#endif
OutColor = SSSSBlurPS(UV, sssWidth, Direction, false);
OutColor.a = 1.0f;
// Lighting
#if METHOD > 0
// on second pass we recombine with the scene color
float4 SceneColor4 = Texture2DSample(PostprocessInput1, PostprocessInput1Sampler, UV);
float4 SSSColor = OutColor;
SSSColor.a = (ScreenSpaceData.GBuffer.ShadingModelID >= SHADINGMODELID_SUBSURFACE);
#if METHOD > 1
// we took the specular highlights out, now we add them back in
SSSColor.rgb += LightAccumulator_ReconstructNonDiffuseLighting(SceneColor4);
#endif
OutColor = float4(lerp(SceneColor4.rgb, SSSColor.rgb, SSSColor.a), 1);
#endif
}