diff --git a/include/QF/Vulkan/qf_lighting.h b/include/QF/Vulkan/qf_lighting.h index f6aa67a94..8541d367e 100644 --- a/include/QF/Vulkan/qf_lighting.h +++ b/include/QF/Vulkan/qf_lighting.h @@ -59,7 +59,7 @@ typedef struct qfv_light_buffer_s { } qfv_light_buffer_t; #define LIGHTING_BUFFER_INFOS 1 -#define LIGHTING_IMAGE_INFOS 4 +#define LIGHTING_IMAGE_INFOS 5 typedef struct lightingframe_s { VkCommandBuffer cmd; diff --git a/include/QF/Vulkan/qf_vid.h b/include/QF/Vulkan/qf_vid.h index 5ac5dddd4..e41d91890 100644 --- a/include/QF/Vulkan/qf_vid.h +++ b/include/QF/Vulkan/qf_vid.h @@ -49,6 +49,7 @@ enum { enum { QFV_attachDepth, QFV_attachColor, + QFV_attachEmission, QFV_attachNormal, QFV_attachPosition, QFV_attachOpaque, diff --git a/libs/video/renderer/vulkan/deferred.plist b/libs/video/renderer/vulkan/deferred.plist index 6eded7acb..229c24c10 100644 --- a/libs/video/renderer/vulkan/deferred.plist +++ b/libs/video/renderer/vulkan/deferred.plist @@ -30,6 +30,21 @@ usage = color_attachment|input_attachment|transient_attachment; initialLayout = undefined; }; + emission = { + imageType = VK_IMAGE_TYPE_2D; + format = r16g16b16a16_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; + }; normal = { imageType = VK_IMAGE_TYPE_2D; format = r16g16b16a16_sfloat; @@ -124,6 +139,22 @@ layerCount = 1; }; }; + emission = { + image = emission; + viewType = VK_IMAGE_VIEW_TYPE_2D; + format = $properties.images.emission.format; + components = { + r = identity; + g = identity; + b = identity; + a = identity; + }; + subresourceRange = { + aspectMask = color; + levelCount = 1; + layerCount = 1; + }; + }; normal = { image = normal; viewType = VK_IMAGE_VIEW_TYPE_2D; @@ -191,8 +222,8 @@ }; framebuffer = { renderPass = $properties.renderpass; - attachments = (depth, color, normal, position, opaque, translucent, - "$swapchain.views[$swapImageIndex]"); + attachments = (depth, color, emission, normal, position, opaque, + translucent, "$swapchain.views[$swapImageIndex]"); width = $swapchain.extent.width; height = $swapchain.extent.height; layers = 1; @@ -200,6 +231,7 @@ clearValues = ( { depthStencil = { depth = 1; stencil = 0; }; }, { color = "[0, 0, 0, 1]"; }, // color + { color = "[0, 0, 0, 1]"; }, // emission { color = "[0, 0, 0, 1]"; }, // normal { color = "[0, 0, 0, 1]"; }, // position { color = "[0, 0, 0, 1]"; }, // opaque @@ -228,6 +260,16 @@ initialLayout = undefined; finalLayout = color_attachment_optimal; }, + { + format = $properties.images.emission.format; + samples = 1; + loadOp = dont_care; + storeOp = dont_care; + stencilLoadOp = dont_care; + stencilStoreOp = dont_care; + initialLayout = undefined; + finalLayout = color_attachment_optimal; + }, { format = $properties.images.normal.format; samples = 1; @@ -294,20 +336,24 @@ attachment = 1; layout = color_attachment_optimal; }, - { // normal + { // emission attachment = 2; layout = color_attachment_optimal; }, - { // position + { // normal attachment = 3; layout = color_attachment_optimal; }, + { // position + attachment = 4; + layout = color_attachment_optimal; + }, ); depthStencilAttachment = { attachment = 0; layout = depth_stencil_attachment_optimal; }; - preserveAttachments = (5); + preserveAttachments = (6); }, { // 2 lighting pipelineBindPoint = graphics; @@ -320,52 +366,56 @@ attachment = 1; layout = shader_read_only_optimal; }, - { // normal + { // emission attachment = 2; layout = shader_read_only_optimal; }, - { // position + { // normal attachment = 3; layout = shader_read_only_optimal; }, + { // position + attachment = 4; + layout = shader_read_only_optimal; + }, ); colorAttachments = ( { // opaque - attachment = 4; + attachment = 5; layout = color_attachment_optimal; }, ); - preserveAttachments = (5); + preserveAttachments = (6); }, { // 3 translucent pipelineBindPoint = graphics; colorAttachments = ( { // translucent - attachment = 5; + attachment = 6; layout = color_attachment_optimal; }, ); - preserveAttachments = (0, 1, 2, 3, 4); + preserveAttachments = (0, 1, 2, 3, 4, 5); }, { // 4 compose pipelineBindPoint = graphics; inputAttachments = ( { // opaque - attachment = 4; + attachment = 5; layout = shader_read_only_optimal; }, { // translucent - attachment = 5; + attachment = 6; layout = shader_read_only_optimal; }, ); colorAttachments = ( { // swapchain - attachment = 6; + attachment = 7; layout = color_attachment_optimal; }, ); - preserveAttachments = (0, 1, 2, 3); + preserveAttachments = (0, 1, 2, 3, 4); }, ); dependencies = ( diff --git a/libs/video/renderer/vulkan/qfpipeline.plist b/libs/video/renderer/vulkan/qfpipeline.plist index 523edfbad..3e8f79274 100644 --- a/libs/video/renderer/vulkan/qfpipeline.plist +++ b/libs/video/renderer/vulkan/qfpipeline.plist @@ -83,7 +83,7 @@ bindings = ( { type = input_attachment; - descriptorCount = "4z * $frames.size"; + descriptorCount = "5z * $frames.size"; }, ); }; @@ -258,6 +258,12 @@ descriptorCount = 1; stageFlags = fragment; }, + { + binding = 4; + descriptorType = input_attachment; + descriptorCount = 1; + stageFlags = fragment; + }, ); }; lighting_lights = { @@ -515,6 +521,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 = { @@ -674,6 +690,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_gbuf.frag b/libs/video/renderer/vulkan/shader/alias_gbuf.frag index 0808b87f7..c9cc81db0 100644 --- a/libs/video/renderer/vulkan/shader/alias_gbuf.frag +++ b/libs/video/renderer/vulkan/shader/alias_gbuf.frag @@ -15,20 +15,24 @@ 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; +layout (location = 1) out vec4 frag_emission; +layout (location = 2) out vec4 frag_normal; +layout (location = 3) out vec4 frag_position; void main (void) { vec4 c; + vec4 e; int i; vec3 light = vec3 (0); c = texture (Skin, vec3 (st, 0)) * unpackUnorm4x8(base_color); c += texture (Skin, vec3 (st, 1)) * unpackUnorm4x8(colorA); c += texture (Skin, vec3 (st, 2)) * unpackUnorm4x8(colorB); + e = texture (Skin, vec3 (st, 3)); frag_color = c; + frag_emission = e; 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 e4578ce5e..c00c0d72d 100644 --- a/libs/video/renderer/vulkan/shader/bsp_gbuf.frag +++ b/libs/video/renderer/vulkan/shader/bsp_gbuf.frag @@ -18,8 +18,9 @@ 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 (location = 1) out vec4 frag_emission; +layout (location = 2) out vec4 frag_normal; +layout (location = 3) out vec4 frag_position; layout (constant_id = 0) const bool doWarp = false; layout (constant_id = 1) const bool doLight = true; @@ -107,7 +108,8 @@ sky_color (vec3 dir, float time) void main (void) { - vec4 c; + vec4 c = vec4 (0); + vec4 e; vec2 t_st = tl_st.xy; vec2 l_st = tl_st.zw; @@ -115,15 +117,16 @@ main (void) t_st = warp_st (t_st, time); } if (doSkyCube || doSkySheet) { - c = sky_color (direction, time); + e = sky_color (direction, time); } else { c = texture (Texture, t_st); if (doLight) { c *= vec4 (texture (LightMap, l_st).xyz, 1); } - c += texture (GlowMap, t_st); + e = texture (GlowMap, t_st); } frag_color = c;//fogBlend (c); + frag_emission = e; frag_normal = vec4 (normal, 0); frag_position = position; } diff --git a/libs/video/renderer/vulkan/shader/lighting.frag b/libs/video/renderer/vulkan/shader/lighting.frag index 98f5b20a6..86e496991 100644 --- a/libs/video/renderer/vulkan/shader/lighting.frag +++ b/libs/video/renderer/vulkan/shader/lighting.frag @@ -2,8 +2,9 @@ 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; +layout (input_attachment_index = 2, set = 0, binding = 2) uniform subpassInput emission; +layout (input_attachment_index = 3, set = 0, binding = 3) uniform subpassInput normal; +layout (input_attachment_index = 4, set = 0, binding = 4) uniform subpassInput position; struct LightData { vec3 color; @@ -47,6 +48,7 @@ main (void) { //float d = subpassLoad (depth).r; vec3 c = subpassLoad (color).rgb; + vec3 e = subpassLoad (emission).rgb; vec3 n = subpassLoad (normal).rgb; vec3 p = subpassLoad (position).rgb; vec3 light = vec3 (0); @@ -56,5 +58,5 @@ main (void) light += calc_light (lights[i], p, n); } } - frag_color = vec4 (c * light, 1); + frag_color = vec4 (c * light + e, 1); } diff --git a/libs/video/renderer/vulkan/vulkan_lighting.c b/libs/video/renderer/vulkan/vulkan_lighting.c index 56c14387a..69c6faa69 100644 --- a/libs/video/renderer/vulkan/vulkan_lighting.c +++ b/libs/video/renderer/vulkan/vulkan_lighting.c @@ -214,8 +214,10 @@ Vulkan_Lighting_Draw (vulkan_ctx_t *ctx) 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]; + = ctx->attachment_views->a[QFV_attachEmission]; lframe->imageInfo[3].imageView + = ctx->attachment_views->a[QFV_attachNormal]; + lframe->imageInfo[4].imageView = ctx->attachment_views->a[QFV_attachPosition]; dfunc->vkUpdateDescriptorSets (device->dev, LIGHTING_BUFFER_INFOS + LIGHTING_IMAGE_INFOS,