diff --git a/include/vkcv/DescriptorWrites.hpp b/include/vkcv/DescriptorWrites.hpp index 00e2d9a0494aec08767ced3a12086c812f6f1451..28de2ed7fa6b7e71bfa49b67a337f80f2e05ddcf 100644 --- a/include/vkcv/DescriptorWrites.hpp +++ b/include/vkcv/DescriptorWrites.hpp @@ -20,20 +20,15 @@ namespace vkcv { uint32_t mipLevel; }; - struct UniformBufferDescriptorWrite { - inline UniformBufferDescriptorWrite(uint32_t binding, BufferHandle buffer, bool dynamic = false) : - binding(binding), buffer(buffer), dynamic(dynamic) {}; + struct BufferDescriptorWrite { + inline BufferDescriptorWrite(uint32_t binding, BufferHandle buffer, bool dynamic = false, + uint32_t offset = 0, uint32_t size = 0) : + binding(binding), buffer(buffer), dynamic(dynamic), offset(offset), size(size) {}; uint32_t binding; BufferHandle buffer; bool dynamic; - }; - - struct StorageBufferDescriptorWrite { - inline StorageBufferDescriptorWrite(uint32_t binding, BufferHandle buffer, bool dynamic = false) : - binding(binding), buffer(buffer), dynamic(dynamic) {}; - uint32_t binding; - BufferHandle buffer; - bool dynamic; + uint32_t offset; + uint32_t size; }; struct SamplerDescriptorWrite { @@ -45,8 +40,8 @@ namespace vkcv { struct DescriptorWrites { std::vector<SampledImageDescriptorWrite> sampledImageWrites; std::vector<StorageImageDescriptorWrite> storageImageWrites; - std::vector<UniformBufferDescriptorWrite> uniformBufferWrites; - std::vector<StorageBufferDescriptorWrite> storageBufferWrites; + std::vector<BufferDescriptorWrite> uniformBufferWrites; + std::vector<BufferDescriptorWrite> storageBufferWrites; std::vector<SamplerDescriptorWrite> samplerWrites; }; } \ No newline at end of file diff --git a/modules/shader_compiler/src/vkcv/shader/GLSLCompiler.cpp b/modules/shader_compiler/src/vkcv/shader/GLSLCompiler.cpp index 341e219fdbbe3ea815925e295069b8a719aca8a4..7d4bf289d8c4135ba776cfd85a270ea277aa40ed 100644 --- a/modules/shader_compiler/src/vkcv/shader/GLSLCompiler.cpp +++ b/modules/shader_compiler/src/vkcv/shader/GLSLCompiler.cpp @@ -214,26 +214,28 @@ namespace vkcv::shader { std::string source (shaderSource); - std::strstream defines; - for (const auto& define : m_defines) { - defines << "#define " << define.first << " " << define.second << std::endl; - } - - defines << '\0'; - - size_t pos = source.find("#version") + 8; - if (pos >= source.length()) { - pos = 0; - } - - const size_t epos = source.find_last_of("#extension", pos) + 10; - if (epos < source.length()) { - pos = epos; + if (!m_defines.empty()) { + std::strstream defines; + for (const auto& define : m_defines) { + defines << "#define " << define.first << " " << define.second << std::endl; + } + + defines << '\0'; + + size_t pos = source.find("#version") + 8; + if (pos >= source.length()) { + pos = 0; + } + + const size_t epos = source.find_last_of("#extension", pos) + 10; + if (epos < source.length()) { + pos = epos; + } + + pos = source.find('\n', pos) + 1; + source = source.insert(pos, defines.str()); } - pos = source.find('\n', pos) + 1; - source = source.insert(pos, defines.str()); - const char *shaderStrings [1]; shaderStrings[0] = source.c_str(); diff --git a/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp b/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp index d028beceabd08ac8b1ae2aea13919477016b5cd1..3d418c2461d5f36f3295e8bd76f92b679dda5d55 100644 --- a/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp +++ b/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp @@ -111,7 +111,7 @@ namespace vkcv::upscaling { m_easuDescriptorSet(m_core.createDescriptorSet(getDescriptorBindings())), m_rcasDescriptorSet(m_core.createDescriptorSet(getDescriptorBindings())), m_constants(m_core.createBuffer<FSRConstants>( - BufferType::UNIFORM,1, + BufferType::UNIFORM,2, BufferMemoryType::HOST_VISIBLE )), m_intermediateImage(), @@ -122,8 +122,9 @@ namespace vkcv::upscaling { SamplerAddressMode::CLAMP_TO_EDGE )), m_hdr(false), - m_sharpness(0/*.875f*/) { - vkcv::shader::GLSLCompiler easuCompiler, rcasCompiler; + m_sharpness(0.875f) { + vkcv::shader::GLSLCompiler easuCompiler; + vkcv::shader::GLSLCompiler rcasCompiler; const auto& features = m_core.getContext().getPhysicalDevice().getFeatures2(); const bool float16Support = ( @@ -159,7 +160,11 @@ namespace vkcv::upscaling { }); DescriptorWrites writes; - writes.uniformBufferWrites.emplace_back(0, m_constants.getHandle(), true); + writes.uniformBufferWrites.emplace_back( + 0, m_constants.getHandle(), + true, 0, sizeof(FSRConstants) + ); + writes.samplerWrites.emplace_back(3, m_sampler); m_core.writeDescriptorSet(m_easuDescriptorSet, writes); @@ -177,7 +182,11 @@ namespace vkcv::upscaling { }); DescriptorWrites writes; - writes.uniformBufferWrites.emplace_back(0, m_constants.getHandle(), true); + writes.uniformBufferWrites.emplace_back( + 0, m_constants.getHandle(), + true, sizeof(FSRConstants), sizeof(FSRConstants) + ); + writes.samplerWrites.emplace_back(3, m_sampler); m_core.writeDescriptorSet(m_rcasDescriptorSet, writes); @@ -218,7 +227,7 @@ namespace vkcv::upscaling { consts.Sample[0] = (((m_hdr) && (m_sharpness <= +0.0f)) ? 1 : 0); - m_constants.fill(&consts); + m_constants.fill(&consts, 1, 0); } static const uint32_t threadGroupWorkRegionDim = 16; @@ -262,7 +271,7 @@ namespace vkcv::upscaling { FsrRcasCon(consts.Const0, (1.0f - m_sharpness) * 2.0f); consts.Sample[0] = (m_hdr ? 1 : 0); - m_constants.fill(&consts); + m_constants.fill(&consts, 1, 1); } m_core.recordBufferMemoryBarrier(cmdStream, m_constants.getHandle()); @@ -290,7 +299,7 @@ namespace vkcv::upscaling { m_core.recordComputeDispatchToCmdStream( cmdStream, - m_rcasPipeline, + m_easuPipeline, dispatch, {DescriptorSetUsage(0, m_core.getDescriptorSet( m_easuDescriptorSet diff --git a/projects/particle_simulation/src/main.cpp b/projects/particle_simulation/src/main.cpp index 0d83644b866f5f89fb33c68f1d5a79fcee8c028a..07ba6b194ce72dbad15a921ca13a4814c6d4f5df 100644 --- a/projects/particle_simulation/src/main.cpp +++ b/projects/particle_simulation/src/main.cpp @@ -163,13 +163,13 @@ int main(int argc, const char **argv) { particleBuffer.fill(particleSystem.getParticles()); vkcv::DescriptorWrites setWrites; - setWrites.uniformBufferWrites = {vkcv::UniformBufferDescriptorWrite(0,color.getHandle()), - vkcv::UniformBufferDescriptorWrite(1,position.getHandle())}; - setWrites.storageBufferWrites = { vkcv::StorageBufferDescriptorWrite(2,particleBuffer.getHandle())}; + setWrites.uniformBufferWrites = {vkcv::BufferDescriptorWrite(0,color.getHandle()), + vkcv::BufferDescriptorWrite(1,position.getHandle())}; + setWrites.storageBufferWrites = { vkcv::BufferDescriptorWrite(2,particleBuffer.getHandle())}; core.writeDescriptorSet(descriptorSet, setWrites); vkcv::DescriptorWrites computeWrites; - computeWrites.storageBufferWrites = { vkcv::StorageBufferDescriptorWrite(0,particleBuffer.getHandle())}; + computeWrites.storageBufferWrites = { vkcv::BufferDescriptorWrite(0,particleBuffer.getHandle())}; core.writeDescriptorSet(computeDescriptorSet, computeWrites); if (!particlePipeline || !computePipeline) diff --git a/projects/voxelization/resources/shaders/postEffects.comp b/projects/voxelization/resources/shaders/postEffects.comp new file mode 100644 index 0000000000000000000000000000000000000000..c0f9fe1a764bcdabac5501e2f82692c6f476e9e6 --- /dev/null +++ b/projects/voxelization/resources/shaders/postEffects.comp @@ -0,0 +1,149 @@ +#version 440 +#extension GL_GOOGLE_include_directive : enable + +#include "luma.inc" + +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; + +layout( push_constant ) uniform constants{ + float time; +}; + +// from: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ +vec3 ACESFilm(vec3 x) +{ + float a = 2.51f; + float b = 0.03f; + float c = 2.43f; + float d = 0.59f; + float e = 0.14f; + return clamp((x*(a*x+b))/(x*(c*x+d)+e), 0, 1); +} + +// From Dave Hoskins: https://www.shadertoy.com/view/4djSRW. +float hash(vec3 p3){ + p3 = fract(p3 * 0.1031); + p3 += dot(p3,p3.yzx + 19.19); + return fract((p3.x + p3.y) * p3.z); +} + +// From iq: https://www.shadertoy.com/view/4sfGzS. +float noise(vec3 x){ + vec3 i = floor(x); + vec3 f = fract(x); + f = f*f*(3.0-2.0*f); + return mix(mix(mix(hash(i+vec3(0, 0, 0)), + hash(i+vec3(1, 0, 0)),f.x), + mix(hash(i+vec3(0, 1, 0)), + hash(i+vec3(1, 1, 0)),f.x),f.y), + mix(mix(hash(i+vec3(0, 0, 1)), + hash(i+vec3(1, 0, 1)),f.x), + mix(hash(i+vec3(0, 1, 1)), + hash(i+vec3(1, 1, 1)),f.x),f.y),f.z); +} + +// From: https://www.shadertoy.com/view/3sGSWVF +// Slightly high-passed continuous value-noise. +float grainSource(vec3 x, float strength, float pitch){ + float center = noise(x); + float v1 = center - noise(vec3( 1, 0, 0)/pitch + x) + 0.5; + float v2 = center - noise(vec3( 0, 1, 0)/pitch + x) + 0.5; + float v3 = center - noise(vec3(-1, 0, 0)/pitch + x) + 0.5; + float v4 = center - noise(vec3( 0,-1, 0)/pitch + x) + 0.5; + + float total = (v1 + v2 + v3 + v4) / 4.0; + return mix(1, 0.5 + total, strength); +} + +vec3 applyGrain(ivec2 uv, vec3 c){ + float grainLift = 0.6; + float grainStrength = 0.4; + float grainTimeFactor = 0.1; + + float timeColorOffset = 1.2; + vec3 grain = vec3( + grainSource(vec3(uv, floor(grainTimeFactor*time)), grainStrength, grainLift), + grainSource(vec3(uv, floor(grainTimeFactor*time + timeColorOffset)), grainStrength, grainLift), + grainSource(vec3(uv, floor(grainTimeFactor*time - timeColorOffset)), grainStrength, grainLift)); + + return c * grain; +} + +vec2 computeDistortedUV(vec2 uv, float aspectRatio){ + uv = uv * 2 - 1; + float r2 = dot(uv, uv); + float k1 = 0.02f; + + float maxR2 = dot(vec2(1), vec2(1)); + float maxFactor = maxR2 * k1; + + // correction only needed for pincushion distortion + maxFactor = min(maxFactor, 0); + + uv /= 1 + r2*k1; + + // correction to avoid going out of [-1, 1] range when using barrel distortion + uv *= 1 + maxFactor; + + return uv * 0.5 + 0.5; +} + +float computeLocalContrast(vec2 uv){ + float lumaMin = 100; + float lumaMax = 0; + + vec2 pixelSize = vec2(1) / textureSize(sampler2D(inTexture, textureSampler), 0); + + for(int x = -1; x <= 1; x++){ + for(int y = -1; y <= 1; y++){ + vec3 c = texture(sampler2D(inTexture, textureSampler), uv + vec2(x, y) * pixelSize).rgb; + float luma = computeLuma(c); + lumaMin = min(lumaMin, luma); + lumaMax = max(lumaMax, luma); + } + } + + return lumaMax - lumaMin; +} + +vec3 computeChromaticAberrationScale(vec2 uv){ + float localContrast = computeLocalContrast(uv); + vec3 colorScales = vec3(-1, 0, 1); + float aberrationScale = 0.004; + vec3 maxScaleFactors = colorScales * aberrationScale; + float factor = clamp(localContrast, 0, 1); + return mix(vec3(0), maxScaleFactors, factor); +} + +vec3 sampleColorChromaticAberration(vec2 uv){ + vec2 toCenter = (vec2(0.5) - uv); + + vec3 scaleFactors = computeChromaticAberrationScale(uv); + + float r = texture(sampler2D(inTexture, textureSampler), uv + toCenter * scaleFactors.r).r; + float g = texture(sampler2D(inTexture, textureSampler), uv + toCenter * scaleFactors.g).g; + float b = texture(sampler2D(inTexture, textureSampler), uv + toCenter * scaleFactors.b).b; + return vec3(r, g, b); +} + +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; + float aspectRatio = float(textureRes.x) / textureRes.y; + uv = computeDistortedUV(uv, aspectRatio); + + vec3 tonemapped = sampleColorChromaticAberration(uv); + tonemapped = applyGrain(coord, tonemapped); + + vec3 gammaCorrected = pow(tonemapped, vec3(1.f / 2.2f)); + imageStore(outImage, coord, vec4(gammaCorrected, 0.f)); +} \ No newline at end of file diff --git a/projects/voxelization/resources/shaders/tonemapping.comp b/projects/voxelization/resources/shaders/tonemapping.comp index 8fa07d39ebb56eab857cdccb755a6558f5ae1ec3..ffadc9a71e207f97fec9a8815aa1c61bc709c369 100644 --- a/projects/voxelization/resources/shaders/tonemapping.comp +++ b/projects/voxelization/resources/shaders/tonemapping.comp @@ -1,18 +1,12 @@ #version 440 #extension GL_GOOGLE_include_directive : enable -#include "luma.inc" - 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; -layout( push_constant ) uniform constants{ - float time; -}; - // from: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ vec3 ACESFilm(vec3 x) { @@ -24,112 +18,6 @@ vec3 ACESFilm(vec3 x) return clamp((x*(a*x+b))/(x*(c*x+d)+e), 0, 1); } -// From Dave Hoskins: https://www.shadertoy.com/view/4djSRW. -float hash(vec3 p3){ - p3 = fract(p3 * 0.1031); - p3 += dot(p3,p3.yzx + 19.19); - return fract((p3.x + p3.y) * p3.z); -} - -// From iq: https://www.shadertoy.com/view/4sfGzS. -float noise(vec3 x){ - vec3 i = floor(x); - vec3 f = fract(x); - f = f*f*(3.0-2.0*f); - return mix(mix(mix(hash(i+vec3(0, 0, 0)), - hash(i+vec3(1, 0, 0)),f.x), - mix(hash(i+vec3(0, 1, 0)), - hash(i+vec3(1, 1, 0)),f.x),f.y), - mix(mix(hash(i+vec3(0, 0, 1)), - hash(i+vec3(1, 0, 1)),f.x), - mix(hash(i+vec3(0, 1, 1)), - hash(i+vec3(1, 1, 1)),f.x),f.y),f.z); -} - -// From: https://www.shadertoy.com/view/3sGSWVF -// Slightly high-passed continuous value-noise. -float grainSource(vec3 x, float strength, float pitch){ - float center = noise(x); - float v1 = center - noise(vec3( 1, 0, 0)/pitch + x) + 0.5; - float v2 = center - noise(vec3( 0, 1, 0)/pitch + x) + 0.5; - float v3 = center - noise(vec3(-1, 0, 0)/pitch + x) + 0.5; - float v4 = center - noise(vec3( 0,-1, 0)/pitch + x) + 0.5; - - float total = (v1 + v2 + v3 + v4) / 4.0; - return mix(1, 0.5 + total, strength); -} - -vec3 applyGrain(ivec2 uv, vec3 c){ - float grainLift = 0.6; - float grainStrength = 0.4; - float grainTimeFactor = 0.1; - - float timeColorOffset = 1.2; - vec3 grain = vec3( - grainSource(vec3(uv, floor(grainTimeFactor*time)), grainStrength, grainLift), - grainSource(vec3(uv, floor(grainTimeFactor*time + timeColorOffset)), grainStrength, grainLift), - grainSource(vec3(uv, floor(grainTimeFactor*time - timeColorOffset)), grainStrength, grainLift)); - - return c * grain; -} - -vec2 computeDistortedUV(vec2 uv, float aspectRatio){ - uv = uv * 2 - 1; - float r2 = dot(uv, uv); - float k1 = 0.02f; - - float maxR2 = dot(vec2(1), vec2(1)); - float maxFactor = maxR2 * k1; - - // correction only needed for pincushion distortion - maxFactor = min(maxFactor, 0); - - uv /= 1 + r2*k1; - - // correction to avoid going out of [-1, 1] range when using barrel distortion - uv *= 1 + maxFactor; - - return uv * 0.5 + 0.5; -} - -float computeLocalContrast(vec2 uv){ - float lumaMin = 100; - float lumaMax = 0; - - vec2 pixelSize = vec2(1) / textureSize(sampler2D(inTexture, textureSampler), 0); - - for(int x = -1; x <= 1; x++){ - for(int y = -1; y <= 1; y++){ - vec3 c = texture(sampler2D(inTexture, textureSampler), uv + vec2(x, y) * pixelSize).rgb; - float luma = computeLuma(c); - lumaMin = min(lumaMin, luma); - lumaMax = max(lumaMax, luma); - } - } - - return lumaMax - lumaMin; -} - -vec3 computeChromaticAberrationScale(vec2 uv){ - float localContrast = computeLocalContrast(uv); - vec3 colorScales = vec3(-1, 0, 1); - float aberrationScale = 0.004; - vec3 maxScaleFactors = colorScales * aberrationScale; - float factor = clamp(localContrast, 0, 1); - return mix(vec3(0), maxScaleFactors, factor); -} - -vec3 sampleColorChromaticAberration(vec2 uv){ - vec2 toCenter = (vec2(0.5) - uv); - - vec3 scaleFactors = computeChromaticAberrationScale(uv); - - float r = texture(sampler2D(inTexture, textureSampler), uv + toCenter * scaleFactors.r).r; - float g = texture(sampler2D(inTexture, textureSampler), uv + toCenter * scaleFactors.g).g; - float b = texture(sampler2D(inTexture, textureSampler), uv + toCenter * scaleFactors.b).b; - return vec3(r, g, b); -} - void main(){ if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(outImage)))){ @@ -138,12 +26,9 @@ void main(){ ivec2 textureRes = textureSize(sampler2D(inTexture, textureSampler), 0); ivec2 coord = ivec2(gl_GlobalInvocationID.xy); vec2 uv = vec2(coord) / textureRes; - float aspectRatio = float(textureRes.x) / textureRes.y; - uv = computeDistortedUV(uv, aspectRatio); - vec3 linearColor = sampleColorChromaticAberration(uv); + + vec3 linearColor = texture(sampler2D(inTexture, textureSampler), uv).rgb; vec3 tonemapped = ACESFilm(linearColor); - tonemapped = applyGrain(coord, tonemapped); - - vec3 gammaCorrected = pow(tonemapped, vec3(1.f / 2.2f)); - imageStore(outImage, coord, vec4(gammaCorrected, 0.f)); + + imageStore(outImage, coord, vec4(tonemapped, 0.f)); } \ No newline at end of file diff --git a/projects/voxelization/src/Voxelization.cpp b/projects/voxelization/src/Voxelization.cpp index bbf161ddeb0899a1ce61279b4c476fb19cb906d7..f7e03709c6423ef0e3c43251afb28e887b9be61f 100644 --- a/projects/voxelization/src/Voxelization.cpp +++ b/projects/voxelization/src/Voxelization.cpp @@ -119,10 +119,10 @@ Voxelization::Voxelization( m_voxelizationPipe = m_corePtr->createGraphicsPipeline(voxelizationPipeConfig); vkcv::DescriptorWrites voxelizationDescriptorWrites; - voxelizationDescriptorWrites.storageBufferWrites = { vkcv::StorageBufferDescriptorWrite(0, m_voxelBuffer.getHandle()) }; + voxelizationDescriptorWrites.storageBufferWrites = { vkcv::BufferDescriptorWrite(0, m_voxelBuffer.getHandle()) }; voxelizationDescriptorWrites.uniformBufferWrites = { - vkcv::UniformBufferDescriptorWrite(1, m_voxelInfoBuffer.getHandle()), - vkcv::UniformBufferDescriptorWrite(3, lightInfoBuffer) + vkcv::BufferDescriptorWrite(1, m_voxelInfoBuffer.getHandle()), + vkcv::BufferDescriptorWrite(3, lightInfoBuffer) }; voxelizationDescriptorWrites.sampledImageWrites = { vkcv::SampledImageDescriptorWrite(4, shadowMap) }; voxelizationDescriptorWrites.samplerWrites = { vkcv::SamplerDescriptorWrite(5, shadowSampler) }; @@ -180,7 +180,7 @@ Voxelization::Voxelization( { m_corePtr->getDescriptorSet(m_voxelResetDescriptorSet).layout }); vkcv::DescriptorWrites resetVoxelWrites; - resetVoxelWrites.storageBufferWrites = { vkcv::StorageBufferDescriptorWrite(0, m_voxelBuffer.getHandle()) }; + resetVoxelWrites.storageBufferWrites = { vkcv::BufferDescriptorWrite(0, m_voxelBuffer.getHandle()) }; m_corePtr->writeDescriptorSet(m_voxelResetDescriptorSet, resetVoxelWrites); // buffer to image @@ -192,7 +192,7 @@ Voxelization::Voxelization( { m_corePtr->getDescriptorSet(m_bufferToImageDescriptorSet).layout }); vkcv::DescriptorWrites bufferToImageDescriptorWrites; - bufferToImageDescriptorWrites.storageBufferWrites = { vkcv::StorageBufferDescriptorWrite(0, m_voxelBuffer.getHandle()) }; + bufferToImageDescriptorWrites.storageBufferWrites = { vkcv::BufferDescriptorWrite(0, m_voxelBuffer.getHandle()) }; bufferToImageDescriptorWrites.storageImageWrites = { vkcv::StorageImageDescriptorWrite(1, m_voxelImageIntermediate.getHandle()) }; m_corePtr->writeDescriptorSet(m_bufferToImageDescriptorSet, bufferToImageDescriptorWrites); @@ -205,11 +205,11 @@ Voxelization::Voxelization( { m_corePtr->getDescriptorSet(m_secondaryBounceDescriptorSet).layout }); vkcv::DescriptorWrites secondaryBounceDescriptorWrites; - secondaryBounceDescriptorWrites.storageBufferWrites = { vkcv::StorageBufferDescriptorWrite(0, m_voxelBuffer.getHandle()) }; + secondaryBounceDescriptorWrites.storageBufferWrites = { vkcv::BufferDescriptorWrite(0, m_voxelBuffer.getHandle()) }; secondaryBounceDescriptorWrites.sampledImageWrites = { vkcv::SampledImageDescriptorWrite(1, m_voxelImageIntermediate.getHandle()) }; secondaryBounceDescriptorWrites.samplerWrites = { vkcv::SamplerDescriptorWrite(2, voxelSampler) }; secondaryBounceDescriptorWrites.storageImageWrites = { vkcv::StorageImageDescriptorWrite(3, m_voxelImage.getHandle()) }; - secondaryBounceDescriptorWrites.uniformBufferWrites = { vkcv::UniformBufferDescriptorWrite(4, m_voxelInfoBuffer.getHandle()) }; + secondaryBounceDescriptorWrites.uniformBufferWrites = { vkcv::BufferDescriptorWrite(4, m_voxelInfoBuffer.getHandle()) }; m_corePtr->writeDescriptorSet(m_secondaryBounceDescriptorSet, secondaryBounceDescriptorWrites); } @@ -331,7 +331,7 @@ void Voxelization::renderVoxelVisualisation( voxelVisualisationDescriptorWrite.storageImageWrites = { vkcv::StorageImageDescriptorWrite(0, m_voxelImage.getHandle(), mipLevel) }; voxelVisualisationDescriptorWrite.uniformBufferWrites = - { vkcv::UniformBufferDescriptorWrite(1, m_voxelInfoBuffer.getHandle()) }; + { vkcv::BufferDescriptorWrite(1, m_voxelInfoBuffer.getHandle()) }; m_corePtr->writeDescriptorSet(m_visualisationDescriptorSet, voxelVisualisationDescriptorWrite); uint32_t drawVoxelCount = voxelCount / exp2(mipLevel); diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp index e50f6b186d2081894451e005bc0ffb97dad5afe4..5763b653e5db75e150f82a0c2c293dfd5d792de3 100644 --- a/projects/voxelization/src/main.cpp +++ b/projects/voxelization/src/main.cpp @@ -396,6 +396,7 @@ int main(int argc, const char** argv) { } vkcv::ImageHandle swapBuffer = core.createImage(colorBufferFormat, windowWidth, windowHeight, 1, false, true).getHandle(); + vkcv::ImageHandle swapBuffer2 = core.createImage(colorBufferFormat, windowWidth, windowHeight, 1, false, true).getHandle(); const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); @@ -424,6 +425,18 @@ int main(int argc, const char** argv) { vkcv::PipelineHandle tonemappingPipeline = core.createComputePipeline( tonemappingProgram, { core.getDescriptorSet(tonemappingDescriptorSet).layout }); + + // tonemapping compute shader + vkcv::ShaderProgram postEffectsProgram; + compiler.compile(vkcv::ShaderStage::COMPUTE, "resources/shaders/postEffects.comp", + [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { + postEffectsProgram.addShader(shaderStage, path); + }); + vkcv::DescriptorSetHandle postEffectsDescriptorSet = core.createDescriptorSet( + postEffectsProgram.getReflectedDescriptors()[0]); + vkcv::PipelineHandle postEffectsPipeline = core.createComputePipeline( + postEffectsProgram, + { core.getDescriptorSet(postEffectsDescriptorSet).layout }); // resolve compute shader vkcv::ShaderProgram resolveProgram; @@ -514,10 +527,10 @@ int main(int argc, const char** argv) { // write forward pass descriptor set vkcv::DescriptorWrites forwardDescriptorWrites; forwardDescriptorWrites.uniformBufferWrites = { - vkcv::UniformBufferDescriptorWrite(0, shadowMapping.getLightInfoBuffer()), - vkcv::UniformBufferDescriptorWrite(3, cameraPosBuffer.getHandle()), - vkcv::UniformBufferDescriptorWrite(6, voxelization.getVoxelInfoBufferHandle()), - vkcv::UniformBufferDescriptorWrite(7, volumetricSettingsBuffer.getHandle())}; + vkcv::BufferDescriptorWrite(0, shadowMapping.getLightInfoBuffer()), + vkcv::BufferDescriptorWrite(3, cameraPosBuffer.getHandle()), + vkcv::BufferDescriptorWrite(6, voxelization.getVoxelInfoBufferHandle()), + vkcv::BufferDescriptorWrite(7, volumetricSettingsBuffer.getHandle())}; forwardDescriptorWrites.sampledImageWrites = { vkcv::SampledImageDescriptorWrite(1, shadowMapping.getShadowMap()), vkcv::SampledImageDescriptorWrite(4, voxelization.getVoxelImageHandle()) }; @@ -574,16 +587,41 @@ int main(int argc, const char** argv) { fsrWidth = width; fsrHeight = height; - depthBuffer = core.createImage(depthBufferFormat, fsrWidth, fsrHeight, 1, false, false, false, msaa).getHandle(); - colorBuffer = core.createImage(colorBufferFormat, fsrWidth, fsrHeight, 1, false, colorBufferRequiresStorage, true, msaa).getHandle(); + depthBuffer = core.createImage( + depthBufferFormat, + fsrWidth, fsrHeight, 1, + false, false, false, + msaa + ).getHandle(); + + colorBuffer = core.createImage( + colorBufferFormat, + fsrWidth, fsrHeight, 1, + false, colorBufferRequiresStorage, true, + msaa + ).getHandle(); if (usingMsaa) { - resolvedColorBuffer = core.createImage(colorBufferFormat, fsrWidth, fsrHeight, 1, false, true, true).getHandle(); + resolvedColorBuffer = core.createImage( + colorBufferFormat, + fsrWidth, fsrHeight, 1, + false, true, true + ).getHandle(); } else { resolvedColorBuffer = colorBuffer; } - swapBuffer = core.createImage(colorBufferFormat, fsrWidth, fsrHeight, 1, false, true).getHandle(); + swapBuffer = core.createImage( + colorBufferFormat, + fsrWidth, fsrHeight, 1, + false, true + ).getHandle(); + + swapBuffer2 = core.createImage( + colorBufferFormat, + swapchainWidth, swapchainHeight, 1, + false, true + ).getHandle(); bloomFlares.updateImageDimensions(swapchainWidth, swapchainHeight); } @@ -598,6 +636,14 @@ int main(int argc, const char** argv) { tonemappingDescriptorWrites.storageImageWrites = { vkcv::StorageImageDescriptorWrite(2, swapBuffer) }; core.writeDescriptorSet(tonemappingDescriptorSet, tonemappingDescriptorWrites); + + // update descriptor sets which use swapchain image + vkcv::DescriptorWrites postEffectsDescriptorWrites; + postEffectsDescriptorWrites.sampledImageWrites = { vkcv::SampledImageDescriptorWrite(0, swapBuffer2) }; + postEffectsDescriptorWrites.samplerWrites = { vkcv::SamplerDescriptorWrite(1, colorSampler) }; + postEffectsDescriptorWrites.storageImageWrites = { vkcv::StorageImageDescriptorWrite(2, swapchainInput) }; + + core.writeDescriptorSet(postEffectsDescriptorSet, postEffectsDescriptorWrites); // update resolve descriptor, color images could be changed vkcv::DescriptorWrites resolveDescriptorWrites; @@ -699,11 +745,18 @@ int main(int argc, const char** argv) { renderTargets); const uint32_t fullscreenLocalGroupSize = 8; - const uint32_t fulsscreenDispatchCount[3] = { - static_cast<uint32_t>(glm::ceil(fsrWidth / static_cast<float>(fullscreenLocalGroupSize))), - static_cast<uint32_t>(glm::ceil(fsrHeight / static_cast<float>(fullscreenLocalGroupSize))), - 1 - }; + + uint32_t fulsscreenDispatchCount [3]; + + fulsscreenDispatchCount[0] = static_cast<uint32_t>( + glm::ceil(fsrWidth / static_cast<float>(fullscreenLocalGroupSize)) + ); + + fulsscreenDispatchCount[1] = static_cast<uint32_t>( + glm::ceil(fsrHeight / static_cast<float>(fullscreenLocalGroupSize)) + ); + + fulsscreenDispatchCount[2] = 1; if (usingMsaa) { if (msaaCustomResolve) { @@ -732,12 +785,6 @@ int main(int argc, const char** argv) { core.prepareImageForStorage(cmdStream, swapBuffer); core.prepareImageForSampling(cmdStream, resolvedColorBuffer); - - auto timeSinceStart = std::chrono::duration_cast<std::chrono::microseconds>(end - appStartTime); - float timeF = static_cast<float>(timeSinceStart.count()) * 0.01f; - - vkcv::PushConstants timePushConstants (sizeof(timeF)); - timePushConstants.appendDrawcall(timeF); core.recordComputeDispatchToCmdStream( cmdStream, @@ -746,21 +793,48 @@ int main(int argc, const char** argv) { { vkcv::DescriptorSetUsage(0, core.getDescriptorSet( tonemappingDescriptorSet ).vulkanHandle) }, - timePushConstants + vkcv::PushConstants(0) ); - core.prepareImageForStorage(cmdStream, swapchainInput); + core.prepareImageForStorage(cmdStream, swapBuffer2); core.prepareImageForSampling(cmdStream, swapBuffer); if (fsrFactor <= 1.0f) { upscaling.setSharpness(0.0f); } - upscaling.recordUpscaling(cmdStream, swapBuffer, swapchainInput); + upscaling.recordUpscaling(cmdStream, swapBuffer, swapBuffer2); if (fsrFactor <= 1.0f) { upscaling.setSharpness(rcasSharpness); } + + core.prepareImageForStorage(cmdStream, swapchainInput); + core.prepareImageForSampling(cmdStream, swapBuffer2); + + auto timeSinceStart = std::chrono::duration_cast<std::chrono::microseconds>(end - appStartTime); + float timeF = static_cast<float>(timeSinceStart.count()) * 0.01f; + + vkcv::PushConstants timePushConstants (sizeof(timeF)); + timePushConstants.appendDrawcall(timeF); + + fulsscreenDispatchCount[0] = static_cast<uint32_t>( + glm::ceil(swapchainWidth / static_cast<float>(fullscreenLocalGroupSize)) + ); + + fulsscreenDispatchCount[1] = static_cast<uint32_t>( + glm::ceil(swapchainHeight / static_cast<float>(fullscreenLocalGroupSize)) + ); + + core.recordComputeDispatchToCmdStream( + cmdStream, + postEffectsPipeline, + fulsscreenDispatchCount, + { vkcv::DescriptorSetUsage(0, core.getDescriptorSet( + postEffectsDescriptorSet + ).vulkanHandle) }, + timePushConstants + ); // present and end core.prepareSwapchainImageForPresent(cmdStream); diff --git a/src/vkcv/DescriptorManager.cpp b/src/vkcv/DescriptorManager.cpp index 8afd50a3ba8259a487a71e578f60459afa7192cf..0df359a15883847c132c429ed2945ac7624fb865 100644 --- a/src/vkcv/DescriptorManager.cpp +++ b/src/vkcv/DescriptorManager.cpp @@ -156,10 +156,15 @@ namespace vkcv } for (const auto& write : writes.uniformBufferWrites) { + const size_t size = bufferManager.getBufferSize(write.buffer); + const uint32_t offset = std::clamp<uint32_t>(write.offset, 0, size); + const vk::DescriptorBufferInfo bufferInfo( bufferManager.getBuffer(write.buffer), - static_cast<uint32_t>(0), - bufferManager.getBufferSize(write.buffer) + offset, + write.size == 0? size : std::min<uint32_t>( + write.size, size - offset + ) ); bufferInfos.push_back(bufferInfo); @@ -177,10 +182,15 @@ namespace vkcv } for (const auto& write : writes.storageBufferWrites) { + const size_t size = bufferManager.getBufferSize(write.buffer); + const uint32_t offset = std::clamp<uint32_t>(write.offset, 0, size); + const vk::DescriptorBufferInfo bufferInfo( bufferManager.getBuffer(write.buffer), - static_cast<uint32_t>(0), - bufferManager.getBufferSize(write.buffer) + offset, + write.size == 0? size : std::min<uint32_t>( + write.size, size - offset + ) ); bufferInfos.push_back(bufferInfo);