Files
UnrealEngineUWP/Engine/Source/Runtime/Renderer/Private/PostProcess/PostProcessVisualizeHDR.cpp
Gil Gribb 2e5b4cbbd1 Copying //UE4/Dev-Rendering to Dev-Main (//UE4/Dev-Main)
#lockdown nick.penwarden

==========================
MAJOR FEATURES + CHANGES
==========================

Change 2821445 on 2016/01/08 by Olaf.Piesche
	More vertex factory improvements, storing off particle vertex factories on the scene proxy instead of the dynamic data to avoid recreating all the time; saves up to 2ms render thread time according to QA's testing.

	#rb martin.mittring

Change 2821520 on 2016/01/08 by Olaf.Piesche

	Coloring subuv modules green for easier visual ID

	#rb martin.mittring

Change 2823479 on 2016/01/11 by Chris.Bunner

	Updated Lightmass HLOD logic to avoid HLODs shadowing non-related meshes. Duplicated CL#2823104 from Dev-General.

Change 2823570 on 2016/01/11 by Zabir.Hoque

	Introduce multiplier that controls decal fade speed.

	#CodeReview: Martin.Mittring
	#1777

Change 2823615 on 2016/01/11 by Uriel.Doyon

	Fixed stencil ref multithreading issue.
	Fixed state caching when depth range is enabled.
	#jira UE-24564
	#review marcus.wassmer

Change 2823652 on 2016/01/11 by Zabir.Hoque

	Rename FadeSpeedScale -> FadeDurationScale to be logically more consistent.

	#CodeReview: Martin.Mittring

Change 2824065 on 2016/01/11 by Brian.Karis

	Fixed last viewrect motion blur bug. Enabled new motion blur algorithm for default.

Change 2825432 on 2016/01/12 by Zabir.Hoque

	Store off view matrices at at time of freezing and base lod selection useing relevant matrices, thus allows lods to be frozen. #OR-10918

	#CodeReview: Marcus.Wassmer, Rolando.Caloca, Martin.Mittring

Change 2825971 on 2016/01/12 by Brian.Karis

	New motion blur enabled.

Change 2825974 on 2016/01/12 by Brian.Karis

	Fixed refraction check value. 1 does nothing not 0.

Change 2825975 on 2016/01/12 by Brian.Karis

	Cloth gets skylight for movable sky.

Change 2827519 on 2016/01/13 by Zabir.Hoque

	ALLOW_UAV_CONDITION did not have a safe fallback when not SM5.0 && COMPILER_SUPPORTS_ATTRIBUTES.

	#CodeReview Martin.Mittring, Rolando.Caloca

Change 2830172 on 2016/01/15 by Rolando.Caloca

	DR - Minor cleanup
	- Renamed Vertex Factories' struct Data to struct FData
	- Removed Data type on FVertexFactory

Change 2830242 on 2016/01/15 by Rolando.Caloca

	DR - Prep cleanup for gpu morph targets
	- Split common code for  GPU skin cache into a base class
	- Moved some local static arrays from UpdateMorphVertexBuffer() to static members
	#codereview Lina.Halper

Change 2830455 on 2016/01/15 by Rolando.Caloca

	DR - Compile fix from bad merge
	#jira UE-25557

Change 2832023 on 2016/01/18 by Rolando.Caloca

	DR - Removed TangentZDelta_DEPRECATED from FVertexAnimDelta
	#rb Marcus.Wassmer
	#codereview Lina.Halper

Change 2832067 on 2016/01/18 by Gil.Gribb

	UE4 - Changed PC to default to parallel rendering when not in editor. Fixed lack of a stall on texture locks and unlocks coming from texture streamer. Fixed a few cases where stuff was being added to rhicommandlists even when we were bypassed.

Change 2834379 on 2016/01/19 by Gil.Gribb

	UE4 - fix perf regression related to cvar

Change 2834864 on 2016/01/19 by Olaf.Piesche

	Fixing potential crash with auto-kill trail emitters, fixing use of the wrong flag to auto-deactivate

	#codereview gil.gribb

Change 2835777 on 2016/01/20 by David.Hill

	EyeAdaptation - using a screen center focus in the weights
	#rb Martin Mitring

	related to: UE-15509.  This is adding the ability to focus the basic eye-adaptation region in the center of the screen, and cvar functionality for paragon testing on ps4

Change 2835778 on 2016/01/20 by David.Hill

	EyeAdapation - DefaultFeature for method
	#rb Martin.Mitring
	Adding a default feature cvar for eye adaptation method

Change 2837410 on 2016/01/20 by David.Hill

	OR-13213   SetupPerObjectProjection()
	#test:PC
	#rb:Martin.Mitring
	#codereview:Daniel.Wright

[CL 2845257 by Gil Gribb in Main branch]
2016-01-27 07:18:43 -05:00

339 lines
14 KiB
C++

// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
/*=============================================================================
PostProcessVisualizeHDR.cpp: Post processing VisualizeHDR implementation.
=============================================================================*/
#include "RendererPrivate.h"
#include "ScenePrivate.h"
#include "SceneFilterRendering.h"
#include "PostProcessVisualizeHDR.h"
#include "PostProcessing.h"
#include "PostProcessHistogram.h"
#include "PostProcessEyeAdaptation.h"
#include "PostProcessTonemap.h"
#include "SceneUtils.h"
/** Encapsulates the post processing eye adaptation pixel shader. */
class FPostProcessVisualizeHDRPS : public FGlobalShader
{
DECLARE_SHADER_TYPE(FPostProcessVisualizeHDRPS, Global);
static bool ShouldCache(EShaderPlatform Platform)
{
return IsFeatureLevelSupported(Platform, ERHIFeatureLevel::SM5);
}
static void ModifyCompilationEnvironment(EShaderPlatform Platform, FShaderCompilerEnvironment& OutEnvironment)
{
FGlobalShader::ModifyCompilationEnvironment(Platform, OutEnvironment);
OutEnvironment.SetDefine(TEXT("USE_COLOR_MATRIX"), 1);
OutEnvironment.SetDefine(TEXT("USE_SHADOW_TINT"), 1);
OutEnvironment.SetDefine(TEXT("USE_CONTRAST"), 1);
OutEnvironment.SetDefine(TEXT("USE_APPROXIMATE_SRGB"), (uint32)0);
}
/** Default constructor. */
FPostProcessVisualizeHDRPS() {}
public:
FPostProcessPassParameters PostprocessParameter;
FShaderParameter EyeAdaptationParams;
FShaderResourceParameter MiniFontTexture;
FShaderParameter InverseGamma;
FShaderParameter HistogramParams;
FShaderParameter ColorMatrixR_ColorCurveCd1;
FShaderParameter ColorMatrixG_ColorCurveCd3Cm3;
FShaderParameter ColorMatrixB_ColorCurveCm2;
FShaderParameter ColorCurve_Cm0Cd0_Cd2_Ch0Cm1_Ch3;
FShaderParameter ColorCurve_Ch1_Ch2;
FShaderParameter ColorShadow_Luma;
FShaderParameter ColorShadow_Tint1;
FShaderParameter ColorShadow_Tint2;
FShaderResourceParameter EyeAdaptationTexture;
/** Initialization constructor. */
FPostProcessVisualizeHDRPS(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
: FGlobalShader(Initializer)
{
PostprocessParameter.Bind(Initializer.ParameterMap);
EyeAdaptationParams.Bind(Initializer.ParameterMap, TEXT("EyeAdaptationParams"));
MiniFontTexture.Bind(Initializer.ParameterMap, TEXT("MiniFontTexture"));
InverseGamma.Bind(Initializer.ParameterMap,TEXT("InverseGamma"));
HistogramParams.Bind(Initializer.ParameterMap,TEXT("HistogramParams"));
ColorMatrixR_ColorCurveCd1.Bind(Initializer.ParameterMap, TEXT("ColorMatrixR_ColorCurveCd1"));
ColorMatrixG_ColorCurveCd3Cm3.Bind(Initializer.ParameterMap, TEXT("ColorMatrixG_ColorCurveCd3Cm3"));
ColorMatrixB_ColorCurveCm2.Bind(Initializer.ParameterMap, TEXT("ColorMatrixB_ColorCurveCm2"));
ColorCurve_Cm0Cd0_Cd2_Ch0Cm1_Ch3.Bind(Initializer.ParameterMap, TEXT("ColorCurve_Cm0Cd0_Cd2_Ch0Cm1_Ch3"));
ColorCurve_Ch1_Ch2.Bind(Initializer.ParameterMap, TEXT("ColorCurve_Ch1_Ch2"));
ColorShadow_Luma.Bind(Initializer.ParameterMap, TEXT("ColorShadow_Luma"));
ColorShadow_Tint1.Bind(Initializer.ParameterMap, TEXT("ColorShadow_Tint1"));
ColorShadow_Tint2.Bind(Initializer.ParameterMap, TEXT("ColorShadow_Tint2"));
EyeAdaptationTexture.Bind(Initializer.ParameterMap, TEXT("EyeAdaptationTexture"));
}
void SetPS(const FRenderingCompositePassContext& Context)
{
const FPixelShaderRHIParamRef ShaderRHI = GetPixelShader();
FGlobalShader::SetParameters(Context.RHICmdList, ShaderRHI, Context.View);
const FPostProcessSettings& Settings = Context.View.FinalPostProcessSettings;
const FSceneViewFamily& ViewFamily = *(Context.View.Family);
PostprocessParameter.SetPS(ShaderRHI, Context, TStaticSamplerState<SF_Point,AM_Clamp,AM_Clamp,AM_Clamp>::GetRHI());
{
FVector4 Temp[3];
FRCPassPostProcessEyeAdaptation::ComputeEyeAdaptationParamsValue(Context.View, Temp);
if (GetAutoExposureMethod(Context.View) == EAutoExposureMethod::AEM_Basic)
{
Temp[2].W = GetBasicAutoExposureFocus();
}
else
{
Temp[2].W = 0.0f;
}
SetShaderValueArray(Context.RHICmdList, ShaderRHI, EyeAdaptationParams, Temp, 3);
}
SetTextureParameter(Context.RHICmdList, ShaderRHI, MiniFontTexture, GEngine->MiniFontTexture ? GEngine->MiniFontTexture->Resource->TextureRHI : GSystemTextures.WhiteDummy->GetRenderTargetItem().TargetableTexture);
// Load Current Eye Adaptation value.
if (EyeAdaptationTexture.IsBound())
{
if (Context.View.HasValidEyeAdaptation())
{
IPooledRenderTarget* EyeAdaptationRT = Context.View.GetEyeAdaptation(Context.RHICmdList);
SetTextureParameter(Context.RHICmdList, ShaderRHI, EyeAdaptationTexture, EyeAdaptationRT->GetRenderTargetItem().TargetableTexture);
}
else
{
SetTextureParameter(Context.RHICmdList, ShaderRHI, EyeAdaptationTexture, GWhiteTexture->TextureRHI);
}
}
{
FIntPoint GatherExtent = FRCPassPostProcessHistogram::ComputeGatherExtent(Context.View);
uint32 TexelPerThreadGroupX = FRCPassPostProcessHistogram::ThreadGroupSizeX * FRCPassPostProcessHistogram::LoopCountX;
uint32 TexelPerThreadGroupY = FRCPassPostProcessHistogram::ThreadGroupSizeY * FRCPassPostProcessHistogram::LoopCountY;
FIntRect Value(GatherExtent, FIntPoint(TexelPerThreadGroupX, TexelPerThreadGroupY));
SetShaderValue(Context.RHICmdList, ShaderRHI, HistogramParams, Value);
}
{
float InvDisplayGammaValue = 1.0f / ViewFamily.RenderTarget->GetDisplayGamma();
SetShaderValue(Context.RHICmdList, ShaderRHI, InverseGamma, InvDisplayGammaValue);
}
{
FVector4 Constants[8];
FilmPostSetConstants(Constants, ~0, &Context.View.FinalPostProcessSettings, false);
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorMatrixR_ColorCurveCd1, Constants[0]);
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorMatrixG_ColorCurveCd3Cm3, Constants[1]);
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorMatrixB_ColorCurveCm2, Constants[2]);
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorCurve_Cm0Cd0_Cd2_Ch0Cm1_Ch3, Constants[3]);
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorCurve_Ch1_Ch2, Constants[4]);
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorShadow_Luma, Constants[5]);
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorShadow_Tint1, Constants[6]);
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorShadow_Tint2, Constants[7]);
}
}
// FShader interface.
virtual bool Serialize(FArchive& Ar) override
{
bool bShaderHasOutdatedParameters = FGlobalShader::Serialize(Ar);
Ar << PostprocessParameter << EyeAdaptationParams << MiniFontTexture << InverseGamma << HistogramParams
<< ColorMatrixR_ColorCurveCd1 << ColorMatrixG_ColorCurveCd3Cm3 << ColorMatrixB_ColorCurveCm2 << ColorCurve_Cm0Cd0_Cd2_Ch0Cm1_Ch3
<< ColorCurve_Ch1_Ch2 << ColorShadow_Luma << ColorShadow_Tint1 << ColorShadow_Tint2 << EyeAdaptationTexture;
return bShaderHasOutdatedParameters;
}
};
IMPLEMENT_SHADER_TYPE(,FPostProcessVisualizeHDRPS,TEXT("PostProcessVisualizeHDR"),TEXT("MainPS"),SF_Pixel);
FString LogToString(float LogValue)
{
if(LogValue > 0)
{
return FString::Printf(TEXT("%.0f"), FMath::Pow(2.0f, LogValue));
}
else
{
return FString::Printf(TEXT("1/%.0f"), FMath::Pow(2.0f, -LogValue));
}
}
void FRCPassPostProcessVisualizeHDR::Process(FRenderingCompositePassContext& Context)
{
SCOPED_DRAW_EVENT(Context.RHICmdList, PostProcessVisualizeHDR);
const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0);
if(!InputDesc)
{
// input is not hooked up correctly
return;
}
const FSceneView& View = Context.View;
const FViewInfo& ViewInfo = Context.View;
const FSceneViewFamily& ViewFamily = *(View.Family);
FIntRect SrcRect = View.ViewRect;
FIntRect DestRect = View.ViewRect;
FIntPoint SrcSize = InputDesc->Extent;
const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context);
// Set the view family's render target/viewport.
SetRenderTarget(Context.RHICmdList, DestRenderTarget.TargetableTexture, FTextureRHIRef());
Context.SetViewportAndCallRHI(DestRect);
// set the state
Context.RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI());
Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI());
Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI());
TShaderMapRef<FPostProcessVS> VertexShader(Context.GetShaderMap());
TShaderMapRef<FPostProcessVisualizeHDRPS> PixelShader(Context.GetShaderMap());
static FGlobalBoundShaderState BoundShaderState;
SetGlobalBoundShaderState(Context.RHICmdList, Context.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);
PixelShader->SetPS(Context);
// Draw a quad mapping scene color to the view's render target
DrawRectangle(
Context.RHICmdList,
DestRect.Min.X, DestRect.Min.Y,
DestRect.Width(), DestRect.Height(),
SrcRect.Min.X, SrcRect.Min.Y,
SrcRect.Width(), SrcRect.Height(),
DestRect.Size(),
SrcSize,
*VertexShader,
EDRF_UseTriangleOptimization);
// this is a helper class for FCanvas to be able to get screen size
class FRenderTargetTemp : public FRenderTarget
{
public:
const FSceneView& View;
const FTexture2DRHIRef Texture;
FRenderTargetTemp(const FSceneView& InView, const FTexture2DRHIRef InTexture)
: View(InView), Texture(InTexture)
{
}
virtual FIntPoint GetSizeXY() const
{
return View.ViewRect.Size();
};
virtual const FTexture2DRHIRef& GetRenderTargetTexture() const
{
return Texture;
}
} TempRenderTarget(View, (const FTexture2DRHIRef&)DestRenderTarget.TargetableTexture);
FCanvas Canvas(&TempRenderTarget, NULL, ViewFamily.CurrentRealTime, ViewFamily.CurrentWorldTime, ViewFamily.DeltaWorldTime, Context.GetFeatureLevel());
float X = 30;
float Y = 28;
const float YStep = 14;
const float ColumnWidth = 250;
FString Line;
Line = FString::Printf(TEXT("HDR Histogram (Logarithmic, max of RGB)"));
Canvas.DrawShadowedString( X, Y += YStep, *Line, GetStatsFont(), FLinearColor(1, 1, 1));
Y += 160;
float MinX = 64 + 10;
float MaxY = View.ViewRect.Max.Y - 64;
float SizeX = View.ViewRect.Size().X - 64 * 2 - 20;
for(uint32 i = 0; i <= 4; ++i)
{
int XAdd = (int)(i * SizeX / 4);
float HistogramPosition = i / 4.0f;
float LogValue = FMath::Lerp(View.FinalPostProcessSettings.HistogramLogMin, View.FinalPostProcessSettings.HistogramLogMax, HistogramPosition);
Line = FString::Printf(TEXT("%.2g"), LogValue);
Canvas.DrawShadowedString( MinX + XAdd - 5, MaxY, *Line, GetStatsFont(), FLinearColor(1, 0.3f, 0.3f));
Line = LogToString(LogValue);
Canvas.DrawShadowedString( MinX + XAdd - 5, MaxY + YStep, *Line, GetStatsFont(), FLinearColor(0.3f, 0.3f, 1));
}
Y += 3 * YStep;
if (GetAutoExposureMethod(ViewInfo) == EAutoExposureMethod::AEM_Basic)
{
Line = FString::Printf(TEXT("Basic"));
}
else
{
Line = FString::Printf(TEXT("Histogram"));
}
Canvas.DrawShadowedString(X, Y += YStep, TEXT("Auto Exposure Method:"), GetStatsFont(), FLinearColor(1, 1, 1));
Canvas.DrawShadowedString(X + ColumnWidth, Y, *Line, GetStatsFont(), FLinearColor(1, 1, 1));
Line = FString::Printf(TEXT("%g%% .. %g%%"), View.FinalPostProcessSettings.AutoExposureLowPercent, View.FinalPostProcessSettings.AutoExposureHighPercent);
Canvas.DrawShadowedString( X, Y += YStep, TEXT("Percent Low/High:"), GetStatsFont(), FLinearColor(1, 1, 1));
Canvas.DrawShadowedString( X + ColumnWidth, Y, *Line, GetStatsFont(), FLinearColor(1, 1, 1));
Line = FString::Printf(TEXT("%g .. %g"), View.FinalPostProcessSettings.AutoExposureMinBrightness, View.FinalPostProcessSettings.AutoExposureMaxBrightness);
Canvas.DrawShadowedString( X, Y += YStep, TEXT("Brightness Min/Max:"), GetStatsFont(), FLinearColor(1, 1, 1));
Canvas.DrawShadowedString( X + ColumnWidth, Y, *Line, GetStatsFont(), FLinearColor(0.3f, 0.3f, 1));
Line = FString::Printf(TEXT("%g / %g"), View.FinalPostProcessSettings.AutoExposureSpeedUp, View.FinalPostProcessSettings.AutoExposureSpeedDown);
Canvas.DrawShadowedString( X, Y += YStep, TEXT("Speed Up/Down:"), GetStatsFont(), FLinearColor(1, 1, 1));
Canvas.DrawShadowedString( X + ColumnWidth, Y, *Line, GetStatsFont(), FLinearColor(1, 1, 1));
Line = FString::Printf(TEXT("%g"), View.FinalPostProcessSettings.AutoExposureBias);
Canvas.DrawShadowedString( X, Y += YStep, TEXT("Exposure Bias: "), GetStatsFont(), FLinearColor(1, 1, 1));
Canvas.DrawShadowedString( X + ColumnWidth, Y, *Line, GetStatsFont(), FLinearColor(1, 0.3f, 0.3f));
Line = FString::Printf(TEXT("%g .. %g (log2)"),
View.FinalPostProcessSettings.HistogramLogMin, View.FinalPostProcessSettings.HistogramLogMax);
Canvas.DrawShadowedString( X, Y += YStep, TEXT("Log Min/Max:"), GetStatsFont(), FLinearColor(1, 1, 1));
Canvas.DrawShadowedString( X + ColumnWidth, Y, *Line, GetStatsFont(), FLinearColor(1, 0.3f, 0.3f));
Line = FString::Printf(TEXT("%s .. %s (Value)"),
*LogToString(View.FinalPostProcessSettings.HistogramLogMin), *LogToString(View.FinalPostProcessSettings.HistogramLogMax));
Canvas.DrawShadowedString( X + ColumnWidth, Y+= YStep, *Line, GetStatsFont(), FLinearColor(0.3f, 0.3f, 1));
if (GetAutoExposureMethod(ViewInfo) == EAutoExposureMethod::AEM_Basic)
{
Line = FString::Printf(TEXT("%g"), GetBasicAutoExposureFocus());
Canvas.DrawShadowedString(X, Y += YStep, TEXT("Weighting Focus: "), GetStatsFont(), FLinearColor(1, 1, 1));
Canvas.DrawShadowedString(X + ColumnWidth, Y, *Line, GetStatsFont(), FLinearColor(1, 0.3f, 0.3f));
}
Canvas.Flush_RenderThread(Context.RHICmdList);
Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams());
}
FPooledRenderTargetDesc FRCPassPostProcessVisualizeHDR::ComputeOutputDesc(EPassOutputId InPassOutputId) const
{
FPooledRenderTargetDesc Ret = GetInput(ePId_Input0)->GetOutput()->RenderTargetDesc;
Ret.Reset();
Ret.DebugName = TEXT("VisualizeHDR");
return Ret;
}