Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 119-graphicspipeline-refactoring
  • 129-projekte-und-assets-auslagern
  • 132-denoising-module
  • 143-ar-vr-support-via-openxr
  • 43-multi-threading
  • 91-compute-first-network
  • 95-arm64-raspberry-pi-4-support
  • develop
  • master
  • optimizations
  • 0.1.0
  • 0.2.0
12 results

Target

Select target project
  • vulkan2021/vkcv-framework
1 result
Select Git revision
  • 119-graphicspipeline-refactoring
  • 129-projekte-und-assets-auslagern
  • 132-denoising-module
  • 143-ar-vr-support-via-openxr
  • 43-multi-threading
  • 91-compute-first-network
  • 95-arm64-raspberry-pi-4-support
  • develop
  • master
  • optimizations
  • 0.1.0
  • 0.2.0
12 results
Show changes
Showing
with 1480 additions and 1 deletion
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(set=0, binding=0) uniform texture2D blurImage;
layout(set=0, binding=1) uniform texture2D lensImage;
layout(set=0, binding=2) uniform sampler linearSampler;
layout(set=0, binding=3, r11f_g11f_b10f) uniform image2D colorBuffer;
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
void main()
{
if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(colorBuffer)))){
return;
}
ivec2 pixel_coord = ivec2(gl_GlobalInvocationID.xy);
vec2 pixel_size = vec2(1.0f) / textureSize(sampler2D(blurImage, linearSampler), 0);
vec2 UV = pixel_coord.xy * pixel_size;
vec4 composite_color = vec4(0.0f);
vec3 blur_color = texture(sampler2D(blurImage, linearSampler), UV).rgb;
vec3 lens_color = texture(sampler2D(lensImage, linearSampler), UV).rgb;
vec3 main_color = imageLoad(colorBuffer, pixel_coord).rgb;
// composite blur and lens features
float bloom_weight = 0.01f;
float lens_weight = 0.f;
float main_weight = 1 - (bloom_weight + lens_weight);
composite_color.rgb = blur_color * bloom_weight +
lens_color * lens_weight +
main_color * main_weight;
imageStore(colorBuffer, pixel_coord, composite_color);
}
\ No newline at end of file
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(set=0, binding=0) uniform texture2D inBlurImage;
layout(set=0, binding=1) uniform sampler inImageSampler;
layout(set=0, binding=2, r11f_g11f_b10f) uniform writeonly image2D outBlurImage;
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
void main()
{
if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(outBlurImage)))){
return;
}
ivec2 pixel_coord = ivec2(gl_GlobalInvocationID.xy);
vec2 pixel_size = vec2(1.0f) / imageSize(outBlurImage);
vec2 UV = pixel_coord.xy * pixel_size;
vec2 UV_offset = UV + 0.5f * pixel_size;
vec2 color_fetches[13] = {
// center neighbourhood (RED)
vec2(-1, 1), // LT
vec2(-1, -1), // LB
vec2( 1, -1), // RB
vec2( 1, 1), // RT
vec2(-2, 2), // LT
vec2( 0, 2), // CT
vec2( 2, 2), // RT
vec2(0 ,-2), // LC
vec2(0 , 0), // CC
vec2(2, 0), // CR
vec2(-2, -2), // LB
vec2(0 , -2), // CB
vec2(2 , -2) // RB
};
float color_weights[13] = {
// 0.5f
1.f/8.f,
1.f/8.f,
1.f/8.f,
1.f/8.f,
// 0.125f
1.f/32.f,
1.f/16.f,
1.f/32.f,
// 0.25f
1.f/16.f,
1.f/8.f,
1.f/16.f,
// 0.125f
1.f/32.f,
1.f/16.f,
1.f/32.f
};
vec3 sampled_color = vec3(0.0f);
for(uint i = 0; i < 13; i++)
{
vec2 color_fetch = UV_offset + color_fetches[i] * pixel_size;
vec3 color = texture(sampler2D(inBlurImage, inImageSampler), color_fetch).rgb;
color *= color_weights[i];
sampled_color += color;
}
imageStore(outBlurImage, pixel_coord, vec4(sampled_color, 1.f));
}
\ No newline at end of file
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(set=0, binding=0) uniform texture2D blurBuffer;
layout(set=0, binding=1) uniform sampler linearSampler;
layout(set=0, binding=2, r11f_g11f_b10f) uniform image2D lensBuffer;
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
vec3 sampleColorChromaticAberration(vec2 _uv)
{
vec2 toCenter = (vec2(0.5) - _uv);
vec3 colorScales = vec3(-1, 0, 1);
float aberrationScale = 0.1;
vec3 scaleFactors = colorScales * aberrationScale;
float r = texture(sampler2D(blurBuffer, linearSampler), _uv + toCenter * scaleFactors.r).r;
float g = texture(sampler2D(blurBuffer, linearSampler), _uv + toCenter * scaleFactors.g).g;
float b = texture(sampler2D(blurBuffer, linearSampler), _uv + toCenter * scaleFactors.b).b;
return vec3(r, g, b);
}
// _uv assumed to be flipped UV coordinates!
vec3 ghost_vectors(vec2 _uv)
{
vec2 ghost_vec = (vec2(0.5f) - _uv);
const uint c_ghost_count = 64;
const float c_ghost_spacing = length(ghost_vec) / c_ghost_count;
ghost_vec *= c_ghost_spacing;
vec3 ret_color = vec3(0.0f);
for (uint i = 0; i < c_ghost_count; ++i)
{
// sample scene color
vec2 s_uv = fract(_uv + ghost_vec * vec2(i));
vec3 s = sampleColorChromaticAberration(s_uv);
// tint/weight
float d = distance(s_uv, vec2(0.5));
float weight = 1.0f - smoothstep(0.0f, 0.75f, d);
s *= weight;
ret_color += s;
}
ret_color /= c_ghost_count;
return ret_color;
}
vec3 halo(vec2 _uv)
{
const float c_aspect_ratio = float(imageSize(lensBuffer).x) / float(imageSize(lensBuffer).y);
const float c_radius = 0.6f;
const float c_halo_thickness = 0.1f;
vec2 halo_vec = vec2(0.5) - _uv;
//halo_vec.x /= c_aspect_ratio;
halo_vec = normalize(halo_vec);
//halo_vec.x *= c_aspect_ratio;
//vec2 w_uv = (_uv - vec2(0.5, 0.0)) * vec2(c_aspect_ratio, 1.0) + vec2(0.5, 0.0);
vec2 w_uv = _uv;
float d = distance(w_uv, vec2(0.5)); // distance to center
float distance_to_halo = abs(d - c_radius);
float halo_weight = 0.0f;
if(abs(d - c_radius) <= c_halo_thickness)
{
float distance_to_border = c_halo_thickness - distance_to_halo;
halo_weight = distance_to_border / c_halo_thickness;
//halo_weight = clamp((halo_weight / 0.4f), 0.0f, 1.0f);
halo_weight = pow(halo_weight, 2.0f);
//halo_weight = 1.0f;
}
return sampleColorChromaticAberration(_uv + halo_vec) * halo_weight;
}
void main()
{
if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(lensBuffer)))){
return;
}
ivec2 pixel_coord = ivec2(gl_GlobalInvocationID.xy);
vec2 pixel_size = vec2(1.0f) / imageSize(lensBuffer);
vec2 UV = pixel_coord.xy * pixel_size;
vec2 flipped_UV = vec2(1.0f) - UV;
vec3 color = vec3(0.0f);
color += ghost_vectors(flipped_UV);
color += halo(UV);
color *= 0.5f;
imageStore(lensBuffer, pixel_coord, vec4(color, 0.0f));
}
\ No newline at end of file
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(set=0, binding=0) uniform texture2D inUpsampleImage;
layout(set=0, binding=1) uniform sampler inImageSampler;
layout(set=0, binding=2, r11f_g11f_b10f) uniform image2D outUpsampleImage;
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
void main()
{
if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(outUpsampleImage)))){
return;
}
ivec2 pixel_coord = ivec2(gl_GlobalInvocationID.xy);
vec2 pixel_size = vec2(1.0f) / imageSize(outUpsampleImage);
vec2 UV = pixel_coord.xy * pixel_size;
const float gauss_kernel[3] = {1.f, 2.f, 1.f};
const float gauss_weight = 16.f;
vec3 sampled_color = vec3(0.f);
for(int i = -1; i <= 1; i++)
{
for(int j = -1; j <= 1; j++)
{
vec2 sample_location = UV + vec2(j, i) * pixel_size;
vec3 color = texture(sampler2D(inUpsampleImage, inImageSampler), sample_location).rgb;
color *= gauss_kernel[j+1];
color *= gauss_kernel[i+1];
color /= gauss_weight;
sampled_color += color;
}
}
//vec3 prev_color = imageLoad(outUpsampleImage, pixel_coord).rgb;
//float bloomRimStrength = 0.75f; // adjust this to change strength of bloom
//sampled_color = mix(prev_color, sampled_color, bloomRimStrength);
imageStore(outUpsampleImage, pixel_coord, vec4(sampled_color, 1.f));
}
\ No newline at end of file
float circleFactor(vec2 triangleCoordinates){
// percentage of distance from center to circle edge
float p = clamp((0.4 - length(triangleCoordinates)) / 0.4, 0, 1);
// remapping for nice falloff
return sqrt(p);
}
\ No newline at end of file
#version 460 core
#extension GL_ARB_separate_shader_objects : enable
layout(location = 0) in vec3 particle;
struct Particle
{
vec3 position;
float lifeTime;
vec3 velocity;
float padding_2;
vec3 reset_velocity;
float padding_3;
};
layout(std430, binding = 2) coherent buffer buffer_inParticle
{
Particle inParticle[];
};
layout( push_constant ) uniform constants{
mat4 view;
mat4 projection;
};
layout(location = 0) out vec2 passTriangleCoordinates;
layout(location = 1) out vec3 passVelocity;
layout(location = 2) out float passlifeTime;
void main()
{
int id = gl_InstanceIndex;
passVelocity = inParticle[id].velocity;
passlifeTime = inParticle[id].lifeTime;
// particle position in view space
vec4 positionView = view * vec4(inParticle[id].position, 1);
// by adding the triangle position in view space the mesh is always camera facing
positionView.xyz += particle;
// multiply with projection matrix for final position
gl_Position = projection * positionView;
// 0.01 corresponds to vertex position size in main
float normalizationDivider = 0.012;
passTriangleCoordinates = particle.xy / normalizationDivider;
}
\ No newline at end of file
#version 450 core
#extension GL_ARB_separate_shader_objects : enable
layout(local_size_x = 256) in;
struct Particle
{
vec3 position;
float lifeTime;
vec3 velocity;
float mass;
vec3 reset_velocity;
float _padding;
};
layout(std430, binding = 0) coherent buffer buffer_inParticle
{
Particle inParticle[];
};
layout( push_constant ) uniform constants{
float deltaTime;
float rand;
};
const int n = 4;
vec4 gravityPoint[n] = vec4[n](
vec4(-0.8, -0.5, 0.0, 3),
vec4(-0.4, 0.5, 0.8, 2),
vec4( 0.8, 0.8, -0.3, 4),
vec4( 0.5, -0.7, -0.5, 1)
);
const float G = 6.6743015e-11;
const float sim_d_factor = 10e11;
const float sim_g_factor = 10e30;
const float sim_t_factor = 5;
const float c = 299792458;
void main() {
uint id = gl_GlobalInvocationID.x;
inParticle[id].lifeTime -= deltaTime;
vec3 pos = inParticle[id].position;
vec3 vel = inParticle[id].velocity;
float mass = inParticle[id].mass;
if(inParticle[id].lifeTime < 0.f)
{
inParticle[id].lifeTime = 5.f * rand;
inParticle[id].mass *= rand;
pos = vec3(0);
vel *= rand;
}
for(int i = 0; i < n; i++)
{
vec3 d = (gravityPoint[i].xyz - pos) * sim_d_factor;
float r = length(d);
float g = G * (gravityPoint[i].w * sim_g_factor) / (r * r);
if (r > 0) {
vec3 dvel = (deltaTime * sim_t_factor) * g * (d / r);
vel = (vel + dvel) / (1.0 + dot(vel, dvel) / (c*c));
}
}
pos += vel * (deltaTime * sim_t_factor);
vec3 a_pos = abs(pos);
if ((a_pos.x > 2.0) || (a_pos.y > 2.0) || (a_pos.z > 2.0))
{
inParticle[id].lifeTime *= 0.9;
}
inParticle[id].position = pos;
inParticle[id].velocity = vel;
}
#version 450 core
#extension GL_ARB_separate_shader_objects : enable
layout(local_size_x = 256) in;
struct Particle
{
vec3 position;
float lifeTime;
vec3 velocity;
float padding_2;
vec3 reset_velocity;
float padding_3;
};
layout(std430, binding = 0) coherent buffer buffer_inParticle
{
Particle inParticle[];
};
layout( push_constant ) uniform constants{
float deltaTime;
float rand;
};
vec3 attraction(vec3 pos, vec3 attractPos)
{
vec3 delta = attractPos - pos;
const float damp = 0.5;
float dDampedDot = dot(delta, delta) + damp;
float invDist = 1.0f / sqrt(dDampedDot);
float invDistCubed = invDist*invDist*invDist;
return delta * invDistCubed * 0.0035;
}
vec3 repulsion(vec3 pos, vec3 attractPos)
{
vec3 delta = attractPos - pos;
float targetDistance = sqrt(dot(delta, delta));
return delta * (1.0 / (targetDistance * targetDistance * targetDistance)) * -0.000035;
}
const int n = 4;
vec3 gravity = vec3(0,-9.8,0);
vec3 gravityPoint[n] = vec3[n](vec3(-0.3, .5, -0.6),vec3(-0.2, 0.6, -0.3),vec3(.4, -0.4, 0.6),vec3(-.4, -0.4, -0.6));
//vec3 gravityPoint[n] = vec3[n](vec3(-0.5, 0.5, 0));
void main() {
uint id = gl_GlobalInvocationID.x;
inParticle[id].lifeTime -= deltaTime;
vec3 pos = inParticle[id].position;
vec3 vel = inParticle[id].velocity;
if(inParticle[id].lifeTime < 0.f)
{
inParticle[id].lifeTime = 5.f;
pos = vec3(0);
}
// inParticle[id].position += deltaTime * -normalize(max(2 - distance(inParticle[id].position,respawnPos),0.0) * respawnPos - inParticle[id].position);
for(int i = 0; i < n; i++)
{
vel += deltaTime * deltaTime * normalize(max(2 - distance(pos,gravityPoint[i]),0.1) * gravityPoint[i] - pos);
}
if((pos.x <= -2.0) || (pos.x > 2.0) || (pos.y <= -2.0) || (pos.y > 2.0)|| (pos.z <= -2.0) || (pos.z > 2.0)){
vel = (-vel * 0.1);
}
pos += normalize(vel) * deltaTime;
inParticle[id].position = pos;
float rand1 = rand;
inParticle[id].velocity = vel;
}
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_GOOGLE_include_directive : enable
#include "particleShading.inc"
layout(location = 0) in vec2 passTriangleCoordinates;
layout(location = 1) in vec3 passVelocity;
layout(location = 2) in float passlifeTime;
layout(location = 0) out vec3 outColor;
layout(set=0, binding=0) uniform uColor {
vec4 color;
} Color;
layout(set=0,binding=1) uniform uPosition{
vec2 position;
} Position;
void main()
{
vec2 mouse = vec2(Position.position.x, Position.position.y);
vec3 c0 = vec3(1, 1, 0.05);
vec3 c1 = vec3(1, passlifeTime * 0.5, 0.05);
vec3 c2 = vec3(passlifeTime * 0.5,passlifeTime * 0.5,0.05);
vec3 c3 = vec3(1, 0.05, 0.05);
if(passlifeTime < 1){
outColor = mix(c0, c1, passlifeTime );
}
else if(passlifeTime < 2){
outColor = mix(c1, c2, passlifeTime - 1);
}
else{
outColor = mix(c2, c3, clamp((passlifeTime - 2) * 0.5, 0, 1));
}
// make the triangle look like a circle
outColor *= circleFactor(passTriangleCoordinates);
// fade out particle shortly before it dies
outColor *= clamp(passlifeTime * 2, 0, 1);
}
\ No newline at end of file
#version 450 core
#extension GL_ARB_separate_shader_objects : enable
layout(local_size_x = 256) in;
struct Particle
{
vec3 position;
float lifeTime;
vec3 velocity;
float padding_2;
vec3 reset_velocity;
float padding_3;
};
layout(std430, binding = 0) coherent buffer buffer_inParticle
{
Particle inParticle[];
};
layout( push_constant ) uniform constants{
float deltaTime;
float rand;
};
vec3 attraction(vec3 pos, vec3 attractPos)
{
vec3 delta = attractPos - pos;
const float damp = 0.5;
float dDampedDot = dot(delta, delta) + damp;
float invDist = 1.0f / sqrt(dDampedDot);
float invDistCubed = invDist*invDist*invDist;
return delta * invDistCubed * 0.0035;
}
vec3 repulsion(vec3 pos, vec3 attractPos)
{
vec3 delta = attractPos - pos;
float targetDistance = sqrt(dot(delta, delta));
return delta * (1.0 / (targetDistance * targetDistance * targetDistance)) * -0.000035;
}
const int n = 3;
vec3 gravity = vec3(0,-9.8,0);
vec3 gravityPoint[n] = vec3[n](vec3(-0.5, 0.5, 0),vec3(0.5, 0.5, 0),vec3(0, -0.5, 0));
//vec3 gravityPoint[n] = vec3[n](vec3(-0.5, 0.5, 0));
void main() {
uint id = gl_GlobalInvocationID.x;
inParticle[id].lifeTime -= deltaTime;
vec3 pos = inParticle[id].position;
vec3 vel = inParticle[id].velocity;
if(inParticle[id].lifeTime < 0.f)
{
inParticle[id].lifeTime = 7.f;
pos = vec3(0);
vel = inParticle[id].reset_velocity;
inParticle[id].velocity = inParticle[id].reset_velocity;
}
// inParticle[id].position += deltaTime * -normalize(max(2 - distance(inParticle[id].position,respawnPos),0.0) * respawnPos - inParticle[id].position);
for(int i = 0; i < n; i++)
{
vel += deltaTime * deltaTime * deltaTime * normalize(max(2 - distance(pos,gravityPoint[i]),0.1) * gravityPoint[i] - pos);
}
//vec3 delta = respawnPos - pos;
//float targetDistane = sqrt(dot(delta,delta));
//vel += repulsion(pos, respawnPos);
//if((pos.x <= -1.0) || (pos.x > 1.0) || (pos.y <= -1.0) || (pos.y > 1.0)|| (pos.z <= -1.0) || (pos.z > 1.0))
vel = (-vel * 0.01);
if((pos.y <= -1.0) || (pos.y > 1.0)){
vel = reflect(vel, vec3(0,1,0));
}
pos += normalize(vel) * deltaTime;
inParticle[id].position = pos;
float weight = 1.0;
float rand1 = rand;
inParticle[id].velocity = vel;
}
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_GOOGLE_include_directive : enable
#include "particleShading.inc"
layout(location = 0) in vec2 passTriangleCoordinates;
layout(location = 1) in vec3 passVelocity;
layout(location = 2) in float passlifeTime;
layout(location = 0) out vec3 outColor;
layout(set=0, binding=0) uniform uColor {
vec4 color;
} Color;
layout(set=0,binding=1) uniform uPosition{
vec2 position;
} Position;
void main()
{
float normlt = 1-normalize(passlifeTime);
vec2 mouse = vec2(Position.position.x, Position.position.y);
vec3 c0 = vec3(0.2,0.5,1);
vec3 c1 = vec3(0.3, 0.7,1);
vec3 c2 = vec3(0.5,0.9,1);
vec3 c3 = vec3(0.9,1,1);
if(passlifeTime < 1){
outColor = mix(c0, c1, passlifeTime );
}
else if(passlifeTime < 2){
outColor = mix(c1, c2, passlifeTime - 1);
}
else{
outColor = mix(c2, c3, clamp((passlifeTime - 2) * 0.5, 0, 1));
}
// make the triangle look like a circle
outColor *= circleFactor(passTriangleCoordinates);
// fade out particle shortly before it dies
outColor *= clamp(passlifeTime * 2, 0, 1);
}
#version 440
layout(set=0, binding=0, rgba16f) uniform image2D inImage;
layout(set=0, binding=1, rgba8) uniform image2D outImage;
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
void main(){
if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(inImage)))){
return;
}
ivec2 uv = ivec2(gl_GlobalInvocationID.xy);
vec3 linearColor = imageLoad(inImage, uv).rgb;
vec3 tonemapped = linearColor / (dot(linearColor, vec3(0.21, 0.71, 0.08)) + 1); // reinhard tonemapping
vec3 gammaCorrected = pow(tonemapped, vec3(1.f / 2.2f));
imageStore(outImage, uv, vec4(gammaCorrected, 0.f));
}
\ No newline at end of file
#include "BloomAndFlares.hpp"
#include <vkcv/shader/GLSLCompiler.hpp>
BloomAndFlares::BloomAndFlares(
vkcv::Core *p_Core,
vk::Format colorBufferFormat,
uint32_t width,
uint32_t height) :
p_Core(p_Core),
m_ColorBufferFormat(colorBufferFormat),
m_Width(width),
m_Height(height),
m_LinearSampler(p_Core->createSampler(vkcv::SamplerFilterType::LINEAR,
vkcv::SamplerFilterType::LINEAR,
vkcv::SamplerMipmapMode::LINEAR,
vkcv::SamplerAddressMode::CLAMP_TO_EDGE)),
m_Blur(p_Core->createImage(colorBufferFormat, width, height, 1, true, true, false)),
m_LensFeatures(p_Core->createImage(colorBufferFormat, width, height, 1, false, true, false))
{
vkcv::shader::GLSLCompiler compiler;
// DOWNSAMPLE
vkcv::ShaderProgram dsProg;
compiler.compile(vkcv::ShaderStage::COMPUTE,
"shaders/bloom/downsample.comp",
[&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path)
{
dsProg.addShader(shaderStage, path);
});
for(uint32_t mipLevel = 0; mipLevel < m_Blur.getMipCount(); mipLevel++)
{
m_DownsampleDescSets.push_back(
p_Core->createDescriptorSet(dsProg.getReflectedDescriptors()[0]));
}
m_DownsamplePipe = p_Core->createComputePipeline(
dsProg, { p_Core->getDescriptorSet(m_DownsampleDescSets[0]).layout });
// UPSAMPLE
vkcv::ShaderProgram usProg;
compiler.compile(vkcv::ShaderStage::COMPUTE,
"shaders/bloom/upsample.comp",
[&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path)
{
usProg.addShader(shaderStage, path);
});
for(uint32_t mipLevel = 0; mipLevel < m_Blur.getMipCount(); mipLevel++)
{
m_UpsampleDescSets.push_back(
p_Core->createDescriptorSet(usProg.getReflectedDescriptors()[0]));
}
m_UpsamplePipe = p_Core->createComputePipeline(
usProg, { p_Core->getDescriptorSet(m_UpsampleDescSets[0]).layout });
// LENS FEATURES
vkcv::ShaderProgram lensProg;
compiler.compile(vkcv::ShaderStage::COMPUTE,
"shaders/bloom/lensFlares.comp",
[&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path)
{
lensProg.addShader(shaderStage, path);
});
m_LensFlareDescSet = p_Core->createDescriptorSet(lensProg.getReflectedDescriptors()[0]);
m_LensFlarePipe = p_Core->createComputePipeline(
lensProg, { p_Core->getDescriptorSet(m_LensFlareDescSet).layout });
// COMPOSITE
vkcv::ShaderProgram compProg;
compiler.compile(vkcv::ShaderStage::COMPUTE,
"shaders/bloom/composite.comp",
[&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path)
{
compProg.addShader(shaderStage, path);
});
m_CompositeDescSet = p_Core->createDescriptorSet(compProg.getReflectedDescriptors()[0]);
m_CompositePipe = p_Core->createComputePipeline(
compProg, { p_Core->getDescriptorSet(m_CompositeDescSet).layout });
}
void BloomAndFlares::execDownsamplePipe(const vkcv::CommandStreamHandle &cmdStream,
const vkcv::ImageHandle &colorAttachment)
{
auto dispatchCountX = static_cast<float>(m_Width) / 8.0f;
auto dispatchCountY = static_cast<float>(m_Height) / 8.0f;
// blur dispatch
uint32_t initialDispatchCount[3] = {
static_cast<uint32_t>(glm::ceil(dispatchCountX)),
static_cast<uint32_t>(glm::ceil(dispatchCountY)),
1
};
// downsample dispatch of original color attachment
p_Core->prepareImageForSampling(cmdStream, colorAttachment);
p_Core->prepareImageForStorage(cmdStream, m_Blur.getHandle());
vkcv::DescriptorWrites initialDownsampleWrites;
initialDownsampleWrites.sampledImageWrites = {vkcv::SampledImageDescriptorWrite(0, colorAttachment)};
initialDownsampleWrites.samplerWrites = {vkcv::SamplerDescriptorWrite(1, m_LinearSampler)};
initialDownsampleWrites.storageImageWrites = {vkcv::StorageImageDescriptorWrite(2, m_Blur.getHandle(), 0) };
p_Core->writeDescriptorSet(m_DownsampleDescSets[0], initialDownsampleWrites);
p_Core->recordComputeDispatchToCmdStream(
cmdStream,
m_DownsamplePipe,
initialDispatchCount,
{vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_DownsampleDescSets[0]).vulkanHandle)},
vkcv::PushConstantData(nullptr, 0));
// downsample dispatches of blur buffer's mip maps
float mipDispatchCountX = dispatchCountX;
float mipDispatchCountY = dispatchCountY;
for(uint32_t mipLevel = 1; mipLevel < std::min((uint32_t)m_DownsampleDescSets.size(), m_Blur.getMipCount()); mipLevel++)
{
// mip descriptor writes
vkcv::DescriptorWrites mipDescriptorWrites;
mipDescriptorWrites.sampledImageWrites = {vkcv::SampledImageDescriptorWrite(0, m_Blur.getHandle(), mipLevel - 1, true)};
mipDescriptorWrites.samplerWrites = {vkcv::SamplerDescriptorWrite(1, m_LinearSampler)};
mipDescriptorWrites.storageImageWrites = {vkcv::StorageImageDescriptorWrite(2, m_Blur.getHandle(), mipLevel) };
p_Core->writeDescriptorSet(m_DownsampleDescSets[mipLevel], mipDescriptorWrites);
// mip dispatch calculation
mipDispatchCountX /= 2.0f;
mipDispatchCountY /= 2.0f;
uint32_t mipDispatchCount[3] = {
static_cast<uint32_t>(glm::ceil(mipDispatchCountX)),
static_cast<uint32_t>(glm::ceil(mipDispatchCountY)),
1
};
if(mipDispatchCount[0] == 0)
mipDispatchCount[0] = 1;
if(mipDispatchCount[1] == 0)
mipDispatchCount[1] = 1;
// mip blur dispatch
p_Core->recordComputeDispatchToCmdStream(
cmdStream,
m_DownsamplePipe,
mipDispatchCount,
{vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_DownsampleDescSets[mipLevel]).vulkanHandle)},
vkcv::PushConstantData(nullptr, 0));
// image barrier between mips
p_Core->recordImageMemoryBarrier(cmdStream, m_Blur.getHandle());
}
}
void BloomAndFlares::execUpsamplePipe(const vkcv::CommandStreamHandle &cmdStream)
{
// upsample dispatch
p_Core->prepareImageForStorage(cmdStream, m_Blur.getHandle());
const uint32_t upsampleMipLevels = std::min(
static_cast<uint32_t>(m_UpsampleDescSets.size() - 1),
static_cast<uint32_t>(3)
);
// upsample dispatch for each mip map
for(uint32_t mipLevel = upsampleMipLevels; mipLevel > 0; mipLevel--)
{
// mip descriptor writes
vkcv::DescriptorWrites mipUpsampleWrites;
mipUpsampleWrites.sampledImageWrites = {vkcv::SampledImageDescriptorWrite(0, m_Blur.getHandle(), mipLevel, true)};
mipUpsampleWrites.samplerWrites = {vkcv::SamplerDescriptorWrite(1, m_LinearSampler)};
mipUpsampleWrites.storageImageWrites = {vkcv::StorageImageDescriptorWrite(2, m_Blur.getHandle(), mipLevel - 1) };
p_Core->writeDescriptorSet(m_UpsampleDescSets[mipLevel], mipUpsampleWrites);
auto mipDivisor = glm::pow(2.0f, static_cast<float>(mipLevel) - 1.0f);
auto upsampleDispatchX = static_cast<float>(m_Width) / mipDivisor;
auto upsampleDispatchY = static_cast<float>(m_Height) / mipDivisor;
upsampleDispatchX /= 8.0f;
upsampleDispatchY /= 8.0f;
const uint32_t upsampleDispatchCount[3] = {
static_cast<uint32_t>(glm::ceil(upsampleDispatchX)),
static_cast<uint32_t>(glm::ceil(upsampleDispatchY)),
1
};
p_Core->recordComputeDispatchToCmdStream(
cmdStream,
m_UpsamplePipe,
upsampleDispatchCount,
{vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_UpsampleDescSets[mipLevel]).vulkanHandle)},
vkcv::PushConstantData(nullptr, 0)
);
// image barrier between mips
p_Core->recordImageMemoryBarrier(cmdStream, m_Blur.getHandle());
}
}
void BloomAndFlares::execLensFeaturePipe(const vkcv::CommandStreamHandle &cmdStream)
{
// lens feature generation descriptor writes
p_Core->prepareImageForSampling(cmdStream, m_Blur.getHandle());
p_Core->prepareImageForStorage(cmdStream, m_LensFeatures.getHandle());
vkcv::DescriptorWrites lensFeatureWrites;
lensFeatureWrites.sampledImageWrites = {vkcv::SampledImageDescriptorWrite(0, m_Blur.getHandle(), 0)};
lensFeatureWrites.samplerWrites = {vkcv::SamplerDescriptorWrite(1, m_LinearSampler)};
lensFeatureWrites.storageImageWrites = {vkcv::StorageImageDescriptorWrite(2, m_LensFeatures.getHandle(), 0)};
p_Core->writeDescriptorSet(m_LensFlareDescSet, lensFeatureWrites);
auto dispatchCountX = static_cast<float>(m_Width) / 8.0f;
auto dispatchCountY = static_cast<float>(m_Height) / 8.0f;
// lens feature generation dispatch
uint32_t lensFeatureDispatchCount[3] = {
static_cast<uint32_t>(glm::ceil(dispatchCountX)),
static_cast<uint32_t>(glm::ceil(dispatchCountY)),
1
};
p_Core->recordComputeDispatchToCmdStream(
cmdStream,
m_LensFlarePipe,
lensFeatureDispatchCount,
{vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_LensFlareDescSet).vulkanHandle)},
vkcv::PushConstantData(nullptr, 0));
}
void BloomAndFlares::execCompositePipe(const vkcv::CommandStreamHandle &cmdStream,
const vkcv::ImageHandle &colorAttachment)
{
p_Core->prepareImageForSampling(cmdStream, m_Blur.getHandle());
p_Core->prepareImageForSampling(cmdStream, m_LensFeatures.getHandle());
p_Core->prepareImageForStorage(cmdStream, colorAttachment);
// bloom composite descriptor write
vkcv::DescriptorWrites compositeWrites;
compositeWrites.sampledImageWrites = {vkcv::SampledImageDescriptorWrite(0, m_Blur.getHandle()),
vkcv::SampledImageDescriptorWrite(1, m_LensFeatures.getHandle())};
compositeWrites.samplerWrites = {vkcv::SamplerDescriptorWrite(2, m_LinearSampler)};
compositeWrites.storageImageWrites = {vkcv::StorageImageDescriptorWrite(3, colorAttachment)};
p_Core->writeDescriptorSet(m_CompositeDescSet, compositeWrites);
float dispatchCountX = static_cast<float>(m_Width) / 8.0f;
float dispatchCountY = static_cast<float>(m_Height) / 8.0f;
uint32_t compositeDispatchCount[3] = {
static_cast<uint32_t>(glm::ceil(dispatchCountX)),
static_cast<uint32_t>(glm::ceil(dispatchCountY)),
1
};
// bloom composite dispatch
p_Core->recordComputeDispatchToCmdStream(
cmdStream,
m_CompositePipe,
compositeDispatchCount,
{vkcv::DescriptorSetUsage(0, p_Core->getDescriptorSet(m_CompositeDescSet).vulkanHandle)},
vkcv::PushConstantData(nullptr, 0));
}
void BloomAndFlares::execWholePipeline(const vkcv::CommandStreamHandle &cmdStream,
const vkcv::ImageHandle &colorAttachment)
{
execDownsamplePipe(cmdStream, colorAttachment);
execUpsamplePipe(cmdStream);
execLensFeaturePipe(cmdStream);
execCompositePipe(cmdStream, colorAttachment);
}
void BloomAndFlares::updateImageDimensions(uint32_t width, uint32_t height)
{
m_Width = width;
m_Height = height;
p_Core->getContext().getDevice().waitIdle();
m_Blur = p_Core->createImage(m_ColorBufferFormat, m_Width, m_Height, 1, true, true, false);
m_LensFeatures = p_Core->createImage(m_ColorBufferFormat, m_Width, m_Height, 1, false, true, false);
}
#pragma once
#include <vkcv/Core.hpp>
#include <glm/glm.hpp>
class BloomAndFlares{
public:
BloomAndFlares(vkcv::Core *p_Core,
vk::Format colorBufferFormat,
uint32_t width,
uint32_t height);
void execWholePipeline(const vkcv::CommandStreamHandle &cmdStream, const vkcv::ImageHandle &colorAttachment);
void updateImageDimensions(uint32_t width, uint32_t height);
private:
vkcv::Core *p_Core;
vk::Format m_ColorBufferFormat;
uint32_t m_Width;
uint32_t m_Height;
vkcv::SamplerHandle m_LinearSampler;
vkcv::Image m_Blur;
vkcv::Image m_LensFeatures;
vkcv::PipelineHandle m_DownsamplePipe;
std::vector<vkcv::DescriptorSetHandle> m_DownsampleDescSets; // per mip desc set
vkcv::PipelineHandle m_UpsamplePipe;
std::vector<vkcv::DescriptorSetHandle> m_UpsampleDescSets; // per mip desc set
vkcv::PipelineHandle m_LensFlarePipe;
vkcv::DescriptorSetHandle m_LensFlareDescSet;
vkcv::PipelineHandle m_CompositePipe;
vkcv::DescriptorSetHandle m_CompositeDescSet;
void execDownsamplePipe(const vkcv::CommandStreamHandle &cmdStream, const vkcv::ImageHandle &colorAttachment);
void execUpsamplePipe(const vkcv::CommandStreamHandle &cmdStream);
void execLensFeaturePipe(const vkcv::CommandStreamHandle &cmdStream);
void execCompositePipe(const vkcv::CommandStreamHandle &cmdStream, const vkcv::ImageHandle &colorAttachment);
};
#include "Particle.hpp"
Particle::Particle(glm::vec3 position, glm::vec3 velocity, float lifeTime)
: m_position(position),
m_velocity(velocity),
m_lifeTime(lifeTime),
m_reset_velocity(velocity)
{}
const glm::vec3& Particle::getPosition()const{
return m_position;
}
const bool Particle::isAlive()const{
return m_lifeTime > 0.f;
}
void Particle::setPosition( const glm::vec3 pos ){
m_position = pos;
}
const glm::vec3& Particle::getVelocity()const{
return m_velocity;
}
void Particle::setVelocity( const glm::vec3 vel ){
m_velocity = vel;
}
void Particle::update( const float delta ){
m_position += m_velocity * delta;
}
void Particle::setLifeTime( const float lifeTime ){
m_lifeTime = lifeTime;
}
const float& Particle::getLifeTime()const{
return m_lifeTime;
}
\ No newline at end of file
#pragma once
#include <glm/glm.hpp>
class Particle {
public:
Particle(glm::vec3 position, glm::vec3 velocity, float lifeTime = 1.f);
const glm::vec3& getPosition()const;
void setPosition( const glm::vec3 pos );
const glm::vec3& getVelocity()const;
void setVelocity( const glm::vec3 vel );
void update( const float delta );
const bool isAlive()const;
void setLifeTime( const float lifeTime );
const float& getLifeTime()const;
private:
// all properties of the Particle
glm::vec3 m_position;
float m_lifeTime;
glm::vec3 m_velocity;
float mass = 1.f;
glm::vec3 m_reset_velocity;
float padding_3 = 0.f;
};
#include "ParticleSystem.hpp"
ParticleSystem::ParticleSystem(uint32_t particleCount ,glm::vec3 minVelocity , glm::vec3 maxVelocity , glm::vec2 lifeTime )
{
m_rdmVel.resize(3);
m_rdmVel[0] = std::uniform_real_distribution<float>(minVelocity.x, maxVelocity.x);
m_rdmVel[1] = std::uniform_real_distribution<float>(minVelocity.y, maxVelocity.y);
m_rdmVel[2] = std::uniform_real_distribution<float>(minVelocity.z, maxVelocity.z);
m_rdmLifeTime = std::uniform_real_distribution<float>(lifeTime.x, lifeTime.y);
for(uint32_t i = 0; i < particleCount ;i++ ){
addParticle(Particle(m_respawnPos, getRandomVelocity(), getRandomLifeTime()));
}
}
const std::vector<Particle>& ParticleSystem::getParticles() const{
return m_particles;
}
void ParticleSystem::addParticle( const Particle particle ){
m_particles.push_back(particle);
}
void ParticleSystem::addParticles( const std::vector<Particle> particles ){
m_particles.insert(m_particles.end(), particles.begin(), particles.end());
}
void ParticleSystem::updateParticles( const float deltaTime ){
for(Particle& particle :m_particles){
bool alive = particle.isAlive();
particle.setPosition( particle.getPosition() * static_cast<float>(alive) + static_cast<float>(!alive) * m_respawnPos );
particle.setVelocity( particle.getVelocity() * static_cast<float>(alive) + static_cast<float>(!alive) * getRandomVelocity());
particle.setLifeTime( (particle.getLifeTime() * alive + !alive * getRandomLifeTime() ) - deltaTime );
particle.update(deltaTime);
}
}
glm::vec3 ParticleSystem::getRandomVelocity(){
return glm::vec3(m_rdmVel[0](m_rdmEngine), m_rdmVel[1](m_rdmEngine),m_rdmVel[2](m_rdmEngine));
}
float ParticleSystem::getRandomLifeTime(){
return m_rdmLifeTime(m_rdmEngine);
}
void ParticleSystem::setRespawnPos( const glm::vec3 respawnPos){
m_respawnPos = respawnPos;
}
void ParticleSystem::setRdmLifeTime( const glm::vec2 lifeTime ){
m_rdmLifeTime = std::uniform_real_distribution<float> (lifeTime.x,lifeTime.y);
}
void ParticleSystem::setRdmVelocity( glm::vec3 minVelocity, glm::vec3 maxVelocity ){
m_rdmVel[0] = std::uniform_real_distribution<float> (minVelocity.x,maxVelocity.x);
m_rdmVel[1] = std::uniform_real_distribution<float> (minVelocity.y,maxVelocity.y);
m_rdmVel[2] = std::uniform_real_distribution<float> (minVelocity.z,maxVelocity.z);
}
const glm::vec3 ParticleSystem::getRespawnPos() const{
return m_respawnPos;
}
#pragma once
#include <vector>
#include "Particle.hpp"
#include <random>
#include "vkcv/Buffer.hpp"
class ParticleSystem {
public:
ParticleSystem(uint32_t particleCount , glm::vec3 minVelocity = glm::vec3(0.f,0.f,0.f), glm::vec3 maxVelocity = glm::vec3(1.f,1.f,0.f), glm::vec2 lifeTime = glm::vec2(2.f,3.f));
const std::vector<Particle> &getParticles() const;
void updateParticles( const float deltaTime );
void setRespawnPos( const glm::vec3 respawnPos );
void setRdmLifeTime( const glm::vec2 lifeTime );
void setRdmVelocity( glm::vec3 minVelocity, glm::vec3 maxVelocity );
const glm::vec3 getRespawnPos() const;
private:
void addParticle( const Particle particle );
void addParticles( const std::vector<Particle> particles );
glm::vec3 getRandomVelocity();
float getRandomLifeTime();
std::vector<Particle> m_particles;
glm::vec3 m_respawnPos = glm::vec3(0.f);
std::vector<std::uniform_real_distribution<float>> m_rdmVel;
std::uniform_real_distribution<float> m_rdmLifeTime;
std::default_random_engine m_rdmEngine;
};
\ No newline at end of file
#include <iostream>
#include <vkcv/Core.hpp>
#include <GLFW/glfw3.h>
#include <vkcv/camera/CameraManager.hpp>
#include <chrono>
#include "ParticleSystem.hpp"
#include <random>
#include <glm/gtc/matrix_access.hpp>
#include <time.h>
#include <vkcv/shader/GLSLCompiler.hpp>
#include "BloomAndFlares.hpp"
int main(int argc, const char **argv) {
const char *applicationName = "Particlesystem";
uint32_t windowWidth = 800;
uint32_t windowHeight = 600;
vkcv::Window window = vkcv::Window::create(
applicationName,
windowWidth,
windowHeight,
true
);
vkcv::camera::CameraManager cameraManager(window);
vkcv::Core core = vkcv::Core::create(
window,
applicationName,
VK_MAKE_VERSION(0, 0, 1),
{vk::QueueFlagBits::eTransfer, vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute},
{},
{"VK_KHR_swapchain"}
);
auto particleIndexBuffer = core.createBuffer<uint16_t>(vkcv::BufferType::INDEX, 3,
vkcv::BufferMemoryType::DEVICE_LOCAL);
uint16_t indices[3] = {0, 1, 2};
particleIndexBuffer.fill(&indices[0], sizeof(indices));
vk::Format colorFormat = vk::Format::eR16G16B16A16Sfloat;
// an example attachment for passes that output to the window
const vkcv::AttachmentDescription present_color_attachment(
vkcv::AttachmentOperation::STORE,
vkcv::AttachmentOperation::CLEAR,
colorFormat);
vkcv::PassConfig particlePassDefinition({present_color_attachment});
vkcv::PassHandle particlePass = core.createPass(particlePassDefinition);
vkcv::PassConfig computePassDefinition({});
vkcv::PassHandle computePass = core.createPass(computePassDefinition);
if (!particlePass || !computePass)
{
std::cout << "Error. Could not create renderpass. Exiting." << std::endl;
return EXIT_FAILURE;
}
// use space or use water
bool useSpace = true;
vkcv::shader::GLSLCompiler compiler;
vkcv::ShaderProgram computeShaderProgram{};
compiler.compile(vkcv::ShaderStage::COMPUTE, useSpace ? "shaders/shader_space.comp" : "shaders/shader_water.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
computeShaderProgram.addShader(shaderStage, path);
});
vkcv::DescriptorSetHandle computeDescriptorSet = core.createDescriptorSet(computeShaderProgram.getReflectedDescriptors()[0]);
const std::vector<vkcv::VertexAttachment> computeVertexAttachments = computeShaderProgram.getVertexAttachments();
std::vector<vkcv::VertexBinding> computeBindings;
for (size_t i = 0; i < computeVertexAttachments.size(); i++) {
computeBindings.push_back(vkcv::VertexBinding(i, { computeVertexAttachments[i] }));
}
const vkcv::VertexLayout computeLayout(computeBindings);
vkcv::ShaderProgram particleShaderProgram{};
compiler.compile(vkcv::ShaderStage::VERTEX, "shaders/shader.vert", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
particleShaderProgram.addShader(shaderStage, path);
});
compiler.compile(vkcv::ShaderStage::FRAGMENT, useSpace ? "shaders/shader_space.frag" : "shaders/shader_water.frag", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
particleShaderProgram.addShader(shaderStage, path);
});
vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(
particleShaderProgram.getReflectedDescriptors()[0]);
vkcv::Buffer<glm::vec3> vertexBuffer = core.createBuffer<glm::vec3>(
vkcv::BufferType::VERTEX,
3
);
const std::vector<vkcv::VertexAttachment> vertexAttachments = particleShaderProgram.getVertexAttachments();
const std::vector<vkcv::VertexBufferBinding> vertexBufferBindings = {
vkcv::VertexBufferBinding(0, vertexBuffer.getVulkanHandle())};
std::vector<vkcv::VertexBinding> bindings;
for (size_t i = 0; i < vertexAttachments.size(); i++) {
bindings.push_back(vkcv::VertexBinding(i, {vertexAttachments[i]}));
}
const vkcv::VertexLayout particleLayout(bindings);
vkcv::PipelineConfig particlePipelineDefinition{
particleShaderProgram,
UINT32_MAX,
UINT32_MAX,
particlePass,
{particleLayout},
{core.getDescriptorSet(descriptorSet).layout},
true};
particlePipelineDefinition.m_blendMode = vkcv::BlendMode::Additive;
const std::vector<glm::vec3> vertices = {glm::vec3(-0.012, 0.012, 0),
glm::vec3(0.012, 0.012, 0),
glm::vec3(0, -0.012, 0)};
vertexBuffer.fill(vertices);
vkcv::PipelineHandle particlePipeline = core.createGraphicsPipeline(particlePipelineDefinition);
vkcv::PipelineHandle computePipeline = core.createComputePipeline(computeShaderProgram, {core.getDescriptorSet(computeDescriptorSet).layout} );
vkcv::Buffer<glm::vec4> color = core.createBuffer<glm::vec4>(
vkcv::BufferType::UNIFORM,
1
);
vkcv::Buffer<glm::vec2> position = core.createBuffer<glm::vec2>(
vkcv::BufferType::UNIFORM,
1
);
glm::vec3 minVelocity = glm::vec3(-0.1f,-0.1f,-0.1f);
glm::vec3 maxVelocity = glm::vec3(0.1f,0.1f,0.1f);
glm::vec2 lifeTime = glm::vec2(-1.f,8.f);
ParticleSystem particleSystem = ParticleSystem( 100000 , minVelocity, maxVelocity, lifeTime);
vkcv::Buffer<Particle> particleBuffer = core.createBuffer<Particle>(
vkcv::BufferType::STORAGE,
particleSystem.getParticles().size()
);
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())};
core.writeDescriptorSet(descriptorSet, setWrites);
vkcv::DescriptorWrites computeWrites;
computeWrites.storageBufferWrites = { vkcv::StorageBufferDescriptorWrite(0,particleBuffer.getHandle())};
core.writeDescriptorSet(computeDescriptorSet, computeWrites);
if (!particlePipeline || !computePipeline)
{
std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl;
return EXIT_FAILURE;
}
const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle();
const vkcv::Mesh renderMesh({vertexBufferBindings}, particleIndexBuffer.getVulkanHandle(),
particleIndexBuffer.getCount());
vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle);
//vkcv::DrawcallInfo drawcalls(renderMesh, {vkcv::DescriptorSetUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle)});
glm::vec2 pos = glm::vec2(0.f);
glm::vec3 spawnPosition = glm::vec3(0.f);
glm::vec4 tempPosition = glm::vec4(0.f);
window.e_mouseMove.add([&](double offsetX, double offsetY) {
pos = glm::vec2(static_cast<float>(offsetX), static_cast<float>(offsetY));
// std::cout << offsetX << " , " << offsetY << std::endl;
// borders are assumed to be 0.5
//pos = glm::vec2((pos.x -0.5f * static_cast<float>(window.getWidth()))/static_cast<float>(window.getWidth()), (pos.y -0.5f * static_cast<float>(window.getHeight()))/static_cast<float>(window.getHeight()));
//borders are assumed to be 1
pos.x = (-2 * pos.x + static_cast<float>(window.getWidth())) / static_cast<float>(window.getWidth());
pos.y = (-2 * pos.y + static_cast<float>(window.getHeight())) / static_cast<float>(window.getHeight());
glm::vec4 row1 = glm::row(cameraManager.getCamera(0).getView(), 0);
glm::vec4 row2 = glm::row(cameraManager.getCamera(0).getView(), 1);
glm::vec4 row3 = glm::row(cameraManager.getCamera(0).getView(), 2);
glm::vec4 camera_pos = glm::column(cameraManager.getCamera(0).getView(), 3);
// std::cout << "row1: " << row1.x << ", " << row1.y << ", " << row1.z << std::endl;
// std::cout << "row2: " << row2.x << ", " << row2.y << ", " << row2.z << std::endl;
// std::cout << "row3: " << row3.x << ", " << row3.y << ", " << row3.z << std::endl;
// std::cout << "camerapos: " << camera_pos.x << ", " << camera_pos.y << ", " << camera_pos.z << std::endl;
// std::cout << "camerapos: " << camera_pos.x << ", " << camera_pos.y << ", " << camera_pos.z << std::endl;
//glm::vec4 view_axis = glm::row(cameraManager.getCamera().getView(), 2);
// std::cout << "view_axis: " << view_axis.x << ", " << view_axis.y << ", " << view_axis.z << std::endl;
//std::cout << "Front: " << cameraManager.getCamera().getFront().x << ", " << cameraManager.getCamera().getFront().z << ", " << cameraManager.getCamera().getFront().z << std::endl;
glm::mat4 viewmat = cameraManager.getCamera(0).getView();
spawnPosition = glm::vec3(pos.x, pos.y, 0.f);
tempPosition = glm::vec4(spawnPosition, 1.0f);
spawnPosition = glm::vec3(tempPosition.x, tempPosition.y, tempPosition.z);
particleSystem.setRespawnPos(glm::vec3(-spawnPosition.x, spawnPosition.y, spawnPosition.z));
// std::cout << "respawn pos: " << spawnPosition.x << ", " << spawnPosition.y << ", " << spawnPosition.z << std::endl;
});
std::vector<glm::mat4> modelMatrices;
std::vector<vkcv::DrawcallInfo> drawcalls;
drawcalls.push_back(vkcv::DrawcallInfo(renderMesh, {descriptorUsage}, particleSystem.getParticles().size()));
auto start = std::chrono::system_clock::now();
glm::vec4 colorData = glm::vec4(1.0f, 1.0f, 0.0f, 1.0f);
uint32_t camIndex0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT);
uint32_t camIndex1 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL);
cameraManager.getCamera(camIndex0).setNearFar(0.1, 30);
cameraManager.getCamera(camIndex1).setNearFar(0.1, 30);
cameraManager.setActiveCamera(1);
cameraManager.getCamera(camIndex0).setPosition(glm::vec3(0, 0, -2));
cameraManager.getCamera(camIndex1).setPosition(glm::vec3(0.0f, 0.0f, -2.0f));
cameraManager.getCamera(camIndex1).setCenter(glm::vec3(0.0f, 0.0f, 0.0f));
vkcv::ImageHandle colorBuffer = core.createImage(colorFormat, windowWidth, windowHeight, 1, false, true, true).getHandle();
BloomAndFlares bloomAndFlares(&core, colorFormat, windowWidth, windowHeight);
window.e_resize.add([&](int width, int height) {
windowWidth = width;
windowHeight = height;
colorBuffer = core.createImage(colorFormat, windowWidth, windowHeight, 1, false, true, true).getHandle();
bloomAndFlares.updateImageDimensions(width, height);
});
vkcv::ShaderProgram tonemappingShader;
compiler.compile(vkcv::ShaderStage::COMPUTE, "shaders/tonemapping.comp", [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
tonemappingShader.addShader(shaderStage, path);
});
vkcv::DescriptorSetHandle tonemappingDescriptor = core.createDescriptorSet(tonemappingShader.getReflectedDescriptors()[0]);
vkcv::PipelineHandle tonemappingPipe = core.createComputePipeline(
tonemappingShader,
{ core.getDescriptorSet(tonemappingDescriptor).layout });
std::uniform_real_distribution<float> rdm = std::uniform_real_distribution<float>(0.95f, 1.05f);
std::default_random_engine rdmEngine;
while (window.isWindowOpen()) {
window.pollEvents();
uint32_t swapchainWidth, swapchainHeight;
if (!core.beginFrame(swapchainWidth, swapchainHeight)) {
continue;
}
color.fill(&colorData);
position.fill(&pos);
auto end = std::chrono::system_clock::now();
float deltatime = 0.000001 * static_cast<float>( std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() );
start = end;
// particleSystem.updateParticles(deltatime);
cameraManager.update(deltatime);
// split view and projection to allow for easy billboarding in shader
glm::mat4 renderingMatrices[2];
renderingMatrices[0] = cameraManager.getActiveCamera().getView();
renderingMatrices[1] = cameraManager.getActiveCamera().getProjection();
auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics);
float random = rdm(rdmEngine);
glm::vec2 pushData = glm::vec2(deltatime, random);
vkcv::PushConstantData pushConstantDataCompute( &pushData, sizeof(glm::vec2));
uint32_t computeDispatchCount[3] = {static_cast<uint32_t> (std::ceil(particleSystem.getParticles().size()/256.f)),1,1};
core.recordComputeDispatchToCmdStream(cmdStream,
computePipeline,
computeDispatchCount,
{vkcv::DescriptorSetUsage(0,core.getDescriptorSet(computeDescriptorSet).vulkanHandle)},
pushConstantDataCompute);
core.recordBufferMemoryBarrier(cmdStream, particleBuffer.getHandle());
vkcv::PushConstantData pushConstantDataDraw((void *) &renderingMatrices[0], 2 * sizeof(glm::mat4));
core.recordDrawcallsToCmdStream(
cmdStream,
particlePass,
particlePipeline,
pushConstantDataDraw,
{drawcalls},
{ colorBuffer });
bloomAndFlares.execWholePipeline(cmdStream, colorBuffer);
core.prepareImageForStorage(cmdStream, colorBuffer);
core.prepareImageForStorage(cmdStream, swapchainInput);
vkcv::DescriptorWrites tonemappingDescriptorWrites;
tonemappingDescriptorWrites.storageImageWrites = {
vkcv::StorageImageDescriptorWrite(0, colorBuffer),
vkcv::StorageImageDescriptorWrite(1, swapchainInput)
};
core.writeDescriptorSet(tonemappingDescriptor, tonemappingDescriptorWrites);
uint32_t tonemappingDispatchCount[3];
tonemappingDispatchCount[0] = std::ceil(windowWidth / 8.f);
tonemappingDispatchCount[1] = std::ceil(windowHeight / 8.f);
tonemappingDispatchCount[2] = 1;
core.recordComputeDispatchToCmdStream(
cmdStream,
tonemappingPipe,
tonemappingDispatchCount,
{vkcv::DescriptorSetUsage(0, core.getDescriptorSet(tonemappingDescriptor).vulkanHandle) },
vkcv::PushConstantData(nullptr, 0));
core.prepareSwapchainImageForPresent(cmdStream);
core.submitCommandStream(cmdStream);
core.endFrame();
}
return 0;
}
......@@ -13,7 +13,11 @@ add_executable(voxelization src/main.cpp)
target_sources(voxelization PRIVATE
src/Voxelization.hpp
src/Voxelization.cpp)
src/Voxelization.cpp
src/ShadowMapping.hpp
src/ShadowMapping.cpp
src/BloomAndFlares.hpp
src/BloomAndFlares.cpp)
# this should fix the execution path to load local files from the project (for MSVC)
if(MSVC)
......