diff --git a/projects/voxelization/resources/shaders/shader.frag b/projects/voxelization/resources/shaders/shader.frag index 2597492bc7a59c671fdf081aa2b30283127edb01..8653ae5958ce3b42eac6b1eaa6813f85b6ed589c 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 0000000000000000000000000000000000000000..1fa34a388c35b96a3316e972ca562d35e2c3cf90 --- /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 d2b4400235817e3be1739dc46857ab42f260ebf7..25c0a82bbc887913a4d69ccdeee2b0d8934828c8 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 e745cf2a4440da8cc3d88bbf0e72377f26c72e6e..a49b13185ec26b069661141cfdbbfbbe45d14fd3 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 6c7d996774faa0b4f30eefbf9ffbdbf21f72bfa1..e471eea637093e746181e1895ec90df3876edae2 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 270ac0514c78d6f7e9a59f123cd55279306d4105..0e62b059fb5bef1f73681c10c83aa6c79c806fa4 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 c916c5c958cf5ca843d08c277b1a384ea56b3567..53c25e6dfcd43efcd0d9e0957b6c34f82fad0b5a 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);