From 350bd1477c463380a8df4ff4d383860ae41f646e Mon Sep 17 00:00:00 2001
From: Tobias Frisch <tfrisch@uni-koblenz.de>
Date: Fri, 28 Jan 2022 20:37:08 +0100
Subject: [PATCH] Added pipeline to render grid

Signed-off-by: Tobias Frisch <tfrisch@uni-koblenz.de>
---
 projects/wobble_bobble/shaders/grid.frag |  22 +++
 projects/wobble_bobble/shaders/grid.vert |  36 +++++
 projects/wobble_bobble/src/main.cpp      | 163 ++++++++++++++++++-----
 3 files changed, 184 insertions(+), 37 deletions(-)

diff --git a/projects/wobble_bobble/shaders/grid.frag b/projects/wobble_bobble/shaders/grid.frag
index e69de29b..0d616c03 100644
--- a/projects/wobble_bobble/shaders/grid.frag
+++ b/projects/wobble_bobble/shaders/grid.frag
@@ -0,0 +1,22 @@
+#version 450
+
+layout(location = 0) in vec2 passPos;
+layout(location = 1) in float passMass;
+
+layout(location = 0) out vec3 outColor;
+
+void main()	{
+    if (passMass <= 0.0f) {
+        discard;
+    }
+
+    const float value = length(passPos);
+
+    float z = sqrt(0.25 - value * value);
+
+    if (value < 0.5f) {
+        outColor = vec3(passPos.x + 0.5f, passPos.y + 0.5f, z * 2.0f);
+    } else {
+        discard;
+    }
+}
\ No newline at end of file
diff --git a/projects/wobble_bobble/shaders/grid.vert b/projects/wobble_bobble/shaders/grid.vert
index e69de29b..8acf8f26 100644
--- a/projects/wobble_bobble/shaders/grid.vert
+++ b/projects/wobble_bobble/shaders/grid.vert
@@ -0,0 +1,36 @@
+#version 450
+
+layout(set=0, binding=0, rgba32f) readonly uniform image3D gridImage;
+
+layout(location = 0) in vec2 vertexPos;
+
+layout(location = 0) out vec2 passPos;
+layout(location = 1) out float passMass;
+
+layout( push_constant ) uniform constants{
+    mat4 mvp;
+};
+
+void main()	{
+    ivec3 gridResolution = imageSize(gridImage);
+
+    ivec3 gridID = ivec3(
+        gl_InstanceIndex % gridResolution.x,
+        (gl_InstanceIndex / gridResolution.x) % gridResolution.y,
+        (gl_InstanceIndex / gridResolution.x / gridResolution.y) % gridResolution.z
+    );
+
+    vec3 position = (vec3(gridID) + vec3(0.5f)) / gridResolution;
+    float size = 1.0f / length(vec3(gridResolution));
+
+    vec4 gridData = imageLoad(gridImage, gridID);
+
+    float mass = gridData.w;
+
+    passPos = vertexPos;
+    passMass = mass;
+
+    // align voxel to face camera
+    gl_Position = mvp * vec4(position, 1);      // transform position into projected view space
+    gl_Position.xy += vertexPos * (size * 2.0f) * (mass * 100.0f);  // move position directly in view space
+}
\ No newline at end of file
diff --git a/projects/wobble_bobble/src/main.cpp b/projects/wobble_bobble/src/main.cpp
index dae4ecdb..575fc4a3 100644
--- a/projects/wobble_bobble/src/main.cpp
+++ b/projects/wobble_bobble/src/main.cpp
@@ -260,25 +260,56 @@ int main(int argc, const char **argv) {
 		core.writeDescriptorSet(updateParticlePositionsSets[0], writes);
 	}
 	
-	vkcv::ShaderProgram gfxProgram;
+	vkcv::ShaderProgram gfxProgramGrid;
+	
+	compiler.compile(
+			vkcv::ShaderStage::VERTEX,
+			"shaders/grid.vert",
+			[&gfxProgramGrid](vkcv::ShaderStage stage, const std::filesystem::path& path) {
+				gfxProgramGrid.addShader(stage, path);
+			}
+	);
+	
+	compiler.compile(
+			vkcv::ShaderStage::FRAGMENT,
+			"shaders/grid.frag",
+			[&gfxProgramGrid](vkcv::ShaderStage stage, const std::filesystem::path& path) {
+				gfxProgramGrid.addShader(stage, path);
+			}
+	);
+	
+	vkcv::ShaderProgram gfxProgramParticles;
 	
 	compiler.compile(
 			vkcv::ShaderStage::VERTEX,
 			"shaders/particle.vert",
-			[&gfxProgram](vkcv::ShaderStage stage, const std::filesystem::path& path) {
-				gfxProgram.addShader(stage, path);
+			[&gfxProgramParticles](vkcv::ShaderStage stage, const std::filesystem::path& path) {
+				gfxProgramParticles.addShader(stage, path);
 			}
 	);
 	
 	compiler.compile(
 			vkcv::ShaderStage::FRAGMENT,
 			"shaders/particle.frag",
-			[&gfxProgram](vkcv::ShaderStage stage, const std::filesystem::path& path) {
-				gfxProgram.addShader(stage, path);
+			[&gfxProgramParticles](vkcv::ShaderStage stage, const std::filesystem::path& path) {
+				gfxProgramParticles.addShader(stage, path);
 			}
 	);
 	
-	vkcv::PassConfig passConfig ({
+	vkcv::PassConfig passConfigGrid ({
+		vkcv::AttachmentDescription(
+				vkcv::AttachmentOperation::STORE,
+				vkcv::AttachmentOperation::CLEAR,
+				core.getSwapchain(windowHandle).getFormat()
+		),
+		vkcv::AttachmentDescription(
+				vkcv::AttachmentOperation::STORE,
+				vkcv::AttachmentOperation::CLEAR,
+				vk::Format::eD32Sfloat
+		)
+	});
+	
+	vkcv::PassConfig passConfigParticles ({
 		vkcv::AttachmentDescription(
 				vkcv::AttachmentOperation::STORE,
 				vkcv::AttachmentOperation::CLEAR,
@@ -291,35 +322,63 @@ int main(int argc, const char **argv) {
 		)
 	});
 	
-	vkcv::DescriptorSetLayoutHandle gfxSetLayout = core.createDescriptorSetLayout(
-			gfxProgram.getReflectedDescriptors().at(0)
+	vkcv::DescriptorSetLayoutHandle gfxSetLayoutGrid = core.createDescriptorSetLayout(
+			gfxProgramGrid.getReflectedDescriptors().at(0)
 	);
 	
-	vkcv::DescriptorSetHandle gfxSet = core.createDescriptorSet(gfxSetLayout);
+	vkcv::DescriptorSetHandle gfxSetGrid = core.createDescriptorSet(gfxSetLayoutGrid);
+	
+	{
+		vkcv::DescriptorWrites writes;
+		writes.storageImageWrites.push_back(vkcv::StorageImageDescriptorWrite(0, tmpGrid.getHandle()));
+		core.writeDescriptorSet(gfxSetGrid, writes);
+	}
+	
+	vkcv::DescriptorSetLayoutHandle gfxSetLayoutParticles = core.createDescriptorSetLayout(
+			gfxProgramParticles.getReflectedDescriptors().at(0)
+	);
+	
+	vkcv::DescriptorSetHandle gfxSetParticles = core.createDescriptorSet(gfxSetLayoutParticles);
 	
 	{
 		vkcv::DescriptorWrites writes;
 		writes.storageBufferWrites.push_back(vkcv::BufferDescriptorWrite(0, particles.getHandle()));
-		core.writeDescriptorSet(gfxSet, writes);
+		core.writeDescriptorSet(gfxSetParticles, writes);
 	}
 	
-	vkcv::PassHandle gfxPass = core.createPass(passConfig);
+	vkcv::PassHandle gfxPassGrid = core.createPass(passConfigGrid);
+	vkcv::PassHandle gfxPassParticles = core.createPass(passConfigParticles);
 	
-	vkcv::VertexLayout vertexLayout ({
-		vkcv::VertexBinding(0, gfxProgram.getVertexAttachments())
+	vkcv::VertexLayout vertexLayoutGrid ({
+		vkcv::VertexBinding(0, gfxProgramGrid.getVertexAttachments())
 	});
 	
-	vkcv::GraphicsPipelineConfig gfxPipelineConfig;
-	gfxPipelineConfig.m_ShaderProgram = gfxProgram;
-	gfxPipelineConfig.m_Width = windowWidth;
-	gfxPipelineConfig.m_Height = windowHeight;
-	gfxPipelineConfig.m_PassHandle = gfxPass;
-	gfxPipelineConfig.m_VertexLayout = vertexLayout;
-	gfxPipelineConfig.m_DescriptorLayouts = { gfxSetLayout };
-	gfxPipelineConfig.m_UseDynamicViewport = true;
-	gfxPipelineConfig.m_blendMode = vkcv::BlendMode::Additive;
+	vkcv::GraphicsPipelineConfig gfxPipelineConfigGrid;
+	gfxPipelineConfigGrid.m_ShaderProgram = gfxProgramGrid;
+	gfxPipelineConfigGrid.m_Width = windowWidth;
+	gfxPipelineConfigGrid.m_Height = windowHeight;
+	gfxPipelineConfigGrid.m_PassHandle = gfxPassGrid;
+	gfxPipelineConfigGrid.m_VertexLayout = vertexLayoutGrid;
+	gfxPipelineConfigGrid.m_DescriptorLayouts = { gfxSetLayoutGrid };
+	gfxPipelineConfigGrid.m_UseDynamicViewport = true;
+	gfxPipelineConfigGrid.m_blendMode = vkcv::BlendMode::Additive;
+	
+	vkcv::VertexLayout vertexLayoutParticles ({
+		vkcv::VertexBinding(0, gfxProgramParticles.getVertexAttachments())
+	});
+	
+	vkcv::GraphicsPipelineConfig gfxPipelineConfigParticles;
+	gfxPipelineConfigParticles.m_ShaderProgram = gfxProgramParticles;
+	gfxPipelineConfigParticles.m_Width = windowWidth;
+	gfxPipelineConfigParticles.m_Height = windowHeight;
+	gfxPipelineConfigParticles.m_PassHandle = gfxPassParticles;
+	gfxPipelineConfigParticles.m_VertexLayout = vertexLayoutParticles;
+	gfxPipelineConfigParticles.m_DescriptorLayouts = { gfxSetLayoutParticles };
+	gfxPipelineConfigParticles.m_UseDynamicViewport = true;
+	gfxPipelineConfigParticles.m_blendMode = vkcv::BlendMode::Additive;
 	
-	vkcv::GraphicsPipelineHandle gfxPipeline = core.createGraphicsPipeline(gfxPipelineConfig);
+	vkcv::GraphicsPipelineHandle gfxPipelineGrid = core.createGraphicsPipeline(gfxPipelineConfigGrid);
+	vkcv::GraphicsPipelineHandle gfxPipelineParticles = core.createGraphicsPipeline(gfxPipelineConfigParticles);
 	
 	vkcv::Buffer<glm::vec2> trianglePositions = core.createBuffer<glm::vec2>(vkcv::BufferType::VERTEX, 3);
 	trianglePositions.fill({
@@ -339,15 +398,24 @@ int main(int argc, const char **argv) {
 			triangleIndices.getCount()
 	);
 	
-	std::vector<vkcv::DrawcallInfo> drawcalls;
+	std::vector<vkcv::DrawcallInfo> drawcallsGrid;
 	
-	drawcalls.push_back(vkcv::DrawcallInfo(
+	drawcallsGrid.push_back(vkcv::DrawcallInfo(
 			triangleMesh,
-			{ vkcv::DescriptorSetUsage(0, core.getDescriptorSet(gfxSet).vulkanHandle) },
+			{ vkcv::DescriptorSetUsage(0, core.getDescriptorSet(gfxSetGrid).vulkanHandle) },
+			grid.getWidth() * grid.getHeight() * grid.getDepth()
+	));
+	
+	std::vector<vkcv::DrawcallInfo> drawcallsParticles;
+	
+	drawcallsParticles.push_back(vkcv::DrawcallInfo(
+			triangleMesh,
+			{ vkcv::DescriptorSetUsage(0, core.getDescriptorSet(gfxSetParticles).vulkanHandle) },
 			particles.getCount()
 	));
 	
 	bool initializedParticleVolumes = false;
+	bool renderGrid = false;
 	
 	auto start = std::chrono::system_clock::now();
 	auto current = start;
@@ -500,17 +568,36 @@ int main(int argc, const char **argv) {
 				depthBuffer
 		};
 		
-		core.recordBeginDebugLabel(cmdStream, "RENDER PARTICLES", { 0.13f, 0.20f, 0.22f, 1.0f });
-		core.recordDrawcallsToCmdStream(
-				cmdStream,
-				gfxPass,
-				gfxPipeline,
-				cameraPushConstants,
-				drawcalls,
-				renderTargets,
-				windowHandle
-		);
-		core.recordEndDebugLabel(cmdStream);
+		if (renderGrid) {
+			core.recordBeginDebugLabel(cmdStream, "RENDER GRID", { 0.13f, 0.20f, 0.22f, 1.0f });
+			core.prepareImageForStorage(cmdStream, tmpGrid.getHandle());
+			
+			core.recordDrawcallsToCmdStream(
+					cmdStream,
+					gfxPassGrid,
+					gfxPipelineGrid,
+					cameraPushConstants,
+					drawcallsGrid,
+					renderTargets,
+					windowHandle
+			);
+			
+			core.recordEndDebugLabel(cmdStream);
+		} else {
+			core.recordBeginDebugLabel(cmdStream, "RENDER PARTICLES", { 0.13f, 0.20f, 0.22f, 1.0f });
+			
+			core.recordDrawcallsToCmdStream(
+					cmdStream,
+					gfxPassParticles,
+					gfxPipelineParticles,
+					cameraPushConstants,
+					drawcallsParticles,
+					renderTargets,
+					windowHandle
+			);
+			
+			core.recordEndDebugLabel(cmdStream);
+		}
 		
 		core.prepareSwapchainImageForPresent(cmdStream);
 		core.submitCommandStream(cmdStream);
@@ -518,6 +605,8 @@ int main(int argc, const char **argv) {
 		gui.beginGUI();
 		
 		ImGui::Begin("Settings");
+		ImGui::Checkbox("Render Grid", &renderGrid);
+		
 		ImGui::End();
 		
 		gui.endGUI();
-- 
GitLab