From 495882951400b4ce7741bd311a7d70b0e7afb3be Mon Sep 17 00:00:00 2001 From: Tobias Frisch <tfrisch@uni-koblenz.de> Date: Sun, 8 May 2022 23:06:53 +0200 Subject: [PATCH] Added red point rendering to clipping in skull demo Signed-off-by: Tobias Frisch <tfrisch@uni-koblenz.de> --- projects/head_demo/assets/shaders/clip.inc | 19 +++++++ projects/head_demo/assets/shaders/red.frag | 10 ++++ projects/head_demo/assets/shaders/shader.geom | 46 ++++----------- projects/head_demo/assets/shaders/wired.geom | 51 +++++++++++++++++ projects/head_demo/src/main.cpp | 57 ++++++++++++++++--- 5 files changed, 142 insertions(+), 41 deletions(-) create mode 100644 projects/head_demo/assets/shaders/clip.inc create mode 100644 projects/head_demo/assets/shaders/red.frag create mode 100644 projects/head_demo/assets/shaders/wired.geom diff --git a/projects/head_demo/assets/shaders/clip.inc b/projects/head_demo/assets/shaders/clip.inc new file mode 100644 index 00000000..edb5ac3c --- /dev/null +++ b/projects/head_demo/assets/shaders/clip.inc @@ -0,0 +1,19 @@ + +#define CLIP_SCALE 10000.0f + +vec4 clipPosition(vec4 pos) { + return vec4( + max(clipX, pos.x), + max(clipY, pos.y), + max(clipZ, pos.z), + 1.0f / CLIP_SCALE + ); +} + +vec4 clipByLimit(vec4 pos) { + if (pos.x / pos.w < clipLimit) { + return vec4(pos.xyz / pos.w, 1.0f); + } else { + return vec4(clipLimit, pos.y / pos.w, pos.z / pos.w, 1.0f); + } +} diff --git a/projects/head_demo/assets/shaders/red.frag b/projects/head_demo/assets/shaders/red.frag new file mode 100644 index 00000000..3991f939 --- /dev/null +++ b/projects/head_demo/assets/shaders/red.frag @@ -0,0 +1,10 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout(location = 0) in vec3 passNormal; + +layout(location = 0) out vec3 outColor; + +void main() { + outColor = (vec3(0.3f, 0, 0) + max(dot(passNormal, vec3(1.0f, -1.0f, 0.5f)), 0.0f) * vec3(0.7f, 0, 0)); +} \ No newline at end of file diff --git a/projects/head_demo/assets/shaders/shader.geom b/projects/head_demo/assets/shaders/shader.geom index 4dc5121b..275b300e 100644 --- a/projects/head_demo/assets/shaders/shader.geom +++ b/projects/head_demo/assets/shaders/shader.geom @@ -1,5 +1,6 @@ #version 450 #extension GL_ARB_separate_shader_objects : enable +#extension GL_GOOGLE_include_directive : enable layout(triangles) in; layout(triangle_strip, max_vertices = 3) out; @@ -19,24 +20,7 @@ layout( push_constant ) uniform constants{ mat4 mvp; }; -#define CLIP_SCALE 10000.0f - -vec4 clipPosition(vec4 pos) { - return vec4( - min(clipX, pos.x), - min(clipY, pos.y), - min(clipZ, pos.z), - 1.0f / CLIP_SCALE - ); -} - -vec4 clipByLimit(vec4 pos) { - if (pos.x / pos.w < clipLimit) { - return vec4(pos.xyz / pos.w, 1.0f); - } else { - return vec4(clipLimit, pos.y / pos.w, pos.z / pos.w, 1.0f); - } -} +#include "clip.inc" void main() { vec4 v0 = gl_in[0].gl_Position; @@ -52,24 +36,18 @@ void main() { float dz = abs(v0.z - clipZ) + abs(v1.z - clipZ) + abs(v2.z - clipZ); if (dx * dy * dz > 0.0f) { - v0 = clipByLimit(mvp * (v0 * CLIP_SCALE)); - v1 = clipByLimit(mvp * (v1 * CLIP_SCALE)); - v2 = clipByLimit(mvp * (v2 * CLIP_SCALE)); - - if ((v0.x < clipLimit) || (v1.x < clipLimit) || (v2.x < clipLimit)) { - gl_Position = v0; - passNormal = geomNormal[0]; - EmitVertex(); + gl_Position = mvp * (v0 * CLIP_SCALE); + passNormal = geomNormal[0]; + EmitVertex(); - gl_Position = v1; - passNormal = geomNormal[1]; - EmitVertex(); + gl_Position = mvp * (v1 * CLIP_SCALE); + passNormal = geomNormal[1]; + EmitVertex(); - gl_Position = v2; - passNormal = geomNormal[2]; - EmitVertex(); + gl_Position = mvp * (v2 * CLIP_SCALE); + passNormal = geomNormal[2]; + EmitVertex(); - EndPrimitive(); - } + EndPrimitive(); } } diff --git a/projects/head_demo/assets/shaders/wired.geom b/projects/head_demo/assets/shaders/wired.geom new file mode 100644 index 00000000..00633605 --- /dev/null +++ b/projects/head_demo/assets/shaders/wired.geom @@ -0,0 +1,51 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_GOOGLE_include_directive : enable + +layout(triangles) in; +layout(points, max_vertices = 1) out; + +layout(location = 0) in vec3 geomNormal[]; + +layout(location = 0) out vec3 passNormal; + +layout(set=1, binding=0) uniform clipBuffer { + float clipLimit; + float clipX; + float clipY; + float clipZ; +}; + +layout( push_constant ) uniform constants{ + mat4 mvp; +}; + +#include "clip.inc" + +void main() { + vec4 v0 = gl_in[0].gl_Position; + vec4 v1 = gl_in[1].gl_Position; + vec4 v2 = gl_in[2].gl_Position; + + v0 = clipPosition(v0 / CLIP_SCALE); + v1 = clipPosition(v1 / CLIP_SCALE); + v2 = clipPosition(v2 / CLIP_SCALE); + + float dx = abs(v0.x - clipX) + abs(v1.x - clipX) + abs(v2.x - clipX); + float dy = abs(v0.y - clipY) + abs(v1.y - clipY) + abs(v2.y - clipY); + float dz = abs(v0.z - clipZ) + abs(v1.z - clipZ) + abs(v2.z - clipZ); + + if (dx * dy * dz <= 0.0f) { + v0 = clipByLimit(mvp * gl_in[0].gl_Position); + v1 = clipByLimit(mvp * gl_in[1].gl_Position); + v2 = clipByLimit(mvp * gl_in[2].gl_Position); + + if ((v0.x < clipLimit) || (v1.x < clipLimit) || (v2.x < clipLimit)) { + gl_Position = (v0 + v1 + v2) / 3; + passNormal = (geomNormal[0] + geomNormal[1] + geomNormal[2]) / 3; + EmitVertex(); + + EndPrimitive(); + } + } +} diff --git a/projects/head_demo/src/main.cpp b/projects/head_demo/src/main.cpp index 7acad116..c25ed49f 100644 --- a/projects/head_demo/src/main.cpp +++ b/projects/head_demo/src/main.cpp @@ -38,27 +38,43 @@ int main(int argc, const char** argv) { argc > 1 ? argv[1] : "assets/skull_scaled/scene.gltf" )); - const vkcv::AttachmentDescription present_color_attachment( + const vkcv::AttachmentDescription present_color_attachment0( vkcv::AttachmentOperation::STORE, vkcv::AttachmentOperation::CLEAR, core.getSwapchain(windowHandle).getFormat() ); - const vkcv::AttachmentDescription depth_attachment( + const vkcv::AttachmentDescription depth_attachment0( vkcv::AttachmentOperation::STORE, vkcv::AttachmentOperation::CLEAR, vk::Format::eD32Sfloat ); - vkcv::PassConfig scenePassDefinition({ present_color_attachment, depth_attachment }); + vkcv::PassConfig scenePassDefinition({ present_color_attachment0, depth_attachment0 }); vkcv::PassHandle scenePass = core.createPass(scenePassDefinition); - if (!scenePass) { + const vkcv::AttachmentDescription present_color_attachment1( + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::LOAD, + core.getSwapchain(windowHandle).getFormat() + ); + + const vkcv::AttachmentDescription depth_attachment1( + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::LOAD, + vk::Format::eD32Sfloat + ); + + vkcv::PassConfig linePassDefinition({ present_color_attachment1, depth_attachment1 }); + vkcv::PassHandle linePass = core.createPass(linePassDefinition); + + if ((!scenePass) || (!linePass)) { std::cout << "Error. Could not create renderpass. Exiting." << std::endl; return EXIT_FAILURE; } vkcv::ShaderProgram sceneShaderProgram; + vkcv::ShaderProgram lineShaderProgram; vkcv::shader::GLSLCompiler compiler; compiler.compileProgram(sceneShaderProgram, { @@ -67,6 +83,12 @@ int main(int argc, const char** argv) { { vkcv::ShaderStage::FRAGMENT, "assets/shaders/shader.frag" } }, nullptr); + compiler.compileProgram(lineShaderProgram, { + { vkcv::ShaderStage::VERTEX, "assets/shaders/shader.vert" }, + { vkcv::ShaderStage::GEOMETRY, "assets/shaders/wired.geom" }, + { vkcv::ShaderStage::FRAGMENT, "assets/shaders/red.frag" } + }, nullptr); + const std::vector<vkcv::VertexAttachment> vertexAttachments = sceneShaderProgram.getVertexAttachments(); std::vector<vkcv::VertexBinding> bindings; for (size_t i = 0; i < vertexAttachments.size(); i++) { @@ -84,7 +106,7 @@ int main(int argc, const char** argv) { float clipZ = 0.0f; auto clipBuffer = core.createBuffer<float>(vkcv::BufferType::UNIFORM, 4); - clipBuffer.fill({ clipLimit, clipX, clipY, clipZ }); + clipBuffer.fill({ clipLimit, -clipX, -clipY, -clipZ }); vkcv::DescriptorWrites clipWrites; clipWrites.uniformBufferWrites = { @@ -128,9 +150,21 @@ int main(int argc, const char** argv) { { material0.getDescriptorSetLayout(), clipDescriptorSetLayout }, true }; + + const vkcv::GraphicsPipelineConfig linePipelineDefinition{ + lineShaderProgram, + UINT32_MAX, + UINT32_MAX, + linePass, + {sceneLayout}, + { material0.getDescriptorSetLayout(), clipDescriptorSetLayout }, + true + }; + vkcv::GraphicsPipelineHandle scenePipeline = core.createGraphicsPipeline(scenePipelineDefinition); + vkcv::GraphicsPipelineHandle linePipeline = core.createGraphicsPipeline(linePipelineDefinition); - if (!scenePipeline) { + if ((!scenePipeline) || (!linePipeline)) { std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl; return EXIT_FAILURE; } @@ -170,7 +204,7 @@ int main(int argc, const char** argv) { start = end; cameraManager.update(0.000001 * static_cast<double>(deltatime.count())); - clipBuffer.fill({ clipLimit, clipX, clipY, clipZ }); + clipBuffer.fill({ clipLimit, -clipX, -clipY, -clipZ }); const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, depthBuffer }; auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); @@ -193,6 +227,15 @@ int main(int argc, const char** argv) { renderTargets, windowHandle); + scene.recordDrawcalls(cmdStream, + cameraManager.getActiveCamera(), + linePass, + linePipeline, + sizeof(glm::mat4), + recordMesh, + renderTargets, + windowHandle); + core.prepareSwapchainImageForPresent(cmdStream); core.submitCommandStream(cmdStream); -- GitLab