diff --git a/include/vkcv/PipelineConfig.hpp b/include/vkcv/PipelineConfig.hpp index 1e00c5209118469a7dc6ff1eb1e3c98a3c6903a7..45539769e38d447cf6f283e6e9d2cdcbc9d78c22 100644 --- a/include/vkcv/PipelineConfig.hpp +++ b/include/vkcv/PipelineConfig.hpp @@ -15,6 +15,10 @@ namespace vkcv { enum class PrimitiveTopology{PointList, LineList, TriangleList }; + // add more as needed + // alternatively we could expose the blend factors directly + enum class BlendMode{ None, Additive }; + struct PipelineConfig { ShaderProgram m_ShaderProgram; uint32_t m_Width; @@ -25,6 +29,7 @@ namespace vkcv { bool m_UseDynamicViewport; bool m_UseConservativeRasterization = false; PrimitiveTopology m_PrimitiveTopology = PrimitiveTopology::TriangleList; + BlendMode m_blendMode = BlendMode::None; }; } \ No newline at end of file diff --git a/projects/particle_simulation/shaders/frag_space.spv b/projects/particle_simulation/shaders/frag_space.spv index f05bab5cddababb06332586007586fee842e51c2..8acf8a4295ba661f1b7a893d3c8dd508a4b168b6 100644 Binary files a/projects/particle_simulation/shaders/frag_space.spv and b/projects/particle_simulation/shaders/frag_space.spv differ diff --git a/projects/particle_simulation/shaders/frag_water.spv b/projects/particle_simulation/shaders/frag_water.spv index 0ce71df61bc127c7d057d290b78871593ee4f78e..406e44df35757621d0688d37bd93cb83f5f04c24 100644 Binary files a/projects/particle_simulation/shaders/frag_water.spv and b/projects/particle_simulation/shaders/frag_water.spv differ diff --git a/projects/particle_simulation/shaders/particleShading.inc b/projects/particle_simulation/shaders/particleShading.inc new file mode 100644 index 0000000000000000000000000000000000000000..b2d1832b9ccd6ba05a585b59bdfdedd4729e80f8 --- /dev/null +++ b/projects/particle_simulation/shaders/particleShading.inc @@ -0,0 +1,6 @@ +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 diff --git a/projects/particle_simulation/shaders/shader.vert b/projects/particle_simulation/shaders/shader.vert index 7884d09462c96027fbcec8c2d1f36a2b26a4e6d5..ad80a4e109ebdc71848221b23a6292f1fe8425b4 100644 --- a/projects/particle_simulation/shaders/shader.vert +++ b/projects/particle_simulation/shaders/shader.vert @@ -23,6 +23,7 @@ layout( push_constant ) uniform constants{ mat4 projection; }; +layout(location = 0) out vec2 passTriangleCoordinates; layout(location = 1) out vec3 passVelocity; layout(location = 2) out float passlifeTime; @@ -36,5 +37,9 @@ void main() // 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; + gl_Position = projection * positionView; + + // 0.01 corresponds to vertex position size in main + float normalizationDivider = 0.01; + passTriangleCoordinates = particle.xy / normalizationDivider; } \ No newline at end of file diff --git a/projects/particle_simulation/shaders/shader_space.frag b/projects/particle_simulation/shaders/shader_space.frag index 79c80c3befd377726f4c5c686d420535ed518123..a1da54038381e142f0d40de8c3314514fa37f543 100644 --- a/projects/particle_simulation/shaders/shader_space.frag +++ b/projects/particle_simulation/shaders/shader_space.frag @@ -1,6 +1,10 @@ #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; @@ -14,6 +18,7 @@ layout(set=0,binding=1) uniform uPosition{ vec2 position; } Position; + void main() { vec2 mouse = vec2(Position.position.x, Position.position.y); @@ -21,4 +26,9 @@ void main() float(passlifeTime < 2 && passlifeTime > 1) * vec4(1,passlifeTime * 0.5,0,0) + float(passlifeTime >= 2 && passlifeTime < 2.5f) * vec4(passlifeTime * 0.5,passlifeTime * 0.5,0,0) + float(passlifeTime >= 2.5f) * vec4(1,0,0,0); + + // make the triangle look like a circle + outColor *= circleFactor(passTriangleCoordinates); + // full color is achieved by additively blending many particles + outColor *= 0.5; } \ No newline at end of file diff --git a/projects/particle_simulation/shaders/shader_water.frag b/projects/particle_simulation/shaders/shader_water.frag index 3f817c1c0b4d759742a47481db6590349aea73f4..b0b4cc7050523d52fee25eb46401a9d32f67331d 100644 --- a/projects/particle_simulation/shaders/shader_water.frag +++ b/projects/particle_simulation/shaders/shader_water.frag @@ -1,6 +1,10 @@ #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; @@ -22,4 +26,9 @@ void main() float(passlifeTime < 2 && passlifeTime > 1) * vec4(0.3, 0.7,1,0) + float(passlifeTime >= 2 && passlifeTime < 4.f) * vec4(0.5,0.9,1,0) + float(passlifeTime >= 4.f) * vec4(0.9,1,1,0); + + // make the triangle look like a circle + outColor *= circleFactor(passTriangleCoordinates); + // full color is achieved by additively blending many particles + outColor *= 0.5; } diff --git a/projects/particle_simulation/shaders/vert.spv b/projects/particle_simulation/shaders/vert.spv index 0387f48623f02789d7b0cce0a06128996c0b3cb6..e5a23d663612f70bbbafca156f9a49215dc2fd72 100644 Binary files a/projects/particle_simulation/shaders/vert.spv and b/projects/particle_simulation/shaders/vert.spv differ diff --git a/projects/particle_simulation/src/main.cpp b/projects/particle_simulation/src/main.cpp index f26080368427a668db9e226d9fd8c99164bb235d..b2eb5bc59581795502c0b7df0ed63eca57df01d6 100644 --- a/projects/particle_simulation/src/main.cpp +++ b/projects/particle_simulation/src/main.cpp @@ -95,7 +95,7 @@ int main(int argc, const char **argv) { const vkcv::VertexLayout particleLayout(bindings); - const vkcv::PipelineConfig particlePipelineDefinition{ + vkcv::PipelineConfig particlePipelineDefinition{ particleShaderProgram, UINT32_MAX, UINT32_MAX, @@ -103,10 +103,11 @@ int main(int argc, const char **argv) { {particleLayout}, {core.getDescriptorSet(descriptorSet).layout}, true}; + particlePipelineDefinition.m_blendMode = vkcv::BlendMode::Additive; - const std::vector<glm::vec3> vertices = {glm::vec3(-0.005, 0.005, 0), - glm::vec3(0.005, 0.005, 0), - glm::vec3(0, -0.005, 0)}; + const std::vector<glm::vec3> vertices = {glm::vec3(-0.01, 0.01, 0), + glm::vec3(0.01, 0.01, 0), + glm::vec3(0, -0.01, 0)}; vertexBuffer.fill(vertices); diff --git a/src/vkcv/PipelineManager.cpp b/src/vkcv/PipelineManager.cpp index df36442efc2992bf16b6e82245ef9753dad95e5d..47694ab610e3af3a21b3781c8eb2ccd278a06afc 100644 --- a/src/vkcv/PipelineManager.cpp +++ b/src/vkcv/PipelineManager.cpp @@ -182,8 +182,11 @@ namespace vkcv VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT); + + // currently set to additive, if not disabled + // BlendFactors must be set as soon as additional BlendModes are added vk::PipelineColorBlendAttachmentState colorBlendAttachmentState( - false, + config.m_blendMode != BlendMode::None, vk::BlendFactor::eOne, vk::BlendFactor::eOne, vk::BlendOp::eAdd,