You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
170 lines
4.1 KiB
Plaintext
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
|
|
}
|