From 2e4967372d39f943971446c84c473562dd1d1cc4 Mon Sep 17 00:00:00 2001 From: Alexander Gauggel <agauggel@uni-koblenz.de> Date: Sat, 19 Jun 2021 12:03:55 +0200 Subject: [PATCH] [#81] Properly light voxels --- .../resources/shaders/shader.frag | 20 ++----------- .../resources/shaders/shadowMapping.inc | 16 ++++++++++ .../voxelization/resources/shaders/voxel.inc | 29 +++++++++++++++---- .../resources/shaders/voxelization.frag | 8 ++++- projects/voxelization/src/Voxelization.cpp | 9 +++++- projects/voxelization/src/Voxelization.hpp | 7 ++++- projects/voxelization/src/main.cpp | 7 ++++- 7 files changed, 68 insertions(+), 28 deletions(-) create mode 100644 projects/voxelization/resources/shaders/shadowMapping.inc diff --git a/projects/voxelization/resources/shaders/shader.frag b/projects/voxelization/resources/shaders/shader.frag index 2597492b..8653ae59 100644 --- a/projects/voxelization/resources/shaders/shader.frag +++ b/projects/voxelization/resources/shaders/shader.frag @@ -4,6 +4,7 @@ #include "perMeshResources.inc" #include "lightInfo.inc" +#include "shadowMapping.inc" layout(location = 0) in vec3 passNormal; layout(location = 1) in vec2 passUV; @@ -17,27 +18,10 @@ layout(set=0, binding=0) uniform sunBuffer { layout(set=0, binding=1) uniform texture2D shadowMap; layout(set=0, binding=2) uniform sampler shadowMapSampler; -float shadowTest(vec3 worldPos){ - vec4 lightPos = lightInfo.lightMatrix * vec4(worldPos, 1); - lightPos /= lightPos.w; - lightPos.xy = lightPos.xy * 0.5 + 0.5; - - if(any(lessThan(lightPos.xy, vec2(0))) || any(greaterThan(lightPos.xy, vec2(1)))){ - return 1; - } - - lightPos.z = clamp(lightPos.z, 0, 1); - - float shadowMapSample = texture(sampler2D(shadowMap, shadowMapSampler), lightPos.xy).r; - float bias = 0.01f; - shadowMapSample += bias; - return shadowMapSample < lightPos.z ? 0 : 1; -} - void main() { vec3 N = normalize(passNormal); vec3 sun = lightInfo.sunStrength * lightInfo.sunColor * clamp(dot(N, lightInfo.L), 0, 1); - sun *= shadowTest(passPos); + sun *= shadowTest(passPos, lightInfo, shadowMap, shadowMapSampler); vec3 ambient = vec3(0.05); vec3 albedo = texture(sampler2D(albedoTexture, textureSampler), passUV).rgb; outColor = albedo * (sun + ambient); diff --git a/projects/voxelization/resources/shaders/shadowMapping.inc b/projects/voxelization/resources/shaders/shadowMapping.inc new file mode 100644 index 00000000..1fa34a38 --- /dev/null +++ b/projects/voxelization/resources/shaders/shadowMapping.inc @@ -0,0 +1,16 @@ +float shadowTest(vec3 worldPos, LightInfo lightInfo, texture2D shadowMap, sampler shadowMapSampler){ + vec4 lightPos = lightInfo.lightMatrix * vec4(worldPos, 1); + lightPos /= lightPos.w; + lightPos.xy = lightPos.xy * 0.5 + 0.5; + + if(any(lessThan(lightPos.xy, vec2(0))) || any(greaterThan(lightPos.xy, vec2(1)))){ + return 1; + } + + lightPos.z = clamp(lightPos.z, 0, 1); + + float shadowMapSample = texture(sampler2D(shadowMap, shadowMapSampler), lightPos.xy).r; + float bias = 0.01f; + shadowMapSample += bias; + return shadowMapSample < lightPos.z ? 0 : 1; +} \ No newline at end of file diff --git a/projects/voxelization/resources/shaders/voxel.inc b/projects/voxelization/resources/shaders/voxel.inc index d2b44002..25c0a82b 100644 --- a/projects/voxelization/resources/shaders/voxel.inc +++ b/projects/voxelization/resources/shaders/voxel.inc @@ -7,12 +7,26 @@ uint flattenVoxelUVToIndex(ivec3 UV, ivec3 voxelImageSize){ return UV.x + UV.y * voxelImageSize.x + UV.z * voxelImageSize.x* voxelImageSize.y; } +// packed voxel data: +// 1 bit opacity +// 7 bit exposure +// 8 bit blue +// 8 bit green +// 8 bit red +float maxExposure = 16.f; + uint packVoxelInfo(vec3 color){ - uint opaqueBit = 1 << 31; - uint redBits = uint(color.r * 255); - uint greenBits = uint(color.g * 255) << 8; - uint blueBits = uint(color.b * 255) << 16; - return opaqueBit | redBits | greenBits | blueBits; + + color = clamp(color, vec3(0), vec3(maxExposure)); + float maxComponent = max(max(max(color.r, color.g), color.b), 1.f); + color /= maxComponent; + + uint opaqueBit = 1 << 31; + uint exposureBits = (0x0000007F & uint(maxComponent / maxExposure * 127)) << 24; + uint redBits = (0x000000FF & uint(color.r * 255)) << 0; + uint greenBits = (0x000000FF & uint(color.g * 255)) << 8; + uint blueBits = (0x000000FF & uint(color.b * 255)) << 16; + return opaqueBit | exposureBits | blueBits | greenBits | redBits; } vec4 unpackVoxelInfo(uint packed){ @@ -20,6 +34,9 @@ vec4 unpackVoxelInfo(uint packed){ rgba.r = (packed >> 0 & 0x000000FF) / 255.f; rgba.g = (packed >> 8 & 0x000000FF) / 255.f; rgba.b = (packed >> 16 & 0x000000FF) / 255.f; - rgba.a = packed >> 31; + rgba.a = packed >> 31; + + rgba.rgb *= (packed >> 24 & 0x0000007F) / 127.f * maxExposure; + return rgba; } \ No newline at end of file diff --git a/projects/voxelization/resources/shaders/voxelization.frag b/projects/voxelization/resources/shaders/voxelization.frag index e745cf2a..a49b1318 100644 --- a/projects/voxelization/resources/shaders/voxelization.frag +++ b/projects/voxelization/resources/shaders/voxelization.frag @@ -5,6 +5,7 @@ #include "voxel.inc" #include "perMeshResources.inc" #include "lightInfo.inc" +#include "shadowMapping.inc" layout(location = 0) in vec3 passPos; layout(location = 1) in vec2 passUV; @@ -24,6 +25,9 @@ layout(set=0, binding=3) uniform sunBuffer { LightInfo lightInfo; }; +layout(set=0, binding=4) uniform texture2D shadowMap; +layout(set=0, binding=5) uniform sampler shadowMapSampler; + vec3 worldToVoxelCoordinates(vec3 world, VoxelInfo info){ return (world - info.offset) / info.extent + 0.5f; } @@ -45,7 +49,9 @@ void main() { vec3 N = normalize(passN); float NoL = clamp(dot(N, lightInfo.L), 0, 1); - vec3 color = albedo * NoL; + vec3 sun = lightInfo.sunStrength * lightInfo.sunColor * NoL * shadowTest(passPos, lightInfo, shadowMap, shadowMapSampler); + vec3 color = albedo * sun; + color = albedo * sun; atomicMax(packedVoxelData[flatIndex], packVoxelInfo(color)); } \ No newline at end of file diff --git a/projects/voxelization/src/Voxelization.cpp b/projects/voxelization/src/Voxelization.cpp index 6c7d9967..e471eea6 100644 --- a/projects/voxelization/src/Voxelization.cpp +++ b/projects/voxelization/src/Voxelization.cpp @@ -62,7 +62,12 @@ const uint32_t voxelResolution = 128; uint32_t voxelCount = voxelResolution * voxelResolution * voxelResolution; const vk::Format voxelizationDummyFormat = vk::Format::eR8Unorm; -Voxelization::Voxelization(vkcv::Core* corePtr, const Dependencies& dependencies, vkcv::BufferHandle lightInfoBuffer) +Voxelization::Voxelization( + vkcv::Core* corePtr, + const Dependencies& dependencies, + vkcv::BufferHandle lightInfoBuffer, + vkcv::ImageHandle shadowMap, + vkcv::SamplerHandle shadowSampler) : m_corePtr(corePtr), m_voxelImage(m_corePtr->createImage(vk::Format::eR16G16B16A16Sfloat, voxelResolution, voxelResolution, voxelResolution, false, true)), @@ -104,6 +109,8 @@ Voxelization::Voxelization(vkcv::Core* corePtr, const Dependencies& dependencies vkcv::UniformBufferDescriptorWrite(1, m_voxelInfoBuffer.getHandle()), vkcv::UniformBufferDescriptorWrite(3, lightInfoBuffer) }; + voxelizationDescriptorWrites.sampledImageWrites = { vkcv::SampledImageDescriptorWrite(4, shadowMap) }; + voxelizationDescriptorWrites.samplerWrites = { vkcv::SamplerDescriptorWrite(5, shadowSampler) }; voxelizationDescriptorWrites.storageImageWrites = { vkcv::StorageImageDescriptorWrite(2, m_voxelImage.getHandle()) }; m_corePtr->writeDescriptorSet(m_voxelizationDescriptorSet, voxelizationDescriptorWrites); diff --git a/projects/voxelization/src/Voxelization.hpp b/projects/voxelization/src/Voxelization.hpp index 270ac051..0e62b059 100644 --- a/projects/voxelization/src/Voxelization.hpp +++ b/projects/voxelization/src/Voxelization.hpp @@ -9,7 +9,12 @@ public: vk::Format colorBufferFormat; vk::Format depthBufferFormat; }; - Voxelization(vkcv::Core* corePtr, const Dependencies& dependencies, vkcv::BufferHandle lightInfoBuffer); + Voxelization( + vkcv::Core* corePtr, + const Dependencies& dependencies, + vkcv::BufferHandle lightInfoBuffer, + vkcv::ImageHandle shadowMap, + vkcv::SamplerHandle shadowSampler); void voxelizeMeshes( vkcv::CommandStreamHandle cmdStream, diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp index c916c5c9..53c25e6d 100644 --- a/projects/voxelization/src/main.cpp +++ b/projects/voxelization/src/main.cpp @@ -319,7 +319,12 @@ int main(int argc, const char** argv) { voxelDependencies.colorBufferFormat = colorBufferFormat; voxelDependencies.depthBufferFormat = depthBufferFormat; voxelDependencies.vertexLayout = vertexLayout; - Voxelization voxelization(&core, voxelDependencies, lightBuffer.getHandle()); + Voxelization voxelization( + &core, + voxelDependencies, + lightBuffer.getHandle(), + shadowMap.getHandle(), + shadowSampler); vkcv::gui::GUI gui(core, window); -- GitLab