Skip to content
Snippets Groups Projects
Verified Commit 2ac8270a authored by Tobias Frisch's avatar Tobias Frisch
Browse files

Add tone mapping module and gamma correction effect

parent d48d3576
No related branches found
No related tags found
1 merge request!113Resolve "Tone mapping module"
Showing
with 529 additions and 3 deletions
......@@ -46,3 +46,6 @@
[submodule "lib/VulkanMemoryAllocator"]
path = lib/VulkanMemoryAllocator
url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
[submodule "modules/tone_mapping/lib/glsl-tone-map"]
path = modules/tone_mapping/lib/glsl-tone-map
url = https://github.com/dmnsgn/glsl-tone-map.git
......@@ -13,6 +13,7 @@ add_subdirectory(material)
add_subdirectory(meshlet)
add_subdirectory(scene)
add_subdirectory(shader_compiler)
add_subdirectory(tone_mapping)
add_subdirectory(upscaling)
message(STATUS "Modules:")
......
......@@ -14,6 +14,9 @@ set(vkcv_effects_sources
${vkcv_effects_include}/vkcv/effects/BloomAndFlaresEffect.hpp
${vkcv_effects_source}/vkcv/effects/BloomAndFlaresEffect.cpp
${vkcv_effects_include}/vkcv/effects/GammaCorrectionEffect.hpp
${vkcv_effects_source}/vkcv/effects/GammaCorrectionEffect.cpp
)
filter_headers(vkcv_effects_sources ${vkcv_effects_include} vkcv_effects_headers)
......@@ -23,16 +26,19 @@ set(vkcv_effects_shaders ${PROJECT_SOURCE_DIR}/shaders)
include_shader(${vkcv_effects_shaders}/bloomDownsample.comp ${vkcv_effects_include} ${vkcv_effects_source})
include_shader(${vkcv_effects_shaders}/bloomFlaresComposite.comp ${vkcv_effects_include} ${vkcv_effects_source})
include_shader(${vkcv_effects_shaders}/bloomUpsample.comp ${vkcv_effects_include} ${vkcv_effects_source})
include_shader(${vkcv_effects_shaders}/gammaCorrection.comp ${vkcv_effects_include} ${vkcv_effects_source})
include_shader(${vkcv_effects_shaders}/lensFlares.comp ${vkcv_effects_include} ${vkcv_effects_source})
list(APPEND vkcv_effects_sources ${vkcv_effects_source}/bloomDownsample.comp.cxx)
list(APPEND vkcv_effects_sources ${vkcv_effects_source}/bloomFlaresComposite.comp.cxx)
list(APPEND vkcv_effects_sources ${vkcv_effects_source}/bloomUpsample.comp.cxx)
list(APPEND vkcv_effects_sources ${vkcv_effects_source}/gammaCorrection.comp.cxx)
list(APPEND vkcv_effects_sources ${vkcv_effects_source}/lensFlares.comp.cxx)
list(APPEND vkcv_effects_sources ${vkcv_effects_include}/bloomDownsample.comp.hxx)
list(APPEND vkcv_effects_sources ${vkcv_effects_include}/bloomFlaresComposite.comp.hxx)
list(APPEND vkcv_effects_sources ${vkcv_effects_include}/bloomUpsample.comp.hxx)
list(APPEND vkcv_effects_sources ${vkcv_effects_include}/gammaCorrection.comp.hxx)
list(APPEND vkcv_effects_sources ${vkcv_effects_include}/lensFlares.comp.hxx)
# adding source files to the project
......@@ -40,10 +46,21 @@ add_library(vkcv_effects ${vkcv_build_attribute} ${vkcv_effects_sources})
set_target_properties(vkcv_effects PROPERTIES PUBLIC_HEADER "${vkcv_effects_headers}")
# link the required libraries to the module
target_link_libraries(vkcv_effects ${vkcv_effects_libraries} vkcv vkcv_shader_compiler vkcv_camera vkcv_asset_loader)
target_link_libraries(vkcv_effects
${vkcv_effects_libraries}
vkcv
vkcv_shader_compiler
vkcv_camera
vkcv_asset_loader)
# including headers of dependencies and the VkCV framework
target_include_directories(vkcv_effects SYSTEM BEFORE PRIVATE ${vkcv_effects_includes} ${vkcv_include} ${vkcv_includes} ${vkcv_shader_compiler_include} ${vkcv_camera_include} {vkcv_asset_loader_include})
target_include_directories(vkcv_effects SYSTEM BEFORE PRIVATE
${vkcv_effects_includes}
${vkcv_include}
${vkcv_includes}
${vkcv_shader_compiler_include}
${vkcv_camera_include}
${vkcv_asset_loader_include})
# add the own include directory for public headers
target_include_directories(vkcv_effects BEFORE PUBLIC ${vkcv_effects_include})
......
#pragma once
#include "Effect.hpp"
namespace vkcv::effects {
class GammaCorrectionEffect : public Effect {
private:
float m_gamma;
ComputePipelineHandle m_pipeline;
DescriptorSetLayoutHandle m_descriptorSetLayout;
DescriptorSetHandle m_descriptorSet;
public:
GammaCorrectionEffect(Core& core);
void recordEffect(const CommandStreamHandle& cmdStream,
const ImageHandle& input,
const ImageHandle& output) override;
void setGamma(float gamma);
float getGamma() const;
};
}
#version 450
layout(set=0, binding=0, rgba8) restrict readonly uniform image2D inImage;
layout(set=0, binding=1, rgba8) restrict writeonly uniform image2D outImage;
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
layout( push_constant ) uniform constants {
float gamma;
};
void main() {
if (any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(inImage)))) {
return;
}
if (any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(outImage)))) {
return;
}
ivec2 uv = ivec2(gl_GlobalInvocationID.xy);
vec3 color = imageLoad(inImage, uv).xyz;
color = pow(color, vec3(1.0f / gamma));
imageStore(outImage, uv, vec4(color, 0.f));
}
\ No newline at end of file
#include "vkcv/effects/GammaCorrectionEffect.hpp"
#include <vkcv/shader/GLSLCompiler.hpp>
#include "gammaCorrection.comp.hxx"
namespace vkcv::effects {
static DescriptorBindings getDescriptorBindings() {
DescriptorBindings descriptorBindings = {};
auto binding_0 = DescriptorBinding {
0,
DescriptorType::IMAGE_STORAGE,
1,
ShaderStage::COMPUTE,
false,
false
};
auto binding_1 = DescriptorBinding {
1,
DescriptorType::IMAGE_STORAGE,
1,
ShaderStage::COMPUTE,
false,
false
};
descriptorBindings.insert(std::make_pair(0, binding_0));
descriptorBindings.insert(std::make_pair(1, binding_1));
return descriptorBindings;
}
GammaCorrectionEffect::GammaCorrectionEffect(Core &core)
: Effect(core), m_gamma(2.2f), m_descriptorSetLayout(), m_descriptorSet(), m_pipeline() {
vkcv::shader::GLSLCompiler compiler;
ShaderProgram program;
compiler.compileSource(
ShaderStage::COMPUTE,
GAMMACORRECTION_COMP_SHADER.c_str(),
[&program](ShaderStage stage, const std::filesystem::path &path) {
program.addShader(stage, path);
}
);
m_descriptorSetLayout = m_core.createDescriptorSetLayout(getDescriptorBindings());
m_descriptorSet = m_core.createDescriptorSet(m_descriptorSetLayout);
m_pipeline = m_core.createComputePipeline({
program,
{ m_descriptorSetLayout }
});
}
void GammaCorrectionEffect::recordEffect(const CommandStreamHandle &cmdStream,
const ImageHandle &input,
const ImageHandle &output) {
m_core.recordBeginDebugLabel(cmdStream, "Gamma Correction", std::array<float, 4>{
0.95f, 0.95f, 0.95f, 1.0f
});
m_core.prepareImageForStorage(cmdStream, input);
m_core.prepareImageForStorage(cmdStream, output);
vkcv::DescriptorWrites writes;
writes.writeStorageImage(0, input);
writes.writeStorageImage(1, output);
m_core.writeDescriptorSet(m_descriptorSet, writes);
const uint32_t width = m_core.getImageWidth(output);
const uint32_t height = m_core.getImageHeight(output);
m_core.recordComputeDispatchToCmdStream(
cmdStream,
m_pipeline,
dispatchInvocations(
DispatchSize(width, height),
DispatchSize(8, 8)
),
{ useDescriptorSet(0, m_descriptorSet) },
pushConstants<float>(m_gamma)
);
m_core.recordEndDebugLabel(cmdStream);
}
void GammaCorrectionEffect::setGamma(float gamma) {
m_gamma = std::max(gamma, std::numeric_limits<float>::epsilon());
}
float GammaCorrectionEffect::getGamma() const {
return m_gamma;
}
}
......@@ -76,7 +76,7 @@ namespace vkcv::shader {
*/
bool compileSource(ShaderStage shaderStage, const char* shaderSource,
const ShaderCompiledFunction& compiled,
const std::filesystem::path& includePath) override;
const std::filesystem::path& includePath = "") override;
/**
* Compile a GLSL shader from a specific file path for a target stage with
......
cmake_minimum_required(VERSION 3.16)
project(vkcv_tone_mapping)
# setting c++ standard for the project
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(vkcv_tone_mapping_source ${PROJECT_SOURCE_DIR}/src)
set(vkcv_tone_mapping_include ${PROJECT_SOURCE_DIR}/include)
set(vkcv_tone_mapping_sources
${vkcv_tone_mapping_include}/vkcv/tone/ToneMapping.hpp
${vkcv_tone_mapping_source}/vkcv/tone/ToneMapping.cpp
${vkcv_tone_mapping_include}/vkcv/tone/ACESToneMapping.hpp
${vkcv_tone_mapping_source}/vkcv/tone/ACESToneMapping.cpp
${vkcv_tone_mapping_include}/vkcv/tone/FilmicToneMapping.hpp
${vkcv_tone_mapping_source}/vkcv/tone/FilmicToneMapping.cpp
${vkcv_tone_mapping_include}/vkcv/tone/LottesToneMapping.hpp
${vkcv_tone_mapping_source}/vkcv/tone/LottesToneMapping.cpp
${vkcv_tone_mapping_include}/vkcv/tone/ReinhardToneMapping.hpp
${vkcv_tone_mapping_source}/vkcv/tone/ReinhardToneMapping.cpp
${vkcv_tone_mapping_include}/vkcv/tone/Reinhard2ToneMapping.hpp
${vkcv_tone_mapping_source}/vkcv/tone/Reinhard2ToneMapping.cpp
${vkcv_tone_mapping_include}/vkcv/tone/UchimuraToneMapping.hpp
${vkcv_tone_mapping_source}/vkcv/tone/UchimuraToneMapping.cpp
${vkcv_tone_mapping_include}/vkcv/tone/Uncharted2ToneMapping.hpp
${vkcv_tone_mapping_source}/vkcv/tone/Uncharted2ToneMapping.cpp
${vkcv_tone_mapping_include}/vkcv/tone/UnrealToneMapping.hpp
${vkcv_tone_mapping_source}/vkcv/tone/UnrealToneMapping.cpp
)
filter_headers(vkcv_tone_mapping_sources ${vkcv_tone_mapping_include} vkcv_tone_mapping_headers)
# Setup some path variables to load libraries
set(vkcv_tone_mapping_lib lib)
set(vkcv_tone_mapping_lib_path ${PROJECT_SOURCE_DIR}/${vkcv_tone_mapping_lib})
# Check and load glsl-tone-map
include(config/GLSL_TONE_MAP.cmake)
# Add compile definitions depending on the build context of the module
add_compile_definitions(${vkcv_tone_mapping_definitions})
# adding source files to the project
add_library(vkcv_tone_mapping ${vkcv_build_attribute} ${vkcv_tone_mapping_sources})
set_target_properties(vkcv_tone_mapping PROPERTIES PUBLIC_HEADER "${vkcv_tone_mapping_headers}")
# link the required libraries to the module
target_link_libraries(vkcv_tone_mapping
${vkcv_tone_mapping_libraries}
vkcv
vkcv_shader_compiler
)
# including headers of dependencies and the VkCV framework
target_include_directories(vkcv_tone_mapping SYSTEM BEFORE PRIVATE
${vkcv_tone_mapping_includes}
${vkcv_include}
${vkcv_includes}
${vkcv_shader_compiler_include}
)
# add the own include directory for public headers
target_include_directories(vkcv_tone_mapping BEFORE PUBLIC ${vkcv_tone_mapping_include})
if (vkcv_parent_scope)
list(APPEND vkcv_modules_includes ${vkcv_tone_mapping_include})
list(APPEND vkcv_modules_libraries vkcv_tone_mapping)
set(vkcv_modules_includes ${vkcv_modules_includes} PARENT_SCOPE)
set(vkcv_modules_libraries ${vkcv_modules_libraries} PARENT_SCOPE)
endif()
install(TARGETS vkcv_tone_mapping PUBLIC_HEADER DESTINATION
${CMAKE_INSTALL_INCLUDEDIR}/vkcv/tone)
use_git_submodule("${vkcv_tone_mapping_lib_path}/glsl-tone-map" glsl_tone_map_status)
if (${glsl_tone_map_status})
include_shader(${vkcv_tone_mapping_lib_path}/glsl-tone-map/aces.glsl
${vkcv_tone_mapping_include}
${vkcv_tone_mapping_source})
include_shader(${vkcv_tone_mapping_lib_path}/glsl-tone-map/filmic.glsl
${vkcv_tone_mapping_include}
${vkcv_tone_mapping_source})
include_shader(${vkcv_tone_mapping_lib_path}/glsl-tone-map/lottes.glsl
${vkcv_tone_mapping_include}
${vkcv_tone_mapping_source})
include_shader(${vkcv_tone_mapping_lib_path}/glsl-tone-map/reinhard.glsl
${vkcv_tone_mapping_include}
${vkcv_tone_mapping_source})
include_shader(${vkcv_tone_mapping_lib_path}/glsl-tone-map/reinhard2.glsl
${vkcv_tone_mapping_include}
${vkcv_tone_mapping_source})
include_shader(${vkcv_tone_mapping_lib_path}/glsl-tone-map/uchimura.glsl
${vkcv_tone_mapping_include}
${vkcv_tone_mapping_source})
include_shader(${vkcv_tone_mapping_lib_path}/glsl-tone-map/uncharted2.glsl
${vkcv_tone_mapping_include}
${vkcv_tone_mapping_source})
include_shader(${vkcv_tone_mapping_lib_path}/glsl-tone-map/unreal.glsl
${vkcv_tone_mapping_include}
${vkcv_tone_mapping_source})
list(APPEND vkcv_tone_mapping_sources ${vkcv_tone_mapping_source}/aces.glsl.cxx)
list(APPEND vkcv_tone_mapping_sources ${vkcv_tone_mapping_source}/filmic.glsl.cxx)
list(APPEND vkcv_tone_mapping_sources ${vkcv_tone_mapping_source}/lottes.glsl.cxx)
list(APPEND vkcv_tone_mapping_sources ${vkcv_tone_mapping_source}/reinhard.glsl.cxx)
list(APPEND vkcv_tone_mapping_sources ${vkcv_tone_mapping_source}/reinhard2.glsl.cxx)
list(APPEND vkcv_tone_mapping_sources ${vkcv_tone_mapping_source}/uchimura.glsl.cxx)
list(APPEND vkcv_tone_mapping_sources ${vkcv_tone_mapping_source}/uncharted2.glsl.cxx)
list(APPEND vkcv_tone_mapping_sources ${vkcv_tone_mapping_source}/unreal.glsl.cxx)
list(APPEND vkcv_tone_mapping_sources ${vkcv_tone_mapping_include}/aces.glsl.hxx)
list(APPEND vkcv_tone_mapping_sources ${vkcv_tone_mapping_include}/filmic.glsl.hxx)
list(APPEND vkcv_tone_mapping_sources ${vkcv_tone_mapping_include}/lottes.glsl.hxx)
list(APPEND vkcv_tone_mapping_sources ${vkcv_tone_mapping_include}/reinhard.glsl.hxx)
list(APPEND vkcv_tone_mapping_sources ${vkcv_tone_mapping_include}/reinhard2.glsl.hxx)
list(APPEND vkcv_tone_mapping_sources ${vkcv_tone_mapping_include}/uchimura.glsl.hxx)
list(APPEND vkcv_tone_mapping_sources ${vkcv_tone_mapping_include}/uncharted2.glsl.hxx)
list(APPEND vkcv_tone_mapping_sources ${vkcv_tone_mapping_include}/unreal.glsl.hxx)
endif()
#pragma once
#include "ToneMapping.hpp"
namespace vkcv::tone {
class ACESToneMapping : public ToneMapping {
private:
void initToneMapping() override;
public:
explicit ACESToneMapping(Core& core);
};
}
#pragma once
#include "ToneMapping.hpp"
namespace vkcv::tone {
class FilmicToneMapping : public ToneMapping {
private:
void initToneMapping() override;
public:
explicit FilmicToneMapping(Core& core);
};
}
#pragma once
#include "ToneMapping.hpp"
namespace vkcv::tone {
class LottesToneMapping : public ToneMapping {
private:
void initToneMapping() override;
public:
explicit LottesToneMapping(Core& core);
};
}
#pragma once
#include "ToneMapping.hpp"
namespace vkcv::tone {
class Reinhard2ToneMapping : public ToneMapping {
private:
void initToneMapping() override;
public:
explicit Reinhard2ToneMapping(Core& core);
};
}
#pragma once
#include "ToneMapping.hpp"
namespace vkcv::tone {
class ReinhardToneMapping : public ToneMapping {
private:
void initToneMapping() override;
public:
explicit ReinhardToneMapping(Core& core);
};
}
#pragma once
#include <vkcv/Core.hpp>
namespace vkcv::tone {
class ToneMapping {
private:
/**
* Reference to the current Core instance.
*/
Core& m_core;
std::string m_name;
ComputePipelineHandle m_pipeline;
/**
* The descriptor set layout of the tone mapping pipeline.
*/
DescriptorSetLayoutHandle m_descriptorSetLayout;
/**
* The descriptor set for the tone mapping pipeline.
*/
DescriptorSetHandle m_descriptorSet;
protected:
ShaderProgram compileShaderProgram(const std::string& functionName,
const std::string& functionSource);
void buildComputePipeline(const std::string& functionName,
const std::string& functionSource);
virtual void initToneMapping() = 0;
public:
/**
* Constructor to create an tone mapping instance.
*
* @param[in,out] core Reference to a Core instance
* @param[in] name Name of the tone mapping function
*/
explicit ToneMapping(Core& core, const std::string& name);
~ToneMapping() = default;
[[nodiscard]]
const std::string& getName() const;
/**
* Record the commands of the given tone mapping instance to
* process the image of the input handle mapping its colors into
* the regarding output image handle.
*
* @param[in] cmdStream Command stream handle to record commands
* @param[in] input Input image handle
* @param[in] output Output image handle
*/
void recordToneMapping(const CommandStreamHandle& cmdStream,
const ImageHandle& input,
const ImageHandle& output);
};
}
#pragma once
#include "ToneMapping.hpp"
namespace vkcv::tone {
class UchimuraToneMapping : public ToneMapping {
private:
void initToneMapping() override;
public:
explicit UchimuraToneMapping(Core& core);
};
}
#pragma once
#include "ToneMapping.hpp"
namespace vkcv::tone {
class Uncharted2ToneMapping : public ToneMapping {
private:
void initToneMapping() override;
public:
explicit Uncharted2ToneMapping(Core& core);
};
}
#pragma once
#include "ToneMapping.hpp"
namespace vkcv::tone {
class UnrealToneMapping : public ToneMapping {
private:
void initToneMapping() override;
public:
explicit UnrealToneMapping(Core& core);
};
}
Subproject commit e3d822adee738de936da5d9541dff266f899ed46
#include "vkcv/tone/ACESToneMapping.hpp"
#include "aces.glsl.hxx"
namespace vkcv::tone {
void ACESToneMapping::initToneMapping() {
buildComputePipeline("aces", ACES_GLSL_SHADER);
}
ACESToneMapping::ACESToneMapping(Core &core) : ToneMapping(core, "ACES Tone Mapping") {
initToneMapping();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment