Skip to content
Snippets Groups Projects
Commit 401ed7ad authored by Alexander Gauggel's avatar Alexander Gauggel
Browse files

[#106] Add gamma correction

parent fe4da00f
No related branches found
No related tags found
1 merge request!89Resolve "Indirect Dispatch"
Pipeline #26636 failed
This commit is part of merge request !89. Comments created here will be created in the context of that merge request.
#version 440
#extension GL_GOOGLE_include_directive : enable
layout(set=0, binding=0) uniform texture2D inTexture;
layout(set=0, binding=1) uniform sampler textureSampler;
layout(set=0, binding=2, rgba8) uniform image2D outImage;
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
void main(){
if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(outImage))))
return;
ivec2 textureRes = textureSize(sampler2D(inTexture, textureSampler), 0);
ivec2 coord = ivec2(gl_GlobalInvocationID.xy);
vec2 uv = vec2(coord) / textureRes;
vec3 linearColor = texture(sampler2D(inTexture, textureSampler), uv).rgb;
vec3 gammaCorrected = pow(linearColor, vec3(1 / 2.2));
imageStore(outImage, coord, vec4(gammaCorrected, 0.f));
}
\ No newline at end of file
...@@ -31,12 +31,21 @@ bool App::initialize() { ...@@ -31,12 +31,21 @@ bool App::initialize() {
if (!loadSkyPass(m_core, &m_skyPassHandles)) if (!loadSkyPass(m_core, &m_skyPassHandles))
return false; return false;
if (!loadComputePass(m_core, "resources/shaders/gammaCorrection.comp", &m_gammaCorrectionPass))
return false;
if (!loadMesh(m_core, "resources/models/sphere.gltf", & m_sphereMesh)) if (!loadMesh(m_core, "resources/models/sphere.gltf", & m_sphereMesh))
return false; return false;
if (!loadMesh(m_core, "resources/models/cube.gltf", &m_cubeMesh)) if (!loadMesh(m_core, "resources/models/cube.gltf", &m_cubeMesh))
return false; return false;
m_linearSampler = m_core.createSampler(
vkcv::SamplerFilterType::LINEAR,
vkcv::SamplerFilterType::LINEAR,
vkcv::SamplerMipmapMode::LINEAR,
vkcv::SamplerAddressMode::CLAMP_TO_EDGE);
m_renderTargets = createRenderTargets(m_core, m_windowWidth, m_windowHeight); m_renderTargets = createRenderTargets(m_core, m_windowWidth, m_windowHeight);
const int cameraIndex = m_cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); const int cameraIndex = m_cameraManager.addCamera(vkcv::camera::ControllerType::PILOT);
...@@ -85,8 +94,11 @@ void App::run() { ...@@ -85,8 +94,11 @@ void App::run() {
m_cameraManager.update(0.000001 * static_cast<double>(deltatime.count())); m_cameraManager.update(0.000001 * static_cast<double>(deltatime.count()));
const glm::mat4 viewProjection = m_cameraManager.getActiveCamera().getMVP(); const glm::mat4 viewProjection = m_cameraManager.getActiveCamera().getMVP();
const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, m_renderTargets.depthBuffer }; const std::vector<vkcv::ImageHandle> renderTargets = {
const vkcv::CommandStreamHandle cmdStream = m_core.createCommandStream(vkcv::QueueType::Graphics); m_renderTargets.colorBuffer,
m_renderTargets.depthBuffer };
const vkcv::CommandStreamHandle cmdStream = m_core.createCommandStream(vkcv::QueueType::Graphics);
vkcv::PushConstants meshPushConstants(sizeof(glm::mat4)); vkcv::PushConstants meshPushConstants(sizeof(glm::mat4));
meshPushConstants.appendDrawcall(viewProjection); meshPushConstants.appendDrawcall(viewProjection);
...@@ -110,6 +122,32 @@ void App::run() { ...@@ -110,6 +122,32 @@ void App::run() {
{ cubeDrawcall }, { cubeDrawcall },
renderTargets); renderTargets);
vkcv::DescriptorWrites gammaCorrectionDescriptorWrites;
gammaCorrectionDescriptorWrites.sampledImageWrites = {
vkcv::SampledImageDescriptorWrite(0, m_renderTargets.colorBuffer) };
gammaCorrectionDescriptorWrites.samplerWrites = {
vkcv::SamplerDescriptorWrite(1, m_linearSampler) };
gammaCorrectionDescriptorWrites.storageImageWrites = {
vkcv::StorageImageDescriptorWrite(2, swapchainInput) };
m_core.writeDescriptorSet(m_gammaCorrectionPass.descriptorSet, gammaCorrectionDescriptorWrites);
m_core.prepareImageForSampling(cmdStream, m_renderTargets.colorBuffer);
m_core.prepareImageForStorage (cmdStream, swapchainInput);
uint32_t gammaCorrectionDispatch[3] = {
(m_windowWidth + 7) / 8,
(m_windowHeight + 7) / 8,
1
};
m_core.recordComputeDispatchToCmdStream(
cmdStream,
m_gammaCorrectionPass.pipeline,
gammaCorrectionDispatch,
{ vkcv::DescriptorSetUsage(0, m_core.getDescriptorSet(m_gammaCorrectionPass.descriptorSet).vulkanHandle) },
vkcv::PushConstants(0));
m_core.prepareSwapchainImageForPresent(cmdStream); m_core.prepareSwapchainImageForPresent(cmdStream);
m_core.submitCommandStream(cmdStream); m_core.submitCommandStream(cmdStream);
m_core.endFrame(); m_core.endFrame();
......
...@@ -25,5 +25,8 @@ private: ...@@ -25,5 +25,8 @@ private:
GraphicPassHandles m_meshPassHandles; GraphicPassHandles m_meshPassHandles;
GraphicPassHandles m_skyPassHandles; GraphicPassHandles m_skyPassHandles;
RenderTargets m_renderTargets; ComputePassHandles m_gammaCorrectionPass;
RenderTargets m_renderTargets;
vkcv::SamplerHandle m_linearSampler;
}; };
\ No newline at end of file
...@@ -5,4 +5,5 @@ namespace AppConfig{ ...@@ -5,4 +5,5 @@ namespace AppConfig{
const int defaultWindowWidth = 1280; const int defaultWindowWidth = 1280;
const int defaultWindowHeight = 720; const int defaultWindowHeight = 720;
const vk::Format depthBufferFormat = vk::Format::eD32Sfloat; const vk::Format depthBufferFormat = vk::Format::eD32Sfloat;
const vk::Format colorBufferFormat = vk::Format::eB10G11R11UfloatPack32;
} }
\ No newline at end of file
...@@ -117,7 +117,7 @@ bool loadMeshPass(vkcv::Core& core, GraphicPassHandles* outHandles) { ...@@ -117,7 +117,7 @@ bool loadMeshPass(vkcv::Core& core, GraphicPassHandles* outHandles) {
vkcv::AttachmentDescription colorAttachment( vkcv::AttachmentDescription colorAttachment(
vkcv::AttachmentOperation::STORE, vkcv::AttachmentOperation::STORE,
vkcv::AttachmentOperation::CLEAR, vkcv::AttachmentOperation::CLEAR,
core.getSwapchain().getFormat()); AppConfig::colorBufferFormat);
vkcv::AttachmentDescription depthAttachment( vkcv::AttachmentDescription depthAttachment(
vkcv::AttachmentOperation::STORE, vkcv::AttachmentOperation::STORE,
...@@ -139,7 +139,7 @@ bool loadSkyPass(vkcv::Core& core, GraphicPassHandles* outHandles) { ...@@ -139,7 +139,7 @@ bool loadSkyPass(vkcv::Core& core, GraphicPassHandles* outHandles) {
vkcv::AttachmentDescription colorAttachment( vkcv::AttachmentDescription colorAttachment(
vkcv::AttachmentOperation::STORE, vkcv::AttachmentOperation::STORE,
vkcv::AttachmentOperation::LOAD, vkcv::AttachmentOperation::LOAD,
core.getSwapchain().getFormat()); AppConfig::colorBufferFormat);
vkcv::AttachmentDescription depthAttachment( vkcv::AttachmentDescription depthAttachment(
vkcv::AttachmentOperation::DONT_CARE, vkcv::AttachmentOperation::DONT_CARE,
...@@ -154,6 +154,36 @@ bool loadSkyPass(vkcv::Core& core, GraphicPassHandles* outHandles) { ...@@ -154,6 +154,36 @@ bool loadSkyPass(vkcv::Core& core, GraphicPassHandles* outHandles) {
outHandles); outHandles);
} }
bool loadComputePass(vkcv::Core& core, const std::filesystem::path& path, ComputePassHandles* outComputePass) {
assert(outComputePass);
vkcv::ShaderProgram shaderProgram;
vkcv::shader::GLSLCompiler compiler;
compiler.compile(vkcv::ShaderStage::COMPUTE, path,
[&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
shaderProgram.addShader(shaderStage, path);
});
if (shaderProgram.getReflectedDescriptors().size() < 1) {
vkcv_log(vkcv::LogLevel::ERROR, "Compute shader has no descriptor set");
return false;
}
outComputePass->descriptorSet = core.createDescriptorSet(shaderProgram.getReflectedDescriptors()[0]);
outComputePass->pipeline = core.createComputePipeline(
shaderProgram,
{ core.getDescriptorSet(outComputePass->descriptorSet).layout });
if (!outComputePass->pipeline) {
vkcv_log(vkcv::LogLevel::ERROR, "Compute shader pipeline creation failed");
return false;
}
return true;
}
RenderTargets createRenderTargets(vkcv::Core& core, const uint32_t width, const uint32_t height) { RenderTargets createRenderTargets(vkcv::Core& core, const uint32_t width, const uint32_t height) {
RenderTargets targets; RenderTargets targets;
...@@ -165,5 +195,14 @@ RenderTargets createRenderTargets(vkcv::Core& core, const uint32_t width, const ...@@ -165,5 +195,14 @@ RenderTargets createRenderTargets(vkcv::Core& core, const uint32_t width, const
1, 1,
false).getHandle(); false).getHandle();
targets.colorBuffer = core.createImage(
AppConfig::colorBufferFormat,
width,
height,
1,
false,
false,
true).getHandle();
return targets; return targets;
} }
\ No newline at end of file
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
struct RenderTargets { struct RenderTargets {
vkcv::ImageHandle depthBuffer; vkcv::ImageHandle depthBuffer;
vkcv::ImageHandle colorBuffer;
}; };
struct GraphicPassHandles { struct GraphicPassHandles {
...@@ -10,6 +11,11 @@ struct GraphicPassHandles { ...@@ -10,6 +11,11 @@ struct GraphicPassHandles {
vkcv::PassHandle renderPass; vkcv::PassHandle renderPass;
}; };
struct ComputePassHandles {
vkcv::PipelineHandle pipeline;
vkcv::DescriptorSetHandle descriptorSet;
};
struct MeshResources { struct MeshResources {
vkcv::Mesh mesh; vkcv::Mesh mesh;
vkcv::BufferHandle vertexBuffer; vkcv::BufferHandle vertexBuffer;
...@@ -29,4 +35,6 @@ bool loadGraphicPass( ...@@ -29,4 +35,6 @@ bool loadGraphicPass(
bool loadMeshPass(vkcv::Core& core, GraphicPassHandles* outHandles); bool loadMeshPass(vkcv::Core& core, GraphicPassHandles* outHandles);
bool loadSkyPass (vkcv::Core& core, GraphicPassHandles* outHandles); bool loadSkyPass (vkcv::Core& core, GraphicPassHandles* outHandles);
bool loadComputePass(vkcv::Core& core, const std::filesystem::path& path, ComputePassHandles* outComputePass);
RenderTargets createRenderTargets(vkcv::Core& core, const uint32_t width, const uint32_t height); RenderTargets createRenderTargets(vkcv::Core& core, const uint32_t width, const uint32_t height);
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment