You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
240 lines
7.4 KiB
Plaintext
240 lines
7.4 KiB
Plaintext
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
PostProcessVisualizeHDR.usf: PostProcessing shader to visualize HDR histogram
|
|
=============================================================================*/
|
|
|
|
#include "Common.usf"
|
|
#include "PostProcessCommon.usf"
|
|
#include "PostProcessHistogramCommon.usf"
|
|
#include "DeferredShadingCommon.usf"
|
|
#include "TonemapCommon.usf"
|
|
|
|
Texture2D MiniFontTexture;
|
|
|
|
// only needed for nice visualization
|
|
float ComputeHistogramMax(Texture2D HistogramTexture)
|
|
{
|
|
float Max = 0;
|
|
|
|
for(uint i = 0; i < HISTOGRAM_SIZE; ++i)
|
|
{
|
|
Max = max(Max, GetHistogramBucket(HistogramTexture, i));
|
|
}
|
|
|
|
return Max;
|
|
}
|
|
|
|
// for printf debugging in the shader
|
|
// @param LeftTop - is advanced, in pixels
|
|
void PrintCharacter(int2 PixelPos, inout float3 OutColor, float3 FontColor, inout int2 LeftTop, int CharacterID)
|
|
{
|
|
uint2 Rel = (uint2)(PixelPos - LeftTop);
|
|
|
|
FLATTEN if(Rel.x < 8 && Rel.y < 8)
|
|
{
|
|
OutColor = lerp(OutColor, FontColor, MiniFontTexture.Load(int3(CharacterID * 8 + Rel.x, Rel.y, 0)).r);
|
|
}
|
|
|
|
LeftTop.x += 8;
|
|
}
|
|
|
|
// only for positive numbers
|
|
// @param DigitValue - e.g. 1 for frist digit before period, 10 for second, 0.1 for first digit behind period
|
|
uint ExtractDigitFromFloat(float Number, float DigitValue)
|
|
{
|
|
uint Temp = (uint)(Number / DigitValue);
|
|
|
|
return Temp % 10;
|
|
}
|
|
|
|
|
|
// for printf debugging in the shader, has to be positive
|
|
// outputs a float number in the form: xxx.yyy
|
|
// @param LeftTop - in pixels
|
|
void PrintFloat(int2 PixelPos, inout float3 OutColor, float3 FontColor, int2 LeftTop, float Number)
|
|
{
|
|
int2 Cursor = LeftTop;
|
|
|
|
float BorderDistance = ComputeDistanceToRect(PixelPos, LeftTop, int2(7, 1) * 8 - 1);
|
|
|
|
// black border around number
|
|
// OutColor = lerp(0, OutColor, saturate(BorderDistance - 2));
|
|
|
|
// before period
|
|
PrintCharacter(PixelPos, OutColor, FontColor, Cursor, ExtractDigitFromFloat(Number, 100));
|
|
PrintCharacter(PixelPos, OutColor, FontColor, Cursor, ExtractDigitFromFloat(Number, 10));
|
|
PrintCharacter(PixelPos, OutColor, FontColor, Cursor, ExtractDigitFromFloat(Number, 1));
|
|
// period
|
|
PrintCharacter(PixelPos, OutColor, FontColor, Cursor, 512 / 8 - 3);
|
|
// after period
|
|
PrintCharacter(PixelPos, OutColor, FontColor, Cursor, ExtractDigitFromFloat(Number, 0.1));
|
|
PrintCharacter(PixelPos, OutColor, FontColor, Cursor, ExtractDigitFromFloat(Number, 0.01));
|
|
PrintCharacter(PixelPos, OutColor, FontColor, Cursor, ExtractDigitFromFloat(Number, 0.001));
|
|
}
|
|
|
|
uint ComputeAdvice(float3 HDRColor)
|
|
{
|
|
float Lum = max(HDRColor.r, max(HDRColor.g, HDRColor.b));
|
|
|
|
if(Lum < EyeAdaptationParams[0].z)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
// for some reasons HLSL compiler seems to supress the return 1 when we comment in this code
|
|
// if(Lum > EyeAdaptationParams[0].w)
|
|
// {
|
|
// return 2;
|
|
// }
|
|
|
|
return 0;
|
|
}
|
|
|
|
uint ComputeAdviceUV(float2 UV)
|
|
{
|
|
float3 HDRColor = Texture2DSample(PostprocessInput2, PostprocessInput2Sampler, UV).rgb;
|
|
|
|
return ComputeAdvice(HDRColor);
|
|
}
|
|
|
|
// to highlight areas that have unrealistic materials
|
|
void HighlightAdvice(inout float3 OutColor, float2 UV, int2 PixelPos)
|
|
{
|
|
uint AdviceInner = ComputeAdviceUV(UV);
|
|
uint AdviceOuter = 0;
|
|
|
|
bool SpecialDotInArea = ((PixelPos.x + PixelPos.y) % 6) == 0 && ((PixelPos.x - PixelPos.y) % 6) == 0;
|
|
|
|
AdviceOuter = max(AdviceOuter, ComputeAdviceUV(UV + float2( 1, 0) * PostprocessInput0Size.zw));
|
|
AdviceOuter = max(AdviceOuter, ComputeAdviceUV(UV + float2( 0, 1) * PostprocessInput0Size.zw));
|
|
AdviceOuter = max(AdviceOuter, ComputeAdviceUV(UV + float2(-1, 0) * PostprocessInput0Size.zw));
|
|
AdviceOuter = max(AdviceOuter, ComputeAdviceUV(UV + float2( 0, -1) * PostprocessInput0Size.zw));
|
|
|
|
uint Advice = (AdviceInner == AdviceOuter && !SpecialDotInArea) ? 0 : AdviceOuter;
|
|
|
|
FLATTEN if(Advice)
|
|
{
|
|
FLATTEN if(Advice == 1)
|
|
{
|
|
// heavy shading cost
|
|
OutColor = float3(0, 0, 0.8f);
|
|
}
|
|
else
|
|
FLATTEN if(Advice == 2)
|
|
{
|
|
// warning
|
|
OutColor = float3(0.8f, 0.8f, 0);
|
|
}
|
|
else // if(Advice == 3)
|
|
{
|
|
// error
|
|
OutColor = float3(1, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
void MainPS(float4 UVAndScreenPos : TEXCOORD0, out float4 OutColor : SV_Target0)
|
|
{
|
|
float2 UV = UVAndScreenPos.xy;
|
|
int2 PixelPos = (int2)(UVAndScreenPos.zw * ScreenPosToPixel.xy + ScreenPosToPixel.zw + 0.5f);
|
|
|
|
// background is the scene color
|
|
OutColor = Texture2DSample(PostprocessInput0, PostprocessInput0Sampler, UV);
|
|
|
|
// not fully functional yet
|
|
// HighlightAdvice(OutColor.rgb, UV, PixelPos);
|
|
|
|
// left top of the border
|
|
const int2 HistogramLeftTop = int2(64, ViewportRect.w - 128 - 32);
|
|
const int2 HistogramSize = int2(ViewportRect.z - ViewportRect.x - 64 * 2, 128);
|
|
const int HistogramOuterBorder = 4;
|
|
const float3 BorderColor = float3(0.5f, 0.5f, 0.5f);
|
|
|
|
float BorderDistance = ComputeDistanceToRect(PixelPos, HistogramLeftTop, HistogramSize);
|
|
|
|
// thin black border around the histogram
|
|
OutColor.xyz = lerp(float3(0, 0, 0), OutColor.xyz, saturate(BorderDistance - (HistogramOuterBorder + 2)));
|
|
|
|
// big solid border around the histogram
|
|
OutColor.xyz = lerp(BorderColor, OutColor.xyz, saturate(BorderDistance - (HistogramOuterBorder + 1)));
|
|
|
|
// thin black border around the histogram
|
|
OutColor.xyz = lerp(float3(0, 0, 0), OutColor.xyz, saturate(BorderDistance - 1));
|
|
|
|
if(BorderDistance > 0)
|
|
{
|
|
// outside of the histogram
|
|
return;
|
|
}
|
|
|
|
// inside the histogram
|
|
|
|
// (0, 0) .. (1, 1)
|
|
float2 InsetPx = PixelPos - HistogramLeftTop;
|
|
float2 InsetUV = InsetPx / HistogramSize;
|
|
|
|
uint Bucket = (uint)(InsetUV.x * HISTOGRAM_SIZE);
|
|
|
|
// Texture2D HistogramTexture = InputNew1;
|
|
#define HistogramTexture InputNew1 // WAR for HLSLCC not allowing assignment to samplers (yet)
|
|
float HistogramSum = ComputeHistogramSum(HistogramTexture);
|
|
|
|
if(InsetUV.x < ComputeHistogramPositionFromLuminance(EyeAdaptationParams[0].z))
|
|
{
|
|
// < min: grey
|
|
OutColor.xyz = lerp(OutColor.xyz, float3(0.5f, 0.5f, 0.5f), 0.5f);
|
|
}
|
|
else if(InsetUV.x < ComputeHistogramPositionFromLuminance(EyeAdaptationParams[0].w))
|
|
{
|
|
// >= min && < max: green
|
|
OutColor.xyz = lerp(OutColor.xyz, float3(0.5f, 0.8f, 0.5f), 0.5f);
|
|
}
|
|
else
|
|
{
|
|
// >= max: grey
|
|
OutColor.xyz = lerp(OutColor.xyz, float3(0.5f, 0.5f, 0.5f), 0.5f);
|
|
}
|
|
|
|
float LocalHistogramValue = GetHistogramBucket(HistogramTexture, Bucket) / ComputeHistogramMax(HistogramTexture);
|
|
if(LocalHistogramValue >= 1 - InsetUV.y)
|
|
{
|
|
// histogram bars
|
|
OutColor.xyz = lerp(OutColor.xyz, float3(0.5f, 0.5f, 0.5f), 0.5f);
|
|
}
|
|
|
|
{
|
|
// HDR luminance >0
|
|
float LuminanceVal = ComputeLuminanceFromHistogramPosition(InsetUV.x);
|
|
// HDR > 0
|
|
float3 AdpatedLuminance = LuminanceVal * HistogramTexture.Load(int3(0, 1, 0)).xxx;
|
|
// 0..1
|
|
float3 TonemappedLuminance = FilmPostProcess(AdpatedLuminance);
|
|
float3 DistMask = saturate(1.0 - 100.0 * abs(TonemappedLuminance - (1.0 - InsetUV.y)));
|
|
OutColor = lerp(OutColor, float4(1, 1, 1, 0), float4(DistMask, 0.0));
|
|
}
|
|
|
|
{
|
|
float ValuePx = ComputeHistogramPositionFromLuminance(ComputeEyeAdaptationExposure(HistogramTexture)) * HistogramSize.x;
|
|
if(abs(InsetPx.x - ValuePx) < 3)
|
|
{
|
|
// blue line to show the clamped percentil
|
|
OutColor = lerp(OutColor, float4(0, 0, 1, 0), 0.5f);
|
|
}
|
|
}
|
|
|
|
{
|
|
float Value = ComputeHistogramPositionFromLuminance(1.0f / HistogramTexture.Load(int3(0, 1, 0)).x);
|
|
|
|
PrintFloat(PixelPos, OutColor.xyz, float3(1, 1, 1), HistogramLeftTop + int2(HistogramSize.x - 7 * 8 - 2, 3), Value);
|
|
|
|
float ValuePx = Value * HistogramSize.x;
|
|
if(abs(InsetPx.x - ValuePx) < 2)
|
|
{
|
|
// white line to show the smoothed exposure
|
|
OutColor = lerp(OutColor, float4(1, 1, 1, 0), 1.0f);
|
|
}
|
|
}
|
|
} |