diff --git a/include/QF/Vulkan/qf_lighting.h b/include/QF/Vulkan/qf_lighting.h index d2cee31ac..fab2ffc3d 100644 --- a/include/QF/Vulkan/qf_lighting.h +++ b/include/QF/Vulkan/qf_lighting.h @@ -37,7 +37,7 @@ #include "QF/Vulkan/command.h" #define LIGHTING_BUFFER_INFOS 1 -#define LIGHTING_IMAGE_INFOS 3 +#define LIGHTING_IMAGE_INFOS 4 typedef struct lightingframe_s { VkCommandBuffer cmd; diff --git a/include/QF/Vulkan/qf_vid.h b/include/QF/Vulkan/qf_vid.h index db423d014..5ac5dddd4 100644 --- a/include/QF/Vulkan/qf_vid.h +++ b/include/QF/Vulkan/qf_vid.h @@ -46,6 +46,16 @@ enum { QFV_NumPasses }; +enum { + QFV_attachDepth, + QFV_attachColor, + QFV_attachNormal, + QFV_attachPosition, + QFV_attachOpaque, + QFV_attachTranslucent, + QFV_attachSwapchain, +}; + struct vulkan_ctx_s; void Vulkan_DestroyFrames (struct vulkan_ctx_s *ctx); void Vulkan_CreateFrames (struct vulkan_ctx_s *ctx); diff --git a/libs/video/renderer/vulkan/deferred.plist b/libs/video/renderer/vulkan/deferred.plist index 0245906da..6eded7acb 100644 --- a/libs/video/renderer/vulkan/deferred.plist +++ b/libs/video/renderer/vulkan/deferred.plist @@ -12,7 +12,7 @@ mipLevels = 1; arrayLayers = 1; tiling = optimal; - usage = depth_stencil_attachment|input_attachment; + usage = depth_stencil_attachment|input_attachment|transient_attachment; initialLayout = undefined; }; color = { @@ -27,10 +27,10 @@ mipLevels = 1; arrayLayers = 1; tiling = optimal; - usage = color_attachment|input_attachment; + usage = color_attachment|input_attachment|transient_attachment; initialLayout = undefined; }; - normals = { + normal = { imageType = VK_IMAGE_TYPE_2D; format = r16g16b16a16_sfloat; samples = 1; @@ -42,7 +42,22 @@ mipLevels = 1; arrayLayers = 1; tiling = optimal; - usage = color_attachment|input_attachment; + usage = color_attachment|input_attachment|transient_attachment; + initialLayout = undefined; + }; + position = { + imageType = VK_IMAGE_TYPE_2D; + format = r32g32b32a32_sfloat; + samples = 1; + extent = { + width = $swapchain.extent.width; + height = $swapchain.extent.height; + depth = 1; + }; + mipLevels = 1; + arrayLayers = 1; + tiling = optimal; + usage = color_attachment|input_attachment|transient_attachment; initialLayout = undefined; }; opaque = { @@ -57,7 +72,7 @@ mipLevels = 1; arrayLayers = 1; tiling = optimal; - usage = color_attachment|input_attachment; + usage = color_attachment|input_attachment|transient_attachment; initialLayout = undefined; }; translucent = { @@ -72,7 +87,7 @@ mipLevels = 1; arrayLayers = 1; tiling = optimal; - usage = color_attachment|input_attachment; + usage = color_attachment|input_attachment|transient_attachment; initialLayout = undefined; }; }; @@ -109,10 +124,26 @@ layerCount = 1; }; }; - normals = { - image = normals; + normal = { + image = normal; viewType = VK_IMAGE_VIEW_TYPE_2D; - format = $properties.images.normals.format; + format = $properties.images.normal.format; + components = { + r = identity; + g = identity; + b = identity; + a = identity; + }; + subresourceRange = { + aspectMask = color; + levelCount = 1; + layerCount = 1; + }; + }; + position = { + image = position; + viewType = VK_IMAGE_VIEW_TYPE_2D; + format = $properties.images.position.format; components = { r = identity; g = identity; @@ -160,7 +191,7 @@ }; framebuffer = { renderPass = $properties.renderpass; - attachments = (depth, color, normals, opaque, translucent, + attachments = (depth, color, normal, position, opaque, translucent, "$swapchain.views[$swapImageIndex]"); width = $swapchain.extent.width; height = $swapchain.extent.height; @@ -169,7 +200,8 @@ clearValues = ( { depthStencil = { depth = 1; stencil = 0; }; }, { color = "[0, 0, 0, 1]"; }, // color - { color = "[0, 0, 0, 1]"; }, // normals + { color = "[0, 0, 0, 1]"; }, // normal + { color = "[0, 0, 0, 1]"; }, // position { color = "[0, 0, 0, 1]"; }, // opaque { color = "[0, 0, 0, 0]"; }, // translucent { color = "[0, 0, 0, 1]"; }, // swapchain @@ -197,7 +229,17 @@ finalLayout = color_attachment_optimal; }, { - format = $properties.images.normals.format; + format = $properties.images.normal.format; + samples = 1; + loadOp = dont_care; + storeOp = dont_care; + stencilLoadOp = dont_care; + stencilStoreOp = dont_care; + initialLayout = undefined; + finalLayout = color_attachment_optimal; + }, + { + format = $properties.images.position.format; samples = 1; loadOp = dont_care; storeOp = dont_care; @@ -252,16 +294,20 @@ attachment = 1; layout = color_attachment_optimal; }, - { // normals + { // normal attachment = 2; layout = color_attachment_optimal; }, + { // position + attachment = 3; + layout = color_attachment_optimal; + }, ); depthStencilAttachment = { attachment = 0; layout = depth_stencil_attachment_optimal; }; - preserveAttachments = (4); + preserveAttachments = (5); }, { // 2 lighting pipelineBindPoint = graphics; @@ -274,48 +320,52 @@ attachment = 1; layout = shader_read_only_optimal; }, - { // normals + { // normal attachment = 2; layout = shader_read_only_optimal; }, + { // position + attachment = 3; + layout = shader_read_only_optimal; + }, ); colorAttachments = ( { // opaque - attachment = 3; + attachment = 4; layout = color_attachment_optimal; }, ); - preserveAttachments = (4); + preserveAttachments = (5); }, { // 3 translucent pipelineBindPoint = graphics; colorAttachments = ( { // translucent - attachment = 4; + attachment = 5; layout = color_attachment_optimal; }, ); - preserveAttachments = (0, 1, 2, 3); + preserveAttachments = (0, 1, 2, 3, 4); }, { // 4 compose pipelineBindPoint = graphics; inputAttachments = ( { // opaque - attachment = 3; + attachment = 4; layout = shader_read_only_optimal; }, { // translucent - attachment = 4; + attachment = 5; layout = shader_read_only_optimal; }, ); colorAttachments = ( { // swapchain - attachment = 5; + attachment = 6; layout = color_attachment_optimal; }, ); - preserveAttachments = (0, 1, 2); + preserveAttachments = (0, 1, 2, 3); }, ); dependencies = ( diff --git a/libs/video/renderer/vulkan/qfpipeline.plist b/libs/video/renderer/vulkan/qfpipeline.plist index cb7cf82f9..446ed30c6 100644 --- a/libs/video/renderer/vulkan/qfpipeline.plist +++ b/libs/video/renderer/vulkan/qfpipeline.plist @@ -83,7 +83,7 @@ bindings = ( { type = input_attachment; - descriptorCount = "3z * $frames.size"; + descriptorCount = "4z * $frames.size"; }, ); }; @@ -132,7 +132,7 @@ binding = 0; descriptorType = uniform_buffer; descriptorCount = 1; - stageFlags = vertex; + stageFlags = vertex|geometry; }, { binding = 1; @@ -252,6 +252,12 @@ descriptorCount = 1; stageFlags = fragment; }, + { + binding = 3; + descriptorType = input_attachment; + descriptorCount = 1; + stageFlags = fragment; + }, ); }; lighting_lights = { @@ -499,6 +505,16 @@ alphaBlendOp = add; colorWriteMask = r|g|b|a; }, + { + blendEnable = false; + srcColorBlendFactor = src_alpha; + dstColorBlendFactor = one_minus_src_alpha; + colorBlendOp = add; + srcAlphaBlendFactor = src_alpha; + dstAlphaBlendFactor = one_minus_src_alpha; + alphaBlendOp = add; + colorWriteMask = r|g|b|a; + }, ); }; dynamic = { @@ -639,6 +655,16 @@ alphaBlendOp = add; colorWriteMask = r|g|b|a; }, + { + blendEnable = false; + srcColorBlendFactor = src_alpha; + dstColorBlendFactor = one_minus_src_alpha; + colorBlendOp = add; + srcAlphaBlendFactor = src_alpha; + dstAlphaBlendFactor = one_minus_src_alpha; + alphaBlendOp = add; + colorWriteMask = r|g|b|a; + }, { blendEnable = false; srcColorBlendFactor = src_alpha; diff --git a/libs/video/renderer/vulkan/shader/alias.vert b/libs/video/renderer/vulkan/shader/alias.vert index 871c3a0c0..a54b43674 100644 --- a/libs/video/renderer/vulkan/shader/alias.vert +++ b/libs/video/renderer/vulkan/shader/alias.vert @@ -18,7 +18,7 @@ layout (location = 3) in vec3 normalb; layout (location = 4) in vec2 uv; layout (location = 0) out vec2 st; -layout (location = 1) out vec3 position; +layout (location = 1) out vec4 position; layout (location = 2) out vec3 normal; void @@ -32,7 +32,7 @@ main (void) norm = mix (normala, normalb, blend); pos = (Model * vertex); gl_Position = Projection * (View * pos); - position = pos.xyz; + position = pos; normal = mat3 (Model) * norm; st = uv; } diff --git a/libs/video/renderer/vulkan/shader/alias_gbuf.frag b/libs/video/renderer/vulkan/shader/alias_gbuf.frag index 6ef33dd43..0808b87f7 100644 --- a/libs/video/renderer/vulkan/shader/alias_gbuf.frag +++ b/libs/video/renderer/vulkan/shader/alias_gbuf.frag @@ -11,11 +11,12 @@ layout (push_constant) uniform PushConstants { }; layout (location = 0) in vec2 st; -layout (location = 1) in vec3 position; +layout (location = 1) in vec4 position; layout (location = 2) in vec3 normal; layout (location = 0) out vec4 frag_color; layout (location = 1) out vec4 frag_normal; +layout (location = 2) out vec4 frag_position; void main (void) @@ -29,4 +30,5 @@ main (void) frag_color = c; frag_normal = vec4(normal, 1); + frag_position = position; } diff --git a/libs/video/renderer/vulkan/shader/bsp_gbuf.frag b/libs/video/renderer/vulkan/shader/bsp_gbuf.frag index 272499efa..e4578ce5e 100644 --- a/libs/video/renderer/vulkan/shader/bsp_gbuf.frag +++ b/libs/video/renderer/vulkan/shader/bsp_gbuf.frag @@ -15,9 +15,11 @@ layout (push_constant) uniform PushConstants { layout (location = 0) in vec4 tl_st; layout (location = 1) in vec3 direction; layout (location = 2) in vec3 normal; +layout (location = 3) in vec4 position; layout (location = 0) out vec4 frag_color; layout (location = 1) out vec4 frag_normal; +layout (location = 2) out vec4 frag_position; layout (constant_id = 0) const bool doWarp = false; layout (constant_id = 1) const bool doLight = true; @@ -123,4 +125,5 @@ main (void) } frag_color = c;//fogBlend (c); frag_normal = vec4 (normal, 0); + frag_position = position; } diff --git a/libs/video/renderer/vulkan/shader/bsp_gbuf.geom b/libs/video/renderer/vulkan/shader/bsp_gbuf.geom index f1107f759..bb46ae43a 100644 --- a/libs/video/renderer/vulkan/shader/bsp_gbuf.geom +++ b/libs/video/renderer/vulkan/shader/bsp_gbuf.geom @@ -1,5 +1,11 @@ #version 450 +layout (set = 0, binding = 0) uniform Matrices { + mat4 Projection; + mat4 View; + mat4 Sky; +}; + layout (triangles) in; layout (triangle_strip, max_vertices = 3) out; layout (location = 0) in vec4 v_tl_st[]; @@ -8,6 +14,7 @@ layout (location = 1) in vec3 v_direction[]; layout (location = 0) out vec4 tl_st; layout (location = 1) out vec3 direction; layout (location = 2) out vec3 normal; +layout (location = 3) out vec4 position; void main() @@ -16,13 +23,15 @@ main() vec3 b = gl_in[1].gl_Position.xyz; vec3 c = gl_in[2].gl_Position.xyz; - vec3 n = normalize (cross (b - a, c - a)); + vec3 n = normalize (cross (c - a, b - a)); for (int vert = 0; vert < 3; vert++) { - gl_Position = gl_in[vert].gl_Position; + vec4 p = gl_in[vert].gl_Position; + gl_Position = Projection * (View * (p)); tl_st = v_tl_st[vert]; direction = v_direction[vert]; normal = n; + position = p; EmitVertex (); } EndPrimitive (); diff --git a/libs/video/renderer/vulkan/shader/bsp_gbuf.vert b/libs/video/renderer/vulkan/shader/bsp_gbuf.vert index bb9e87e4a..abfb6c4e6 100644 --- a/libs/video/renderer/vulkan/shader/bsp_gbuf.vert +++ b/libs/video/renderer/vulkan/shader/bsp_gbuf.vert @@ -19,7 +19,8 @@ layout (location = 1) out vec3 direction; void main (void) { - gl_Position = Projection * (View * (Model * vertex)); + // geometry shader will take care of Projection and View + gl_Position = Model * vertex; direction = (Sky * vertex).xyz; tl_st = tl_uv; } diff --git a/libs/video/renderer/vulkan/shader/lighting.frag b/libs/video/renderer/vulkan/shader/lighting.frag index 555682645..89ea7940d 100644 --- a/libs/video/renderer/vulkan/shader/lighting.frag +++ b/libs/video/renderer/vulkan/shader/lighting.frag @@ -3,6 +3,7 @@ layout (input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput depth; layout (input_attachment_index = 1, set = 0, binding = 1) uniform subpassInput color; layout (input_attachment_index = 2, set = 0, binding = 2) uniform subpassInput normal; +layout (input_attachment_index = 3, set = 0, binding = 3) uniform subpassInput position; struct LightData { vec3 color; @@ -25,9 +26,12 @@ void main (void) { float d = subpassLoad (depth).r; - vec4 c; + vec3 c = subpassLoad (color).rgb; + vec3 n = subpassLoad (normal).rgb; + vec3 p = subpassLoad (position).rgb; - //c = vec4 (d, d, d, 1); - c = vec4 (subpassLoad (color).rgb, 1); - frag_color = c; + c = vec3 (d, d, d); + c = (n + 1)/2; + c = (p / 1024 + 1) / 2; + frag_color = vec4 (c, 1); } diff --git a/libs/video/renderer/vulkan/vulkan_compose.c b/libs/video/renderer/vulkan/vulkan_compose.c index e2748dcb3..fc7316ede 100644 --- a/libs/video/renderer/vulkan/vulkan_compose.c +++ b/libs/video/renderer/vulkan/vulkan_compose.c @@ -82,8 +82,10 @@ Vulkan_Compose_Draw (vulkan_ctx_t *ctx) dfunc->vkCmdBindPipeline (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, cctx->pipeline); - cframe->imageInfo[0].imageView = ctx->attachment_views->a[3]; - cframe->imageInfo[1].imageView = ctx->attachment_views->a[4]; + cframe->imageInfo[0].imageView + = ctx->attachment_views->a[QFV_attachOpaque]; + cframe->imageInfo[1].imageView + = ctx->attachment_views->a[QFV_attachTranslucent]; dfunc->vkUpdateDescriptorSets (device->dev, 2, cframe->descriptors, 0, 0); VkDescriptorSet sets[] = { diff --git a/libs/video/renderer/vulkan/vulkan_lighting.c b/libs/video/renderer/vulkan/vulkan_lighting.c index 604e7ff94..84c756cdc 100644 --- a/libs/video/renderer/vulkan/vulkan_lighting.c +++ b/libs/video/renderer/vulkan/vulkan_lighting.c @@ -82,10 +82,15 @@ Vulkan_Lighting_Draw (vulkan_ctx_t *ctx) dfunc->vkCmdBindPipeline (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, lctx->pipeline); - lframe->imageInfo[0].imageView = ctx->attachment_views->a[0]; - lframe->imageInfo[1].imageView = ctx->attachment_views->a[1]; - lframe->imageInfo[2].imageView = ctx->attachment_views->a[2]; - dfunc->vkUpdateDescriptorSets (device->dev, 3, lframe->descriptors+1, 0, 0); + lframe->imageInfo[0].imageView = ctx->attachment_views->a[QFV_attachDepth]; + lframe->imageInfo[1].imageView = ctx->attachment_views->a[QFV_attachColor]; + lframe->imageInfo[2].imageView + = ctx->attachment_views->a[QFV_attachNormal]; + lframe->imageInfo[3].imageView + = ctx->attachment_views->a[QFV_attachPosition]; + dfunc->vkUpdateDescriptorSets (device->dev, LIGHTING_IMAGE_INFOS, + lframe->descriptors + LIGHTING_BUFFER_INFOS, + 0, 0); VkDescriptorSet sets[] = { lframe->descriptors[1].dstSet,