Skip to content
Snippets Groups Projects
Unverified Commit 44e6d7d0 authored by TheJackiMonster's avatar TheJackiMonster
Browse files

Added voxel rendering

parent 1afb74e0
No related branches found
No related tags found
1 merge request!106Created initial firework project
#version 440
#extension GL_GOOGLE_include_directive : enable
layout(set=0, binding=0, rgba16f) readonly uniform image2D inParticles;
layout(set=0, binding=1, rgba16f) readonly uniform image2D inSmoke;
layout(set=0, binding=2, rgba16f) readonly uniform image2D inTrails;
layout(set=0, binding=3, rgba16f) writeonly uniform image2D outImage;
#include "voxel.inc"
layout(set=1, binding=0, r32ui) uniform uimage3D voxelRed;
layout(set=1, binding=1, r32ui) uniform uimage3D voxelGreen;
layout(set=1, binding=2, r32ui) uniform uimage3D voxelBlue;
layout(set=1, binding=3, r32ui) uniform uimage3D voxelDensity;
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
void main() {
if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(outImage)))){
const ivec2 res = imageSize(outImage);
if(any(greaterThanEqual(gl_GlobalInvocationID.xy, res))){
return;
}
......@@ -28,6 +38,27 @@ void main() {
outParticles.a + outSmoke.a + outTrails.a
);
const ivec3 voxelRes = imageSize(voxelDensity);
ivec2 voxelUV = uv * voxelRes.xy / res;
vec4 voxel = vec4(0.0f);
for (int i = 0; i < voxelRes.z; i++) {
const ivec3 voxelPos = ivec3(voxelUV, i);
const float red = voxel_read(voxelRed, voxelPos);
const float green = voxel_read(voxelGreen, voxelPos);
const float blue = voxel_read(voxelBlue, voxelPos);
const float density = voxel_read(voxelDensity, voxelPos);
voxel = vec4(
(voxel.rgb + vec3(red, green, blue) * density) * (1.0f - voxel.a),
voxel.a + (density) * (1.0f - voxel.a)
);
}
result = voxel;
result.r = clamp(result.r, 0, 1);
result.g = clamp(result.g, 0, 1);
result.b = clamp(result.b, 0, 1);
......
......@@ -49,7 +49,7 @@ void main() {
result.r = clamp(result.r, 0, 1);
result.g = clamp(result.g, 0, 1);
result.b = clamp(result.b, 0, 1);
result.a = clamp(result.a, 0, 1);;
result.a = clamp(result.a, 0, 1);
if (result.a < 1.0f) {
outColor = result;
......
#ifndef VOXEL_INC
#define VOXEL_INC
struct voxel_t {
vec3 color;
float density;
};
#define voxel_add(img, pos, value) imageAtomicAdd(img, ivec3((imageSize(img) - ivec3(1)) * pos), uint(0xFF * value))
#define voxel_write(img, pos, value) imageStore(img, pos, uvec4(0xFF * value));
#define voxel_read(img, pos) imageLoad(img, pos).r / 255.0f;
#endif // VOXEL_INC
\ No newline at end of file
#version 450 core
#version 450
#extension GL_GOOGLE_include_directive : enable
#extension GL_ARB_separate_shader_objects : enable
......@@ -13,9 +13,10 @@ layout(set=0, binding=0, std430) readonly buffer particleBuffer {
#include "voxel.inc"
layout(set=1, binding=0, std430) buffer voxelBuffer {
voxel_t voxel [];
};
layout(set=1, binding=0, r32ui) uniform uimage3D voxelRed;
layout(set=1, binding=1, r32ui) uniform uimage3D voxelGreen;
layout(set=1, binding=2, r32ui) uniform uimage3D voxelBlue;
layout(set=1, binding=3, r32ui) uniform uimage3D voxelDensity;
layout( push_constant ) uniform constants{
mat4 mvp;
......@@ -44,10 +45,15 @@ void main() {
vec3 ndc_pos = cs_pos.xyz / cs_pos.w;
vec3 pos = (ndc_pos + vec3(1, 1, 0)) * vec3(0.5f, 0.5f, 1.0f);
// clipping!
if ((any(greaterThanEqual(pos, vec3(1.5f)))) || (any(lessThanEqual(pos, vec3(-0.5f))))) {
return;
}
float size = particles[id].size;
vec3 color = particles[id].color;
// write color into voxel at `pos * (resolution-1)` atomically!
voxel_add(voxelRed, pos, color.r);
voxel_add(voxelGreen, pos, color.g);
voxel_add(voxelBlue, pos, color.b);
voxel_add(voxelDensity, pos, 1.0f);
}
......@@ -13,9 +13,10 @@ layout(set=0, binding=0, std430) readonly buffer smokeBuffer {
#include "voxel.inc"
layout(set=1, binding=0, std430) buffer voxelBuffer {
voxel_t voxel [];
};
layout(set=1, binding=0, r32ui) uniform uimage3D voxelRed;
layout(set=1, binding=1, r32ui) uniform uimage3D voxelGreen;
layout(set=1, binding=2, r32ui) uniform uimage3D voxelBlue;
layout(set=1, binding=3, r32ui) uniform uimage3D voxelDensity;
layout( push_constant ) uniform constants{
mat4 mvp;
......@@ -46,9 +47,14 @@ void main() {
vec3 ndc_pos = cs_pos.xyz / cs_pos.w;
vec3 pos = (ndc_pos + vec3(1, 1, 0)) * vec3(0.5f, 0.5f, 1.0f);
// clipping!
if ((any(greaterThanEqual(pos, vec3(1.5f)))) || (any(lessThanEqual(pos, vec3(-0.5f))))) {
return;
}
vec3 color = smokes[id].color;
// write (color, density) into voxel at `pos * (resolution-1)` atomically!
voxel_add(voxelRed, pos, color.r);
voxel_add(voxelGreen, pos, color.g);
voxel_add(voxelBlue, pos, color.b);
voxel_add(voxelDensity, pos, density);
}
......@@ -20,9 +20,10 @@ layout(set=0, binding=1, std430) buffer pointBuffer {
#include "voxel.inc"
layout(set=1, binding=0, std430) buffer voxelBuffer {
voxel_t voxel [];
};
layout(set=1, binding=0, r32ui) uniform uimage3D voxelRed;
layout(set=1, binding=1, r32ui) uniform uimage3D voxelGreen;
layout(set=1, binding=2, r32ui) uniform uimage3D voxelBlue;
layout(set=1, binding=3, r32ui) uniform uimage3D voxelDensity;
#include "smoke.inc"
......@@ -74,8 +75,13 @@ void main() {
vec3 ndc_pos = cs_pos.xyz / cs_pos.w;
vec3 pos = (ndc_pos + vec3(1, 1, 0)) * vec3(0.5f, 0.5f, 1.0f);
// clipping!
if ((any(greaterThanEqual(pos, vec3(1.5f)))) || (any(lessThanEqual(pos, vec3(-0.5f))))) {
continue;
}
// write (color, density) into voxel at `pos * (resolution-1)` atomically!
voxel_add(voxelRed, pos, color.r);
voxel_add(voxelGreen, pos, color.g);
voxel_add(voxelBlue, pos, color.b);
voxel_add(voxelDensity, pos, density);
}
}
......@@ -695,6 +695,93 @@ int main(int argc, const char **argv) {
{ descriptorSetLayout }
});
const uint32_t voxelWidth = 160;
const uint32_t voxelHeight = 90;
const uint32_t voxelDepth = 64;
std::vector<uint32_t> zeroVoxel;
zeroVoxel.resize(voxelWidth * voxelHeight * voxelDepth, 0);
vkcv::Image voxelRed = core.createImage(
vk::Format::eR32Uint,
voxelWidth,
voxelHeight,
voxelDepth,
false,
true
);
vkcv::Image voxelGreen = core.createImage(
vk::Format::eR32Uint,
voxelWidth,
voxelHeight,
voxelDepth,
false,
true
);
vkcv::Image voxelBlue = core.createImage(
vk::Format::eR32Uint,
voxelWidth,
voxelHeight,
voxelDepth,
false,
true
);
vkcv::Image voxelDensity = core.createImage(
vk::Format::eR32Uint,
voxelWidth,
voxelHeight,
voxelDepth,
false,
true
);
vkcv::ShaderProgram voxelParticleShader;
compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/voxel_particle.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
voxelParticleShader.addShader(shaderStage, path);
});
const auto& voxelBindings = voxelParticleShader.getReflectedDescriptors().at(1);
auto voxelDescriptorSetLayout = core.createDescriptorSetLayout(voxelBindings);
vkcv::ComputePipelineHandle voxelParticlePipeline = core.createComputePipeline({
voxelParticleShader,
{ descriptorSetLayout, voxelDescriptorSetLayout }
});
vkcv::ShaderProgram voxelSmokeShader;
compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/voxel_smoke.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
voxelSmokeShader.addShader(shaderStage, path);
});
vkcv::ComputePipelineHandle voxelSmokePipeline = core.createComputePipeline({
voxelSmokeShader,
{ smokeDescriptorLayout, voxelDescriptorSetLayout }
});
vkcv::ShaderProgram voxelTrailShader;
compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/voxel_trail.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
voxelTrailShader.addShader(shaderStage, path);
});
vkcv::ComputePipelineHandle voxelTrailPipeline = core.createComputePipeline({
voxelTrailShader,
{ trailDescriptorLayout, voxelDescriptorSetLayout }
});
auto voxelDescriptorSet = core.createDescriptorSet(voxelDescriptorSetLayout);
{
vkcv::DescriptorWrites writes;
writes.writeStorageImage(0, voxelRed.getHandle());
writes.writeStorageImage(1, voxelGreen.getHandle());
writes.writeStorageImage(2, voxelBlue.getHandle());
writes.writeStorageImage(3, voxelDensity.getHandle());
core.writeDescriptorSet(voxelDescriptorSet, writes);
}
vkcv::effects::BloomAndFlaresEffect bloomAndFlares (core);
bloomAndFlares.setUpsamplingLimit(3);
......@@ -707,7 +794,7 @@ int main(int argc, const char **argv) {
vkcv::DescriptorSetHandle addDescriptor = core.createDescriptorSet(addDescriptorLayout);
vkcv::ComputePipelineHandle addPipe = core.createComputePipeline({
addShader,
{ addDescriptorLayout }
{ addDescriptorLayout, voxelDescriptorSetLayout }
});
vkcv::ShaderProgram tonemappingShader;
......@@ -760,6 +847,11 @@ int main(int argc, const char **argv) {
std::cout << time_values[0] << " " << time_values[1] << std::endl;
voxelRed.fill(zeroVoxel.data());
voxelGreen.fill(zeroVoxel.data());
voxelBlue.fill(zeroVoxel.data());
voxelDensity.fill(zeroVoxel.data());
auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics);
core.recordBufferMemoryBarrier(cmdStream, eventBuffer.getHandle());
......@@ -870,6 +962,27 @@ int main(int argc, const char **argv) {
);
core.recordEndDebugLabel(cmdStream);
vkcv::PushConstants pushConstantsVoxel (sizeof(glm::mat4));
pushConstantsVoxel.appendDrawcall(camera.getMVP());
core.recordBeginDebugLabel(cmdStream, "Particle voxel update", { 1.0f, 0.5f, 0.8f, 1.0f });
core.prepareImageForStorage(cmdStream, voxelRed.getHandle());
core.prepareImageForStorage(cmdStream, voxelGreen.getHandle());
core.prepareImageForStorage(cmdStream, voxelBlue.getHandle());
core.prepareImageForStorage(cmdStream, voxelDensity.getHandle());
core.recordComputeDispatchToCmdStream(
cmdStream,
voxelParticlePipeline,
particleDispatchCount,
{
vkcv::DescriptorSetUsage(0, descriptorSet),
vkcv::DescriptorSetUsage(1, voxelDescriptorSet)
},
pushConstantsVoxel
);
core.recordEndDebugLabel(cmdStream);
core.recordBufferMemoryBarrier(cmdStream, smokeBuffer.getHandle());
draw_smoke_t draw_smoke {
......@@ -892,6 +1005,24 @@ int main(int argc, const char **argv) {
);
core.recordEndDebugLabel(cmdStream);
core.recordBeginDebugLabel(cmdStream, "Smoke voxel update", { 1.0f, 0.7f, 0.8f, 1.0f });
core.prepareImageForStorage(cmdStream, voxelRed.getHandle());
core.prepareImageForStorage(cmdStream, voxelGreen.getHandle());
core.prepareImageForStorage(cmdStream, voxelBlue.getHandle());
core.prepareImageForStorage(cmdStream, voxelDensity.getHandle());
core.recordComputeDispatchToCmdStream(
cmdStream,
voxelSmokePipeline,
smokeDispatchCount,
{
vkcv::DescriptorSetUsage(0, smokeDescriptorSet),
vkcv::DescriptorSetUsage(1, voxelDescriptorSet)
},
pushConstantsVoxel
);
core.recordEndDebugLabel(cmdStream);
core.recordBufferMemoryBarrier(cmdStream, trailBuffer.getHandle());
core.recordBufferMemoryBarrier(cmdStream, pointBuffer.getHandle());
......@@ -907,6 +1038,24 @@ int main(int argc, const char **argv) {
);
core.recordEndDebugLabel(cmdStream);
core.recordBeginDebugLabel(cmdStream, "Trail voxel update", { 1.0f, 0.9f, 0.8f, 1.0f });
core.prepareImageForStorage(cmdStream, voxelRed.getHandle());
core.prepareImageForStorage(cmdStream, voxelGreen.getHandle());
core.prepareImageForStorage(cmdStream, voxelBlue.getHandle());
core.prepareImageForStorage(cmdStream, voxelDensity.getHandle());
core.recordComputeDispatchToCmdStream(
cmdStream,
voxelTrailPipeline,
trailDispatchCount,
{
vkcv::DescriptorSetUsage(0, trailDescriptorSet),
vkcv::DescriptorSetUsage(1, voxelDescriptorSet)
},
pushConstantsVoxel
);
core.recordEndDebugLabel(cmdStream);
core.recordBeginDebugLabel(cmdStream, "Add rendered images", { 0.5f, 0.5f, 1.0f, 1.0f });
vkcv::DescriptorWrites addDescriptorWrites;
......@@ -917,6 +1066,11 @@ int main(int argc, const char **argv) {
core.writeDescriptorSet(addDescriptor, addDescriptorWrites);
core.prepareImageForStorage(cmdStream, voxelRed.getHandle());
core.prepareImageForStorage(cmdStream, voxelGreen.getHandle());
core.prepareImageForStorage(cmdStream, voxelBlue.getHandle());
core.prepareImageForStorage(cmdStream, voxelDensity.getHandle());
uint32_t colorDispatchCount[3];
colorDispatchCount[0] = std::ceil(swapchainWidth / 8.f);
colorDispatchCount[1] = std::ceil(swapchainHeight / 8.f);
......@@ -926,7 +1080,10 @@ int main(int argc, const char **argv) {
cmdStream,
addPipe,
colorDispatchCount,
{vkcv::DescriptorSetUsage(0, addDescriptor) },
{
vkcv::DescriptorSetUsage(0, addDescriptor),
vkcv::DescriptorSetUsage(1, voxelDescriptorSet)
},
vkcv::PushConstants(0)
);
......
......@@ -470,8 +470,10 @@ namespace vkcv {
switch (format) {
case vk::Format::eR8Unorm:
return 1;
case vk::Format::eR16Unorm:
return 2;
case vk::Format::eR32Uint:
case vk::Format::eR8G8B8A8Srgb:
return 4;
case vk::Format::eR8G8B8A8Unorm:
return 4;
case vk::Format::eR16G16B16A16Sfloat:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment