Files
UnrealEngineUWP/Engine/Shaders/LightAccumulator.usf
Matthew Griffin bb70b349ce Merging CL 2804086 from //UE4/Release-4.11 to Dev-Main (//UE4/Dev-Main) to isolate copyright update
#lockdown Nick.Penwarden

[CL 2819020 by Matthew Griffin in Main branch]
2016-01-07 08:17:16 -05:00

115 lines
4.3 KiB
Plaintext

// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
/*=============================================================================
LightAccumulator.usf: FLightAccumulator "class" and it's methods, useful for screen space subsurface scattering
=============================================================================*/
#ifndef __LIGHTACCUMULATOR_COMMON__
#define __LIGHTACCUMULATOR_COMMON__
// set by c++, not set for LPV
// 0 / 1
#ifndef VISUALIZE_LIGHT_CULLING
#define VISUALIZE_LIGHT_CULLING 0
#endif
// for ScreenSpaceSubsurfaceScattering
// 0 : fastest (speculars leak in SSSSS)
// 1 : luminance specular works well (needs 64bit SceneColor, stores luminance of specular in alpha, can be optimized further in LightAccumulator_Add() )
// 2 : colored specular works well (best, requires another RT for light accumulation)
#define SUBSURFACE_CHANNEL_MODE 0
struct FLightAccumulator
{
// view independent lighting + view dependent lighting
float3 TotalSum;
// only actually used SUBSURFACE_CHANNEL_MODE == 1
// assumed to be compiled out otherwise (not compiled out with #if so we can use if() instead of #if for better readability and compiler error checking)
// input for ScreenSpaceSubsurfaceScattering
// view independent lighting luminance
float ViewIndependentLightingLuminanceSum;
// only actually used SUBSURFACE_CHANNEL_MODE == 2
// assumed to be compiled out otherwise (not compiled out with #if so we can use if() instead of #if for better readability and compiler error checking)
// input for ScreenSpaceSubsurfaceScattering
// view independent lighting color
float3 ViewIndependentLightingSum;
// only used for development (not compiled out with #if so we can use if() instead of #if for better readability and compiler error checking)
// assumed to be compiled out otherwise
float EstimatedCost;
};
//
// accumulate light, can be called multiple times
void LightAccumulator_Add(inout FLightAccumulator In, float3 NonSpecularContribution, float3 SpecularContribution, float3 CommonMultiplier)
{
// 3 add, 3 mad
In.TotalSum += (NonSpecularContribution + SpecularContribution) * CommonMultiplier;
if (SUBSURFACE_CHANNEL_MODE == 1)
{
// 3 mad
In.ViewIndependentLightingLuminanceSum += Luminance(NonSpecularContribution * CommonMultiplier);
}
else if (SUBSURFACE_CHANNEL_MODE == 2)
{
// 3 mad
In.ViewIndependentLightingSum += NonSpecularContribution * CommonMultiplier;
}
}
//
// compute final value to store in the MRT0
// @retrun RGB:SceneColor Specular and Diffuse, A:Non Specular SceneColor Luminance
float4 LightAccumulator_GetResult(FLightAccumulator In)
{
float4 Ret;
if (VISUALIZE_LIGHT_CULLING == 1)
{
// a soft gradient from dark red to bright white, can be changed to be different
Ret = 0.1f * float4(1.0f, 0.25f, 0.075f, 0) * In.EstimatedCost;
}
else
{
Ret = float4(In.TotalSum, 0);
if (SUBSURFACE_CHANNEL_MODE == 1)
{
// RGB accumulated RGB HDR color, A: specular luminance for screenspace subsurface scattering
Ret.a = In.ViewIndependentLightingLuminanceSum;
}
else if (SUBSURFACE_CHANNEL_MODE == 2)
{
// RGB accumulated RGB HDR color, A: view independent (diffuse) luminance for screenspace subsurface scattering
// 3 add, 1 mul, 2 mad, can be optimized to use 2 less temporary during accumulation and remove the 3 add
Ret.a = Luminance(In.ViewIndependentLightingSum);
// todo, need second MRT for SUBSURFACE_CHANNEL_MODE==2
}
}
return Ret;
}
// @param SceneColor4 RGB:SceneColor Specular and Diffuse, A:Non Specular SceneColor Luminance
float3 LightAccumulator_ReconstructDiffuseLighting(float4 SceneColor4)
{
// add small bias to avoid div by 0 (faster than max(), assuming we don't have negatives and NaN in there)
float TotalSceneColorLum = Luminance(SceneColor4.rgb) + 0.000001f;
return SceneColor4.rgb * (SceneColor4.a / TotalSceneColorLum);
}
// @param SceneColor4 RGB:SceneColor Specular and Diffuse, A:Non Specular SceneColor Luminance
float3 LightAccumulator_ReconstructNonDiffuseLighting(float4 SceneColor4)
{
// add small bias to avoid div by 0 (faster than max(), assuming we don't have negatives and NaN in there)
float TotalSceneColorLum = Luminance(SceneColor4.rgb) + 0.000001f;
return SceneColor4.rgb * saturate(1 - SceneColor4.a / TotalSceneColorLum);
}
#endif // __LIGHTACCUMULATOR_COMMON__