mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-31 05:00:35 +00:00
[vulkan] Implement deferred emission (fullbrights)
That was... easier than expected. A little more tedious that I would have liked, but my scripting system isn't perfect (I suspect it's best suited as the output of a code generator), and the C side could do with a little more automation.
This commit is contained in:
parent
5173414d97
commit
4eecbe867d
8 changed files with 116 additions and 28 deletions
|
@ -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;
|
||||
|
|
|
@ -49,6 +49,7 @@ enum {
|
|||
enum {
|
||||
QFV_attachDepth,
|
||||
QFV_attachColor,
|
||||
QFV_attachEmission,
|
||||
QFV_attachNormal,
|
||||
QFV_attachPosition,
|
||||
QFV_attachOpaque,
|
||||
|
|
|
@ -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 = (
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue