[vulkan] Add a position buffer to the g-buffer

While I could reconstruct the position from the screen coords and depth,
this is easier and good enough for now. Reconstruction is an
optimization thing.
This commit is contained in:
Bill Currie 2021-02-25 13:46:33 +09:00
parent 4eb07220cd
commit 918c3af095
12 changed files with 154 additions and 42 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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 = (

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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 ();

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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[] = {

View file

@ -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,