trying to a add automatic exposure
This commit is contained in:
@@ -3,43 +3,121 @@
|
||||
using namespace Seele;
|
||||
|
||||
ToneMappingPass::ToneMappingPass(Gfx::PGraphics graphics) : RenderPass(graphics) {
|
||||
layout = graphics->createDescriptorLayout("ToneMappingDescriptor");
|
||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
tonemappingLayout = graphics->createDescriptorLayout("ToneMappingDescriptor");
|
||||
tonemappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "offset",
|
||||
.uniformLength = sizeof(Vector4),
|
||||
});
|
||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
tonemappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "slope",
|
||||
.uniformLength = sizeof(Vector4),
|
||||
});
|
||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
tonemappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "power",
|
||||
.uniformLength = sizeof(Vector4),
|
||||
});
|
||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
tonemappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "sat",
|
||||
.uniformLength = sizeof(float),
|
||||
});
|
||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
tonemappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "hdrInputTexture",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
});
|
||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
tonemappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "hdrSampler",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
|
||||
});
|
||||
layout->create();
|
||||
pipelineLayout = graphics->createPipelineLayout("ToneMappingLayout");
|
||||
pipelineLayout->addDescriptorLayout(layout);
|
||||
tonemappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "averageLuminance",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
tonemappingLayout->create();
|
||||
tonemappingPipelineLayout = graphics->createPipelineLayout("ToneMappingLayout");
|
||||
tonemappingPipelineLayout->addDescriptorLayout(tonemappingLayout);
|
||||
|
||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||
.name = "ToneMapping",
|
||||
.modules = {"FullScreenQuad", "ToneMapping"},
|
||||
.entryPoints = {{"quadMain", "FullScreenQuad"}, {"toneMapping", "ToneMapping"}},
|
||||
.rootSignature = pipelineLayout,
|
||||
.entryPoints =
|
||||
{
|
||||
{"quadMain", "FullScreenQuad"},
|
||||
{"toneMapping", "ToneMapping"},
|
||||
},
|
||||
.rootSignature = tonemappingPipelineLayout,
|
||||
});
|
||||
pipelineLayout->create();
|
||||
tonemappingPipelineLayout->create();
|
||||
vert = graphics->createVertexShader({0});
|
||||
frag = graphics->createFragmentShader({1});
|
||||
|
||||
histogramLayout = graphics->createDescriptorLayout("pHistogramParams");
|
||||
histogramLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "minLogLum",
|
||||
.uniformLength = sizeof(float),
|
||||
});
|
||||
histogramLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "inverseLogLumRange",
|
||||
.uniformLength = sizeof(float),
|
||||
});
|
||||
histogramLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "timeCoeff",
|
||||
.uniformLength = sizeof(float),
|
||||
});
|
||||
histogramLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "numPixels",
|
||||
.uniformLength = sizeof(uint32),
|
||||
});
|
||||
histogramLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "hdrImage",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
});
|
||||
histogramLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "histogram",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
histogramLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "averageLuminance",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
histogramLayout->create();
|
||||
histogramPipelineLayout = graphics->createPipelineLayout("HistogramPipelineLayout");
|
||||
histogramPipelineLayout->addDescriptorLayout(histogramLayout);
|
||||
|
||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||
.name = "Exposure",
|
||||
.modules = {"Exposure"},
|
||||
.entryPoints =
|
||||
{
|
||||
{"histogram", "Exposure"},
|
||||
{"exposure", "Exposure"},
|
||||
},
|
||||
.rootSignature = histogramPipelineLayout,
|
||||
});
|
||||
histogramPipelineLayout->create();
|
||||
histogramShader = graphics->createComputeShader({0});
|
||||
histogramPipeline = graphics->createComputePipeline(Gfx::ComputePipelineCreateInfo{
|
||||
.computeShader = histogramShader,
|
||||
.pipelineLayout = histogramPipelineLayout,
|
||||
});
|
||||
exposureShader = graphics->createComputeShader({1});
|
||||
exposurePipeline = graphics->createComputePipeline(Gfx::ComputePipelineCreateInfo{
|
||||
.computeShader = exposureShader,
|
||||
.pipelineLayout = histogramPipelineLayout,
|
||||
});
|
||||
histogramBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(uint32) * 256,
|
||||
},
|
||||
.name = "HistogramBuffer",
|
||||
});
|
||||
luminanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(uint32),
|
||||
},
|
||||
.name = "LuminanceBuffer",
|
||||
});
|
||||
sampler = graphics->createSampler({});
|
||||
}
|
||||
|
||||
@@ -50,18 +128,56 @@ void ToneMappingPass::beginFrame(const Component::Camera& cam) { RenderPass::beg
|
||||
void ToneMappingPass::render() {
|
||||
hdrInputTexture.getTexture()->changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
|
||||
layout->reset();
|
||||
set = layout->allocateDescriptorSet();
|
||||
set->updateTexture("hdrInputTexture", 0, hdrInputTexture.getTexture());
|
||||
set->updateSampler("hdrSampler", 0, sampler);
|
||||
set->writeChanges();
|
||||
histogramLayout->reset();
|
||||
Gfx::PDescriptorSet histogramSet = histogramLayout->allocateDescriptorSet();
|
||||
histogramSet->updateConstants("minLogLum", 0, &minLogLum);
|
||||
histogramSet->updateConstants("inverseLogLumRange", 0, &inverseLogLumRange);
|
||||
histogramSet->updateConstants("timeCoeff", 0, &timeCoeff);
|
||||
histogramSet->updateConstants("numPixels", 0, &numPixels);
|
||||
histogramSet->updateTexture("hdrImage", 0, hdrInputTexture.getTexture());
|
||||
histogramSet->updateBuffer("histogram", 0, histogramBuffer);
|
||||
histogramSet->updateBuffer("averageLuminance", 0, luminanceBuffer);
|
||||
histogramSet->writeChanges();
|
||||
|
||||
{
|
||||
Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("HistogramCommand");
|
||||
computeCommand->bindPipeline(histogramPipeline);
|
||||
computeCommand->bindDescriptor({histogramSet});
|
||||
computeCommand->dispatch(threadGroups.x, threadGroups.y, 1);
|
||||
graphics->executeCommands(std::move(computeCommand));
|
||||
}
|
||||
histogramBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
{
|
||||
Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("ExposureCommand");
|
||||
computeCommand->bindPipeline(exposurePipeline);
|
||||
computeCommand->bindDescriptor({histogramSet});
|
||||
computeCommand->dispatch(1, 1, 1);
|
||||
graphics->executeCommands(std::move(computeCommand));
|
||||
}
|
||||
luminanceBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
|
||||
tonemappingLayout->reset();
|
||||
Gfx::PDescriptorSet tonemappingSet = tonemappingLayout->allocateDescriptorSet();
|
||||
tonemappingSet->updateConstants("offset", 0, &offset);
|
||||
tonemappingSet->updateConstants("slope", 0, &slope);
|
||||
tonemappingSet->updateConstants("power", 0, &power);
|
||||
tonemappingSet->updateConstants("sat", 0, &sat);
|
||||
tonemappingSet->updateTexture("hdrInputTexture", 0, hdrInputTexture.getTexture());
|
||||
tonemappingSet->updateSampler("hdrSampler", 0, sampler);
|
||||
tonemappingSet->updateBuffer("averageLuminance", 0, luminanceBuffer);
|
||||
tonemappingSet->writeChanges();
|
||||
graphics->beginRenderPass(renderPass);
|
||||
Gfx::ORenderCommand command = graphics->createRenderCommand("ToneMapping");
|
||||
command->setViewport(viewport);
|
||||
command->bindPipeline(pipeline);
|
||||
command->bindDescriptor({set});
|
||||
command->bindDescriptor({tonemappingSet});
|
||||
command->draw(3, 1, 0, 0);
|
||||
graphics->executeCommands(std::move(command));
|
||||
graphics->endRenderPass();
|
||||
@@ -70,6 +186,8 @@ void ToneMappingPass::render() {
|
||||
void ToneMappingPass::endFrame() {}
|
||||
|
||||
void ToneMappingPass::publishOutputs() {
|
||||
numPixels = viewport->getWidth() * viewport->getHeight();
|
||||
threadGroups = UVector2((viewport->getWidth() + 15) / 16, (viewport->getHeight() + 15) / 16);
|
||||
colorAttachment = Gfx::RenderTargetAttachment(viewport, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
resources->registerRenderPassOutput("TONEMAPPING_COLOR", colorAttachment);
|
||||
@@ -103,7 +221,7 @@ void ToneMappingPass::createRenderPass() {
|
||||
.vertexShader = vert,
|
||||
.fragmentShader = frag,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = pipelineLayout,
|
||||
.pipelineLayout = tonemappingPipelineLayout,
|
||||
.colorBlend =
|
||||
{
|
||||
.attachmentCount = 1,
|
||||
|
||||
@@ -19,13 +19,31 @@ class ToneMappingPass : public RenderPass {
|
||||
private:
|
||||
// non-hdr swapchain output
|
||||
Gfx::RenderTargetAttachment colorAttachment;
|
||||
Gfx::OShaderBuffer histogramBuffer;
|
||||
Gfx::OShaderBuffer luminanceBuffer;
|
||||
|
||||
float minLogLum = 1;
|
||||
float inverseLogLumRange = 1;
|
||||
float timeCoeff = 1;
|
||||
uint32 numPixels;
|
||||
UVector2 threadGroups;
|
||||
Gfx::ODescriptorLayout histogramLayout;
|
||||
Gfx::PDescriptorSet histogramSet;
|
||||
Gfx::OPipelineLayout histogramPipelineLayout;
|
||||
Gfx::OComputeShader histogramShader;
|
||||
Gfx::PComputePipeline histogramPipeline;
|
||||
Gfx::OComputeShader exposureShader;
|
||||
Gfx::PComputePipeline exposurePipeline;
|
||||
|
||||
Gfx::RenderTargetAttachment hdrInputTexture;
|
||||
Gfx::OSampler sampler;
|
||||
|
||||
Gfx::ODescriptorLayout layout;
|
||||
Gfx::PDescriptorSet set;
|
||||
Gfx::OPipelineLayout pipelineLayout;
|
||||
Vector4 offset = Vector4(0.0);
|
||||
Vector4 slope = Vector4(1.0);
|
||||
Vector4 power = Vector4(1.0);
|
||||
float sat = 1.0;
|
||||
Gfx::ODescriptorLayout tonemappingLayout;
|
||||
Gfx::OPipelineLayout tonemappingPipelineLayout;
|
||||
Gfx::OVertexShader vert;
|
||||
Gfx::OFragmentShader frag;
|
||||
Gfx::PGraphicsPipeline pipeline;
|
||||
|
||||
Reference in New Issue
Block a user