This commit is contained in:
2025-05-13 02:46:21 +03:00
parent 143e16692e
commit 86914b7fcc
610 changed files with 92343 additions and 2 deletions
+420
View File
@@ -0,0 +1,420 @@
#ifndef PostHDR_h__
#define PostHDR_h__
#include "render/PostEffect.h"
#include "Globals.h"
#include "render/ITextureSampler.h"
#include "math/LifeMath.h"
#define _CRTDBG_MAP_ALLOC
#include "LifeDebug.h"
#include <stdlib.h>
#include <crtdbg.h>
namespace LifeGraphics
{
class PostHDR : public PostEffect
{
public:
ITexture2D* g_brightPassTexture;
ITexture2D* g_downSampleTexture;
ITexture2D* g_horizontalBlur;
ITexture2D* g_verticalBlur;
ITexture2D* g_finalImage;
ITexture2D* g_lumLast;
ITexture2D* g_lumCur;
static const int NumLuminanceTextures = 4;
ITexture2D* luminanceTextures[NumLuminanceTextures];
ITexture2D* luminanceTexturesZ[NumLuminanceTextures];
ITexture2D* src;
ITexture2D* srcZ;
ITexture2D* downSampleZ;
ITexture2D* brightPassZ;
ITextureSampler* samplerPointClamp;
float exposure;
float brightTheresold;
PostHDR()
{
}
~PostHDR()
{
SAFE_DELETE(g_brightPassTexture);
SAFE_DELETE(g_downSampleTexture);
SAFE_DELETE(g_horizontalBlur);
SAFE_DELETE(g_verticalBlur);
SAFE_DELETE(g_finalImage);
SAFE_DELETE(g_lumLast);
SAFE_DELETE(g_lumCur);
SAFE_DELETE(downSampleZ);
SAFE_DELETE(brightPassZ);
SAFE_DELETE(g_downSamplePS);
SAFE_DELETE(g_brightPassPS);
SAFE_DELETE(g_horizontalBlurPS);
SAFE_DELETE(g_verticalBlurPS);
SAFE_DELETE(g_downSample2x2PS);
SAFE_DELETE(g_downSample3x3PS);
SAFE_DELETE(g_resampleAvgLumExp);
SAFE_DELETE(g_lumAdaptation);
SAFE_DELETE(g_composePS);
SAFE_DELETE(g_constBuffer);
SAFE_DELETE(g_pointSampler);
SAFE_DELETE(g_linearSampler);
SAFE_DELETE(g_cbLumAdaptation);
for(int i = 0; i<NumLuminanceTextures; i++)
{
SAFE_DELETE(luminanceTextures[i]);
SAFE_DELETE(luminanceTexturesZ[i]);
}
}
ITexture2D* Execute(PostEffectParams& params)
{
g_renderer->SetPSTextureSampler(g_pointSampler, 0);
g_renderer->SetPSTextureSampler(g_linearSampler, 1);
g_renderer->SetTargets(g_downSampleTexture, downSampleZ);
g_renderer->SetViewport(LifeMath::Rect2i(0, 0, g_downSampleTexture->Width(), g_downSampleTexture->Height()));
//1'st pass - do down sampling
g_renderer->SetPixelShader(g_downSamplePS);
g_renderer->SetPSTexture(params.renderTarget, 0);
src = params.renderTarget;
srcZ = params.depthTarget;
Get4x4Offsets(params.renderTarget->Width(), params.renderTarget->Height(), offsets2);
g_constBuffer->Update(offsets2, sizeof(LifeMath::float4)*16);
g_renderer->SetPSConstantBuffer(g_constBuffer, 0);
// g_downSamplePS.SetFloat4A("downSampleOffsets", offsets2);
g_renderer->RenderToTextureNoPs();
// g_downSampleTexture.ToFile("C:\\rt_1_downSample.jpg");
//2'nd measure scene luminance
MeasureLuminance(g_downSampleTexture, params.depthTex);
//3'rd calculate scene luminance adaptation
//
CalculateLuminanceAdaptation(params.timeElapsed);
//4'th step - bright pass
g_renderer->UnbindResourcesPS();
g_renderer->SetTargets(g_brightPassTexture, brightPassZ);
g_renderer->SetPixelShader(g_brightPassPS);
g_renderer->SetPSTexture(g_downSampleTexture, 0);
g_renderer->SetPSTexture(g_lumCur, 1);
g_renderer->SetPSTexture(params.depthTex, 2);
//g_renderer.SetTextureSampler(g_pointSampler, 0);
/// g_renderer.SetTextureSampler(g_pointSampler, 1);
g_renderer->SetViewport(LifeMath::Rect2i(0, 0, g_brightPassTexture->Width(), g_brightPassTexture->Height()));
g_renderer->SetScissorRectangle(LifeMath::Rect2i(0, 0, g_brightPassTexture->Width(), g_brightPassTexture->Height()));
g_renderer->RenderToTextureNoPs();
// g_brightPassTexture.ToFile("C:\\rt_2_brightPass.jpg");
// g_renderer.SetTextureSampler(g_linearSampler, 0);
g_renderer->UnbindResourcesPS();
g_renderer->SetPSTextureSampler(samplerPointClamp, 0);
g_renderer->SetPSTextureSampler(samplerPointClamp, 1);
//5'th pass - do horizontal blur
g_renderer->SetTargets(g_horizontalBlur, downSampleZ);
g_renderer->SetPixelShader(g_horizontalBlurPS);
g_renderer->SetPSTexture(g_brightPassTexture, 0);
GetBlurWeightedOffsets((float)NumBlurSamples, g_brightPassTexture->Width(), offsets3);
g_constBuffer->Update(offsets3, sizeof(LifeMath::float4)*NumBlurSamples);
g_renderer->SetPSConstantBuffer(g_constBuffer, 0);
// g_horizontalBlurPS.SetFloat4A("hBlurOffsets", offsets3);
g_renderer->SetViewport(LifeMath::Rect2i(0, 0, g_horizontalBlur->Width(), g_horizontalBlur->Height()));
g_renderer->SetScissorRectangle(LifeMath::Rect2i(0, 0, g_horizontalBlur->Width(), g_horizontalBlur->Height()));
g_renderer->RenderToTextureNoPs();
// g_horizontalBlur.ToFile("C:\\rt_3_horBlur.jpg");
//6'th pass - do vertical blur
g_renderer->UnbindResourcesPS();
g_renderer->SetTargets(g_verticalBlur, downSampleZ);
g_renderer->SetPixelShader(g_verticalBlurPS);
g_renderer->SetPSTexture(g_horizontalBlur, 0);
GetBlurWeightedOffsets((float)NumBlurSamples, g_brightPassTexture->Height(), offsets3);
//g_verticalBlurPS.SetFloat4A("vBlurOffsets", offsets4);
g_constBuffer->Update(offsets3, sizeof(LifeMath::float4)*NumBlurSamples);
g_renderer->SetPSConstantBuffer(g_constBuffer, 0);
g_renderer->RenderToTextureNoPs();
//7'th compose final image
ComposeFinalImage(params.renderTarget, g_lumCur, g_verticalBlur);
// g_finalImage.ToFile("C:\\rt_5_final.jpg");
return g_finalImage;
}
void Init(SceneDescriptor& desc)
{
g_renderer = CG::me()->GetRenderer();
g_lumAdaptation = ResourceManager::me()->CompileUserShaderPS(String(_text("HDRLumAdaptation.psh")));
/* char laPs[] =
"Texture2D tex0 : register(t7);"\
"Texture2D tex1 : register(t8);"\
"SamplerState linearSampler : register(s0);"\
"cbuffer timeData : register(b11){float4 g_fElapsedTime : packoffset(c0);};"\
"float4 main_PS(in float4 Position : SV_Position, in float2 texcoord : TEXCOORD0) : SV_Target{"\
"float4 fAdaptedLum =tex0.Sample(linearSampler, float2(0.25f, 0.25f));"\
"float4 fCurrentLum = tex1.Sample(linearSampler, float2(0.5f, 0.5f));"\
"float fNewAdaptation = fAdaptedLum + (fCurrentLum - fAdaptedLum) * g_fElapsedTime.x;"\
"return fAdaptedLum;}";
g_lumAdaptation = g_renderer->CompileUserShaderPS(laPs);*/
ISamplerDescription pscDesc(Clamp, Clamp, Clamp, MinMagMipPoint);
samplerPointClamp = g_renderer->CreateTextureSampler(&pscDesc);
exposure = 0.72f;
brightTheresold = 0.7f;
g_finalImage = g_renderer->CreateRenderTarget(desc.width, desc.height, FORMAT_R16G16B16A16_FLOAT);
//Bright pass texture
int brightPassTextureWidth = desc.width / 4;
int brightPassTextureHeight = desc.height / 4;
g_brightPassTexture = g_renderer->CreateRenderTarget(brightPassTextureWidth,
brightPassTextureHeight, FORMAT_R16G16B16A16_FLOAT);
brightPassZ = g_renderer->CreateDepthTarget(brightPassTextureWidth,
brightPassTextureHeight, FORMAT_D16_UNORM);
//Down sample texture
int downSampledTextureWidth = brightPassTextureWidth / 1;
int downSampledTextureHeight = brightPassTextureHeight / 1;
g_downSampleTexture = g_renderer->CreateRenderTarget(downSampledTextureWidth,
downSampledTextureHeight, FORMAT_R16G16B16A16_FLOAT);
downSampleZ = g_renderer->CreateDepthTarget(downSampledTextureWidth,
downSampledTextureHeight, FORMAT_D16_UNORM);
//Horizontal blur texture
int horizontalBlurTextureWidth = downSampledTextureWidth;
int horizontalBlurTextureHeight = downSampledTextureHeight;
g_horizontalBlur = g_renderer->CreateRenderTarget(horizontalBlurTextureWidth,
horizontalBlurTextureHeight, FORMAT_R16G16B16A16_FLOAT);
//Vertical blur texture
int verticalBlurTextureWidth = horizontalBlurTextureWidth;
int verticalBlurTextureHeight = horizontalBlurTextureHeight;
g_verticalBlur = g_renderer->CreateRenderTarget(verticalBlurTextureWidth,
verticalBlurTextureHeight, FORMAT_R16G16B16A16_FLOAT);
g_downSamplePS = ResourceManager::me()->CompileUserShaderPS(String(_text("DownSample.psh")));
g_brightPassPS = ResourceManager::me()->CompileUserShaderPS(String(_text("BrightPass.psh")));
g_horizontalBlurPS = ResourceManager::me()->CompileUserShaderPS(String(_text("HorizontalBlur.psh")));
g_verticalBlurPS = ResourceManager::me()->CompileUserShaderPS(String(_text("VerticalBlur.psh")));
g_resampleAvgLumExp = ResourceManager::me()->CompileUserShaderPS(String(_text("ResampleAvgLumExp.psh")));
//LC
g_downSample2x2PS = ResourceManager::me()->CompileUserShaderPS(String(_text("SampleLumInitial.psh")));
g_downSample3x3PS = ResourceManager::me()->CompileUserShaderPS(String(_text("DownSampleLum3.psh")));
g_composePS = ResourceManager::me()->CompileUserShaderPS(String(_text("ComposeHDR.psh")));
g_constBuffer = g_renderer->CreateConstantBuffer(16 * 16*256);
g_cbLumAdaptation = g_renderer->CreateConstantBuffer(sizeof(LifeMath::float4));
CreateLuminanceTextures();
ISamplerDescription psDesc(Wrap, Wrap, Wrap, MinMagMipPoint);
ISamplerDescription lsDesc(Wrap, Wrap, Wrap, Anisotropic);
g_pointSampler = g_renderer->CreateTextureSampler(&psDesc);
g_linearSampler = g_renderer->CreateTextureSampler(&lsDesc);
}
private:
static const int MAX_SAMPLES = 6;
//post effects
IShader* g_downSamplePS;
IShader* g_brightPassPS;
IShader* g_horizontalBlurPS;
IShader* g_verticalBlurPS;
//luminance calculation
IShader* g_downSample2x2PS;
IShader* g_downSample3x3PS;
IShader* g_resampleAvgLumExp;
IShader* g_lumAdaptation;
//final composing shader
IShader* g_composePS;
static const int NumBlurSamples = 9;
//luminance calculator
IRenderer* g_renderer;
IConstantBuffer* g_constBuffer;
ITextureSampler* g_pointSampler;
ITextureSampler* g_linearSampler;
IConstantBuffer* g_cbLumAdaptation;
LifeMath::float4 offsets2[16];
LifeMath::float4 offsets3[NumBlurSamples];
LifeMath::float4 offsets[9];
void CreateLuminanceTextures()
{
for (int i = 0; i < NumLuminanceTextures; i++)
{
int iSampleLen = 1 << (2 * i);
luminanceTextures[i] = g_renderer->CreateRenderTarget(iSampleLen, iSampleLen, FORMAT_R16G16B16A16_FLOAT);
luminanceTexturesZ[i] = g_renderer->CreateDepthTarget(iSampleLen, iSampleLen, FORMAT_D16_UNORM);
}
g_lumCur = g_renderer->CreateRenderTarget(1, 1, FORMAT_R16G16B16A16_FLOAT);
g_lumLast = g_renderer->CreateRenderTarget(1, 1, FORMAT_R16G16B16A16_FLOAT);
LifeMath::float4 clear_color(1,1,1,1);
g_renderer->ClearRenderTarget(g_lumCur, &clear_color);
g_renderer->ClearRenderTarget(g_lumLast, &clear_color);
}
void Render2x2Pass(ITexture2D* srcTexture, ITexture2D* destTexture, ITexture2D* sceneDepth)
{
float tU, tV;
tU = 1.0f / (3.0f * destTexture->Width());
tV = 1.0f / (3.0f * destTexture->Height());
int index = 0;
for (int x = -1; x <= 1; x++)
{
for (int y = -1; y <= 1; y++)
{
offsets[index].X = (float)x * tU;
offsets[index].Y = (float)y * tV;
index++;
}
}
g_renderer->SetTargets(destTexture,luminanceTexturesZ[NumLuminanceTextures - 1]);
g_renderer->SetPSTexture(srcTexture, 0);
g_renderer->SetPSTexture(sceneDepth, 1);
g_renderer->SetPixelShader(g_downSample2x2PS);
g_constBuffer->Update(&offsets, sizeof(LifeMath::float4)* 9);
g_renderer->SetPSConstantBuffer(g_constBuffer, 0);
// With everything configured we can now render the first pass to the luminance textures.
g_renderer->SetViewport(LifeMath::Rect2i(0, 0, destTexture->Width(), destTexture->Height()));
g_renderer->RenderToTextureNoPs();
}
void MeasureLuminance(ITexture2D* hdrTexture, ITexture2D* depth)
{
int curTex = NumLuminanceTextures - 1;
Render2x2Pass(hdrTexture, luminanceTextures[curTex],depth);
curTex--;
while (curTex > 0)
{
g_renderer->SetTargets(luminanceTextures[curTex], luminanceTexturesZ[curTex]);
Get4x4Offsets(luminanceTextures[curTex + 1]->Width(), luminanceTextures[curTex + 1]->Height(), offsets2);
g_renderer->SetPixelShader(g_downSample3x3PS);
g_renderer->SetPSTexture(luminanceTextures[curTex + 1], 0);
g_constBuffer->Update(offsets2, sizeof(LifeMath::float4)*16);
g_renderer->SetPSConstantBuffer(g_constBuffer, 0);
g_renderer->SetViewport(LifeMath::Rect2i(0, 0, luminanceTextures[curTex]->Width(), luminanceTextures[curTex]->Height()));
g_renderer->SetScissorRectangle(LifeMath::Rect2i(0, 0, luminanceTextures[curTex]->Width(), luminanceTextures[curTex]->Height()));
g_renderer->RenderToTextureNoPs();
curTex--;
}
g_renderer->SetTargets(luminanceTextures[0],luminanceTexturesZ[0]);
g_renderer->SetPixelShader(g_resampleAvgLumExp);
Get4x4Offsets(luminanceTextures[1]->Width(), luminanceTextures[1]->Height(), offsets2);
g_constBuffer->Update(offsets2, sizeof(LifeMath::float4)*16);
g_renderer->SetPSConstantBuffer(g_constBuffer, 0);
g_renderer->SetPSTexture(luminanceTextures[1], 0);
g_renderer->SetViewport(LifeMath::Rect2i(0, 0, luminanceTextures[0]->Width(), luminanceTextures[0]->Height()));
g_renderer->SetScissorRectangle(LifeMath::Rect2i(0, 0, luminanceTextures[0]->Width(), luminanceTextures[0]->Height()));
g_renderer->RenderToTextureNoPs();
}
void CalculateLuminanceAdaptation(float timeElapsed)
{
g_renderer->SetViewport(LifeMath::Rect2i(0, 0, 1, 1));
g_renderer->SetScissorRectangle(LifeMath::Rect2i(0, 0, 1, 1));
g_renderer->UnbindResourcesPS();
ITexture2D* texSwap = g_lumLast;
g_lumLast = g_lumCur;
g_lumCur = texSwap;
g_renderer->SetTargets(g_lumCur, luminanceTexturesZ[0]);
LifeMath::float4 clear_color(0,0,0,0);
g_renderer->ClearRenderTarget(g_lumCur, &clear_color);
g_renderer->SetPixelShader(g_lumAdaptation);
g_renderer->SetPSTexture(g_lumLast, luminanceTextures[0], 7,2);
// g_renderer->SetPSTexture(rgba.ptr(), luminanceTextures[0], 7,2);
if(timeElapsed <0.0000001f)
timeElapsed = 0.0000001f;
if(timeElapsed > 1.0f)
timeElapsed = 1.0f;
float val = (1.0f - (pow(0.98f, 30.0f * timeElapsed)));
LifeMath::float4 time(val, 1.0f, 1.0f, 1.0f);
g_cbLumAdaptation->Update(&time, sizeof(LifeMath::float4));
g_renderer->SetPSConstantBuffer(g_cbLumAdaptation, 11);
g_renderer->RenderToTextureNoPs();
}
void ComposeFinalImage(ITexture2D* hdrTexture, ITexture2D* luminanceTexture, ITexture2D* bloomTexture)
{
g_renderer->SetPSTextureSampler(g_linearSampler, 1);
g_renderer->SetTargets(g_finalImage, srcZ);
g_renderer->SetPixelShader(g_composePS);
g_renderer->SetPSTexture(hdrTexture, 0);
g_renderer->SetPSTexture(bloomTexture, 1);
g_renderer->SetPSTextureNULL(2);
g_renderer->SetPSTexture(luminanceTexture, 3);
float g_fKeyValue = 0.05f;
LifeMath::float4 key(g_fKeyValue, 0, 0, 0);
g_constBuffer->Update(key, sizeof(LifeMath::float4));
g_renderer->SetPSConstantBuffer(g_constBuffer, 0);
// g_composePS.SetFloat("g_fMiddleGray", g_fKeyValue);
g_renderer->SetViewport(LifeMath::Rect2i(0, 0, g_finalImage->Width(), g_finalImage->Height()));
g_renderer->SetScissorRectangle(LifeMath::Rect2i(0, 0, g_finalImage->Width(), g_finalImage->Height()));
g_renderer->RenderToTextureNoPs();
g_renderer->UnbindResourcesPS();
}
};
}
#endif // PostHDR_h__