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