[vulkan] Use the shadow matrices when rendering maps

It turns out bsp faces are still back-face culled despite the null point
being on the front of every possible plane... or really, because it's on
the front of every possible plane: sometimes the back face is the front
face, and this breaks the face selection code (a separate traversal
function will be needed for non-culling rendering).

Despite that, other than having to deal with different pipelines,
getting the model renderers working went better than expected.
This commit is contained in:
Bill Currie 2023-07-30 11:52:13 +09:00
parent aed1e7e077
commit ff27da4a05
10 changed files with 280 additions and 138 deletions

View File

@ -123,5 +123,7 @@ void Vulkan_Lighting_Init (struct vulkan_ctx_s *ctx);
void Vulkan_Lighting_Setup (struct vulkan_ctx_s *ctx); void Vulkan_Lighting_Setup (struct vulkan_ctx_s *ctx);
void Vulkan_Lighting_Shutdown (struct vulkan_ctx_s *ctx); void Vulkan_Lighting_Shutdown (struct vulkan_ctx_s *ctx);
void Vulkan_LoadLights (struct scene_s *scene, struct vulkan_ctx_s *ctx); void Vulkan_LoadLights (struct scene_s *scene, struct vulkan_ctx_s *ctx);
VkDescriptorSet Vulkan_Lighting_Descriptors (struct vulkan_ctx_s *ctx,
int frame) __attribute__((pure));
#endif//__QF_Vulkan_qf_lighting_h #endif//__QF_Vulkan_qf_lighting_h

View File

@ -232,6 +232,11 @@ properties = {
brush = { brush = {
shader = { shader = {
shadow_vertex = {
stage = vertex;
name = main;
module = $builtin/bsp_shadow.vert;
};
depth_vertex = { depth_vertex = {
stage = vertex; stage = vertex;
name = main; name = main;
@ -324,9 +329,22 @@ properties = {
}; };
}; };
}; };
shadow_layout = {
descriptorSets = (shadowmat_set, entity_set);
pushConstants = {
vertex = {
MatrixBase = uint;
};
};
};
}; };
alias = { alias = {
shader = { shader = {
shadow_vertex = {
stage = vertex;
name = main;
module = $builtin/alias_shadow.vert;
};
depth_vertex = { depth_vertex = {
stage = vertex; stage = vertex;
name = main; name = main;
@ -369,6 +387,12 @@ properties = {
fragment = { colors = uint; base_color = vec4; fog = vec4; }; fragment = { colors = uint; base_color = vec4; fog = vec4; };
}; };
}; };
shadow_layout = {
descriptorSets = (shadowmat_set);
pushConstants = {
vertex = { Model = mat4; blend = float; MatrixBase = uint; };
};
};
}; };
iqm = { iqm = {
shader = { shader = {
@ -376,16 +400,27 @@ properties = {
mapEntries = ( mapEntries = (
// IQMDepthOnly // IQMDepthOnly
{ size = 4; offset = 0; constantID = 0; }, { size = 4; offset = 0; constantID = 0; },
{ size = 4; offset = 4; constantID = 1; },
); );
}; };
shadow_vertex = {
stage = vertex;
name = main;
module = $builtin/iqm.vert;
specializationInfo = {
@inherit = $iqm.shader.specialization;
// IQMDepthOnly, IQMShadow
data = "array(1, 1)";
};
};
depth_vertex = { depth_vertex = {
stage = vertex; stage = vertex;
name = main; name = main;
module = $builtin/iqm.vert; module = $builtin/iqm.vert;
specializationInfo = { specializationInfo = {
@inherit = $iqm.shader.specialization; @inherit = $iqm.shader.specialization;
// IQMDepthOnly // IQMDepthOnly, IQMShadow
data = "array(1)"; data = "array(1, 0)";
}; };
}; };
gbuf_vertex = { gbuf_vertex = {
@ -394,8 +429,8 @@ properties = {
module = $builtin/iqm.vert; module = $builtin/iqm.vert;
specializationInfo = { specializationInfo = {
@inherit = $iqm.shader.specialization; @inherit = $iqm.shader.specialization;
// IQMDepthOnly // IQMDepthOnly, IQMShadow
data = "array(0)"; data = "array(0, 0)";
}; };
}; };
gbuf_fragment = { gbuf_fragment = {
@ -426,13 +461,10 @@ properties = {
primitiveRestartEnable = false; primitiveRestartEnable = false;
}; };
layout = { layout = {
// skin // skin
descriptorSets = (matrix_set, texture_set, bone_set); descriptorSets = (matrix_set, shadowmat_set, texture_set, bone_set);
pushConstants = { pushConstants = {
vertex = { vertex = { Model = mat4; blend = float; MatrixBase = uint; };
Model = mat4;
blend = float;
};
fragment = { fragment = {
colorA = uint; colorA = uint;
colorB = uint; colorB = uint;
@ -1811,7 +1843,7 @@ renderpasses = {
); );
stages = ( stages = (
$brush.shader.depth_vertex, $brush.shader.shadow_vertex,
); );
vertexInput = { vertexInput = {
bindings = ( bindings = (
@ -1824,7 +1856,7 @@ renderpasses = {
); );
}; };
inputAssembly = $brush.inputAssembly; inputAssembly = $brush.inputAssembly;
layout = $brush.layout; layout = $brush.shadow_layout;
}; };
alias:shadow = { alias:shadow = {
color = $color.alias; color = $color.alias;
@ -1834,7 +1866,7 @@ renderpasses = {
); );
stages = ( stages = (
$alias.shader.depth_vertex, $alias.shader.shadow_vertex,
); );
vertexInput = { vertexInput = {
// depth/shadow pass doesn't use UVs // depth/shadow pass doesn't use UVs
@ -1850,7 +1882,7 @@ renderpasses = {
); );
}; };
inputAssembly = $alias.inputAssembly; inputAssembly = $alias.inputAssembly;
layout = $alias.layout; layout = $alias.shadow_layout;
}; };
iqm:shadow = { iqm:shadow = {
color = $color.iqm; color = $color.iqm;
@ -1860,7 +1892,7 @@ renderpasses = {
); );
stages = ( stages = (
$iqm.shader.depth_vertex, $iqm.shader.shadow_vertex,
); );
vertexInput = $iqm.vertexInput; vertexInput = $iqm.vertexInput;
inputAssembly = $iqm.inputAssembly; inputAssembly = $iqm.inputAssembly;

View File

@ -1,8 +1,15 @@
#version 450 #version 450
#extension GL_GOOGLE_include_directive : enable
#extension GL_EXT_multiview : enable
layout (set = 0, binding = 0) buffer ShadowView {
mat4x4 shadowView[];
};
layout (push_constant) uniform PushConstants { layout (push_constant) uniform PushConstants {
mat4 Model; mat4 Model;
float blend; float blend;
uint MatrixBase;
}; };
layout (location = 0) in vec4 vertexa; layout (location = 0) in vec4 vertexa;
@ -10,14 +17,9 @@ layout (location = 1) in vec3 normala;
layout (location = 2) in vec4 vertexb; layout (location = 2) in vec4 vertexb;
layout (location = 3) in vec3 normalb; layout (location = 3) in vec3 normalb;
layout (location = 0) out int InstanceIndex;
void void
main (void) main (void)
{ {
vec4 vertex; vec4 pos = mix (vertexa, vertexb, blend);
gl_Position = shadowView[MatrixBase + gl_ViewIndex] * (Model * pos);
vertex = mix (vertexa, vertexb, blend);
gl_Position = Model * vertex;
InstanceIndex = gl_InstanceIndex;
} }

View File

@ -1,5 +1,14 @@
#version 450 #version 450
#extension GL_GOOGLE_include_directive : enable #extension GL_GOOGLE_include_directive : enable
#extension GL_EXT_multiview : enable
layout (set = 0, binding = 0) buffer ShadowView {
mat4x4 shadowView[];
};
layout (push_constant) uniform PushConstants {
uint MatrixBase;
};
#include "entity.h" #include "entity.h"
@ -15,7 +24,6 @@ layout (location = 0) out int InstanceIndex;
void void
main (void) main (void)
{ {
vec3 vert = vertex * entities[entid].transform; vec4 pos = vec4 (vertex * entities[entid].transform, 1);
gl_Position = vec4 (vert, 1);; gl_Position = shadowView[MatrixBase + gl_ViewIndex] * pos;
InstanceIndex = gl_InstanceIndex;
} }

View File

@ -1,9 +1,9 @@
#version 450 #version 450
layout (set = 1, binding = 0) uniform sampler2D Skin; layout (set = 2, binding = 0) uniform sampler2D Skin;
layout (push_constant) uniform PushConstants { layout (push_constant) uniform PushConstants {
layout (offset = 68) layout (offset = 72)
uint colorA; uint colorA;
uint colorB; uint colorB;
vec4 base_color; vec4 base_color;

View File

@ -3,12 +3,17 @@
#extension GL_EXT_multiview : enable #extension GL_EXT_multiview : enable
layout (constant_id = 0) const bool IQMDepthOnly = false; layout (constant_id = 0) const bool IQMDepthOnly = false;
layout (constant_id = 1) const bool IQMShadow = false;
layout (set = 0, binding = 0) uniform layout (set = 0, binding = 0) uniform
#include "matrices.h" #include "matrices.h"
; ;
layout (set = 2, binding = 0) buffer Bones { layout (set = 1, binding = 0) buffer ShadowView {
mat4x4 shadowView[];
};
layout (set = 3, binding = 0) buffer Bones {
// NOTE these are transposed, so v * m // NOTE these are transposed, so v * m
mat3x4 bones[]; mat3x4 bones[];
}; };
@ -16,6 +21,7 @@ layout (set = 2, binding = 0) buffer Bones {
layout (push_constant) uniform PushConstants { layout (push_constant) uniform PushConstants {
mat4 Model; mat4 Model;
float blend; float blend;
uint MatrixBase;
}; };
layout (location = 0) in vec3 vposition; layout (location = 0) in vec3 vposition;
@ -41,7 +47,11 @@ main (void)
m += bones[vbones.z] * vweights.z; m += bones[vbones.z] * vweights.z;
m += bones[vbones.w] * vweights.w; m += bones[vbones.w] * vweights.w;
vec4 pos = Model * vec4 (vec4(vposition, 1) * m, 1); vec4 pos = Model * vec4 (vec4(vposition, 1) * m, 1);
gl_Position = Projection3d * (View[gl_ViewIndex] * pos); if (IQMShadow) {
gl_Position = shadowView[MatrixBase + gl_ViewIndex] * pos;
} else {
gl_Position = Projection3d * (View[gl_ViewIndex] * pos);
}
if (!IQMDepthOnly) { if (!IQMDepthOnly) {
position = pos; position = pos;

View File

@ -41,6 +41,7 @@
#include "QF/scene/entity.h" #include "QF/scene/entity.h"
#include "QF/Vulkan/qf_alias.h" #include "QF/Vulkan/qf_alias.h"
#include "QF/Vulkan/qf_lighting.h"
#include "QF/Vulkan/qf_matrices.h" #include "QF/Vulkan/qf_matrices.h"
#include "QF/Vulkan/qf_palette.h" #include "QF/Vulkan/qf_palette.h"
#include "QF/Vulkan/qf_texture.h" #include "QF/Vulkan/qf_texture.h"
@ -60,48 +61,11 @@ typedef struct {
vec4f_t fog; vec4f_t fog;
} alias_push_constants_t; } alias_push_constants_t;
static void typedef struct {
emit_commands (VkCommandBuffer cmd, int pose1, int pose2, mat4f_t mat;
qfv_alias_skin_t *skin, float blend;
uint32_t numPC, qfv_push_constants_t *constants, uint32_t matrix_base;
aliashdr_t *hdr, qfv_taskctx_t *taskctx, entity_t ent) } shadow_push_constants_t;
{
auto ctx = taskctx->ctx;
auto device = ctx->device;
auto dfunc = device->funcs;
auto layout = taskctx->pipeline->layout;
__auto_type mesh = (qfv_alias_mesh_t *) ((byte *) hdr + hdr->commands);
VkDeviceSize offsets[] = {
pose1 * hdr->poseverts * sizeof (aliasvrt_t),
pose2 * hdr->poseverts * sizeof (aliasvrt_t),
0,
};
VkBuffer buffers[] = {
mesh->vertex_buffer,
mesh->vertex_buffer,
mesh->uv_buffer,
};
int bindingCount = skin ? 3 : 2;
Vulkan_BeginEntityLabel (ctx, cmd, ent);
dfunc->vkCmdBindVertexBuffers (cmd, 0, bindingCount, buffers, offsets);
dfunc->vkCmdBindIndexBuffer (cmd, mesh->index_buffer, 0,
VK_INDEX_TYPE_UINT32);
QFV_PushConstants (device, cmd, layout, numPC, constants);
if (skin) {
VkDescriptorSet sets[] = {
skin->descriptor,
};
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
layout, 2, 1, sets, 0, 0);
}
dfunc->vkCmdDrawIndexed (cmd, 3 * hdr->mdl.numtris, 1, 0, 0, 0);
QFV_CmdEndLabel (device, cmd);
}
static void static void
alias_depth_range (qfv_taskctx_t *taskctx, float minDepth, float maxDepth) alias_depth_range (qfv_taskctx_t *taskctx, float minDepth, float maxDepth)
@ -133,27 +97,24 @@ Vulkan_AliasRemoveSkin (vulkan_ctx_t *ctx, qfv_alias_skin_t *skin)
} }
static void static void
alias_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, bool pass) push_alias_constants (const mat4f_t mat, float blend, byte *colors,
vec4f_t base_color, int pass, qfv_taskctx_t *taskctx)
{ {
renderer_t *renderer = Ent_GetComponent (ent.id, scene_renderer, ent.reg); auto ctx = taskctx->ctx;
auto model = renderer->model; auto device = ctx->device;
aliashdr_t *hdr; auto cmd = taskctx->cmd;
qfv_alias_skin_t *skin; auto layout = taskctx->pipeline->layout;
alias_push_constants_t constants = {};
if (!(hdr = model->aliashdr)) { alias_push_constants_t constants = {
hdr = Cache_Get (&model->cache); .blend = blend,
} .colors = { VEC4_EXP (colors) },
.base_color = base_color,
};
animation_t *animation = Ent_GetComponent (ent.id, scene_animation,
ent.reg);
constants.blend = R_AliasGetLerpedFrames (animation, hdr);
transform_t transform = Entity_Transform (ent);
qfv_push_constants_t push_constants[] = { qfv_push_constants_t push_constants[] = {
{ VK_SHADER_STAGE_VERTEX_BIT, { VK_SHADER_STAGE_VERTEX_BIT,
field_offset (alias_push_constants_t, mat), field_offset (alias_push_constants_t, mat),
sizeof (mat4f_t), Transform_GetWorldMatrixPtr (transform) }, sizeof (mat4f_t), mat },
{ VK_SHADER_STAGE_VERTEX_BIT, { VK_SHADER_STAGE_VERTEX_BIT,
field_offset (alias_push_constants_t, blend), field_offset (alias_push_constants_t, blend),
sizeof (float), &constants.blend }, sizeof (float), &constants.blend },
@ -167,6 +128,55 @@ alias_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, bool pass)
field_offset (alias_push_constants_t, fog), field_offset (alias_push_constants_t, fog),
sizeof (constants.fog), &constants.fog }, sizeof (constants.fog), &constants.fog },
}; };
QFV_PushConstants (device, cmd, layout, pass ? 5 : 2, push_constants);
}
static void
push_shadow_constants (const mat4f_t mat, float blend, uint16_t *matrix_base,
qfv_taskctx_t *taskctx)
{
auto ctx = taskctx->ctx;
auto device = ctx->device;
auto cmd = taskctx->cmd;
auto layout = taskctx->pipeline->layout;
shadow_push_constants_t constants = {
.blend = blend,
.matrix_base = *matrix_base,
};
qfv_push_constants_t push_constants[] = {
{ VK_SHADER_STAGE_VERTEX_BIT,
field_offset (shadow_push_constants_t, mat),
sizeof (mat4f_t), mat },
{ VK_SHADER_STAGE_VERTEX_BIT,
field_offset (shadow_push_constants_t, blend),
sizeof (float), &constants.blend },
{ VK_SHADER_STAGE_VERTEX_BIT,
field_offset (shadow_push_constants_t, matrix_base),
sizeof (uint32_t), &constants.matrix_base },
};
QFV_PushConstants (device, cmd, layout, 3, push_constants);
}
static void
alias_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, bool pass)
{
renderer_t *renderer = Ent_GetComponent (ent.id, scene_renderer, ent.reg);
auto model = renderer->model;
aliashdr_t *hdr;
qfv_alias_skin_t *skin;
uint16_t *matrix_base = taskctx->data;
if (!(hdr = model->aliashdr)) {
hdr = Cache_Get (&model->cache);
}
animation_t *animation = Ent_GetComponent (ent.id, scene_animation,
ent.reg);
float blend = R_AliasGetLerpedFrames (animation, hdr);
transform_t transform = Entity_Transform (ent);
if (0/*XXX ent->skin && ent->skin->tex*/) { if (0/*XXX ent->skin && ent->skin->tex*/) {
//skin = ent->skin->tex; //skin = ent->skin->tex;
@ -175,19 +185,57 @@ alias_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, bool pass)
skindesc = R_AliasGetSkindesc (animation, renderer->skinnum, hdr); skindesc = R_AliasGetSkindesc (animation, renderer->skinnum, hdr);
skin = (qfv_alias_skin_t *) ((byte *) hdr + skindesc->skin); skin = (qfv_alias_skin_t *) ((byte *) hdr + skindesc->skin);
} }
QuatCopy (renderer->colormod, constants.base_color); vec4f_t base_color;
QuatCopy (skin->colors, constants.colors); byte colors[4];
QuatCopy (renderer->colormod, base_color);
QuatCopy (skin->colors, colors);
if (Ent_HasComponent (ent.id, scene_colormap, ent.reg)) { if (Ent_HasComponent (ent.id, scene_colormap, ent.reg)) {
colormap_t *colormap=Ent_GetComponent (ent.id, scene_colormap, ent.reg); colormap_t *colormap=Ent_GetComponent (ent.id, scene_colormap, ent.reg);
constants.colors[0] = colormap->top * 16 + 8; colors[0] = colormap->top * 16 + 8;
constants.colors[1] = colormap->bottom * 16 + 8; colors[1] = colormap->bottom * 16 + 8;
} }
QuatZero (constants.fog);
emit_commands (taskctx->cmd, animation->pose1, animation->pose2, auto ctx = taskctx->ctx;
pass ? skin : 0, auto device = ctx->device;
pass ? 5 : 2, push_constants, auto dfunc = device->funcs;
hdr, taskctx, ent); auto cmd = taskctx->cmd;
auto layout = taskctx->pipeline->layout;
auto mesh = (qfv_alias_mesh_t *) ((byte *) hdr + hdr->commands);
VkDeviceSize offsets[] = {
animation->pose1 * hdr->poseverts * sizeof (aliasvrt_t),
animation->pose2 * hdr->poseverts * sizeof (aliasvrt_t),
0,
};
VkBuffer buffers[] = {
mesh->vertex_buffer,
mesh->vertex_buffer,
mesh->uv_buffer,
};
int bindingCount = skin ? 3 : 2;
Vulkan_BeginEntityLabel (ctx, cmd, ent);
dfunc->vkCmdBindVertexBuffers (cmd, 0, bindingCount, buffers, offsets);
dfunc->vkCmdBindIndexBuffer (cmd, mesh->index_buffer, 0,
VK_INDEX_TYPE_UINT32);
if (pass && skin) {
VkDescriptorSet sets[] = {
skin->descriptor,
};
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
layout, 2, 1, sets, 0, 0);
}
if (matrix_base) {
push_shadow_constants (Transform_GetWorldMatrixPtr (transform),
blend, matrix_base, taskctx);
} else {
push_alias_constants (Transform_GetWorldMatrixPtr (transform),
blend, colors, base_color, pass, taskctx);
}
dfunc->vkCmdDrawIndexed (cmd, 3 * hdr->mdl.numtris, 1, 0, 0, 0);
QFV_CmdEndLabel (device, cmd);
} }
static void static void
@ -202,12 +250,14 @@ alias_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
auto dfunc = device->funcs; auto dfunc = device->funcs;
auto layout = taskctx->pipeline->layout; auto layout = taskctx->pipeline->layout;
auto cmd = taskctx->cmd; auto cmd = taskctx->cmd;
bool shadow = !!taskctx->data;
VkDescriptorSet sets[] = { VkDescriptorSet sets[] = {
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame), shadow ? Vulkan_Lighting_Descriptors (ctx, ctx->curFrame)
: Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
Vulkan_Palette_Descriptor (ctx), Vulkan_Palette_Descriptor (ctx),
}; };
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
layout, 0, 2, sets, 0, 0); layout, 0, shadow ? 1 : 2, sets, 0, 0);
auto queue = r_ent_queue; //FIXME fetch from scene auto queue = r_ent_queue; //FIXME fetch from scene
for (size_t i = 0; i < queue->ent_queues[mod_alias].size; i++) { for (size_t i = 0; i < queue->ent_queues[mod_alias].size; i++) {

View File

@ -50,6 +50,7 @@
#include "QF/scene/entity.h" #include "QF/scene/entity.h"
#include "QF/Vulkan/qf_bsp.h" #include "QF/Vulkan/qf_bsp.h"
#include "QF/Vulkan/qf_lighting.h"
#include "QF/Vulkan/qf_lightmap.h" #include "QF/Vulkan/qf_lightmap.h"
#include "QF/Vulkan/qf_matrices.h" #include "QF/Vulkan/qf_matrices.h"
#include "QF/Vulkan/qf_scene.h" #include "QF/Vulkan/qf_scene.h"
@ -80,7 +81,7 @@ typedef struct bsp_push_constants_s {
float time; float time;
float alpha; float alpha;
float turb_scale; float turb_scale;
} bsp_push_constants_t; } bsp_frag_constants_t;
static void static void
add_texture (texture_t *tx, vulkan_ctx_t *ctx) add_texture (texture_t *tx, vulkan_ctx_t *ctx)
@ -798,27 +799,44 @@ bind_texture (vulktex_t *tex, uint32_t setnum, VkPipelineLayout layout,
} }
static void static void
push_fragconst (bsp_push_constants_t *constants, VkPipelineLayout layout, push_fragconst (QFV_BspQueue queue, VkPipelineLayout layout,
qfv_device_t *device, VkCommandBuffer cmd) qfv_device_t *device, VkCommandBuffer cmd)
{ {
//XXX glsl_Fog_GetColor (fog);
//XXX fog[3] = glsl_Fog_GetDensity () / 64.0;
bsp_frag_constants_t constants = {
.time = vr_data.realtime,
.alpha = queue == QFV_bspTurb ? r_wateralpha : 1,
.turb_scale = queue == QFV_bspTurb ? 1 : 0,
};
qfv_push_constants_t push_constants[] = { qfv_push_constants_t push_constants[] = {
//{ VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof (mat), mat },
{ VK_SHADER_STAGE_FRAGMENT_BIT, { VK_SHADER_STAGE_FRAGMENT_BIT,
field_offset (bsp_push_constants_t, fog), field_offset (bsp_frag_constants_t, fog),
sizeof (constants->fog), &constants->fog }, sizeof (constants.fog), &constants.fog },
{ VK_SHADER_STAGE_FRAGMENT_BIT, { VK_SHADER_STAGE_FRAGMENT_BIT,
field_offset (bsp_push_constants_t, time), field_offset (bsp_frag_constants_t, time),
sizeof (constants->time), &constants->time }, sizeof (constants.time), &constants.time },
{ VK_SHADER_STAGE_FRAGMENT_BIT, { VK_SHADER_STAGE_FRAGMENT_BIT,
field_offset (bsp_push_constants_t, alpha), field_offset (bsp_frag_constants_t, alpha),
sizeof (constants->alpha), &constants->alpha }, sizeof (constants.alpha), &constants.alpha },
{ VK_SHADER_STAGE_FRAGMENT_BIT, { VK_SHADER_STAGE_FRAGMENT_BIT,
field_offset (bsp_push_constants_t, turb_scale), field_offset (bsp_frag_constants_t, turb_scale),
sizeof (constants->turb_scale), &constants->turb_scale }, sizeof (constants.turb_scale), &constants.turb_scale },
}; };
QFV_PushConstants (device, cmd, layout, 4, push_constants); QFV_PushConstants (device, cmd, layout, 4, push_constants);
} }
static void
push_shadowconst (uint32_t matrix_base, VkPipelineLayout layout,
qfv_device_t *device, VkCommandBuffer cmd)
{
qfv_push_constants_t push_constants[] = {
{ VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof (uint32_t), &matrix_base },
};
QFV_PushConstants (device, cmd, layout, 1, push_constants);
}
static void static void
clear_queues (bspctx_t *bctx, bsp_pass_t *pass) clear_queues (bspctx_t *bctx, bsp_pass_t *pass)
{ {
@ -1146,6 +1164,7 @@ bsp_draw_queue (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
auto bctx = ctx->bsp_context; auto bctx = ctx->bsp_context;
auto layout = taskctx->pipeline->layout; auto layout = taskctx->pipeline->layout;
auto cmd = taskctx->cmd; auto cmd = taskctx->cmd;
uint16_t *matrix_base = taskctx->data;
if (!bctx->vertex_buffer) { if (!bctx->vertex_buffer) {
return; return;
@ -1168,22 +1187,28 @@ bsp_draw_queue (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
dfunc->vkCmdBindIndexBuffer (cmd, bctx->index_buffer, bframe->index_offset, dfunc->vkCmdBindIndexBuffer (cmd, bctx->index_buffer, bframe->index_offset,
VK_INDEX_TYPE_UINT32); VK_INDEX_TYPE_UINT32);
VkDescriptorSet sets[] = { if (matrix_base) {
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame), VkDescriptorSet sets[] = {
Vulkan_Scene_Descriptors (ctx), Vulkan_Lighting_Descriptors (ctx, ctx->curFrame),
Vulkan_Translucent_Descriptors (ctx, ctx->curFrame), Vulkan_Scene_Descriptors (ctx),
}; };
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
layout, 0, 3, sets, 0, 0); layout, 0, 2, sets, 0, 0);
} else {
VkDescriptorSet sets[] = {
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
Vulkan_Scene_Descriptors (ctx),
Vulkan_Translucent_Descriptors (ctx, ctx->curFrame),
};
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
layout, 0, 3, sets, 0, 0);
}
//XXX glsl_Fog_GetColor (fog); if (matrix_base) {
//XXX fog[3] = glsl_Fog_GetDensity () / 64.0; push_shadowconst (*matrix_base, layout, device, cmd);
bsp_push_constants_t frag_constants = { } else {
.time = vr_data.realtime, push_fragconst (queue, layout, device, cmd);
.alpha = queue == QFV_bspTurb ? r_wateralpha : 1, }
.turb_scale = queue == QFV_bspTurb ? 1 : 0,
};
push_fragconst (&frag_constants, layout, device, cmd);
if (queue == QFV_bspSky) { if (queue == QFV_bspSky) {
vulktex_t skybox = { .descriptor = bctx->skybox_descriptor }; vulktex_t skybox = { .descriptor = bctx->skybox_descriptor };
bind_texture (&skybox, SKYBOX_SET, layout, dfunc, cmd); bind_texture (&skybox, SKYBOX_SET, layout, dfunc, cmd);

View File

@ -40,6 +40,7 @@
#include "QF/scene/entity.h" #include "QF/scene/entity.h"
#include "QF/Vulkan/qf_iqm.h" #include "QF/Vulkan/qf_iqm.h"
#include "QF/Vulkan/qf_lighting.h"
#include "QF/Vulkan/qf_matrices.h" #include "QF/Vulkan/qf_matrices.h"
#include "QF/Vulkan/qf_texture.h" #include "QF/Vulkan/qf_texture.h"
#include "QF/Vulkan/debug.h" #include "QF/Vulkan/debug.h"
@ -56,6 +57,7 @@
typedef struct { typedef struct {
mat4f_t mat; mat4f_t mat;
float blend; float blend;
uint32_t matrix_base;
byte colorA[4]; byte colorA[4];
byte colorB[4]; byte colorB[4];
vec4f_t base_color; vec4f_t base_color;
@ -96,14 +98,14 @@ emit_commands (VkCommandBuffer cmd, int pose1, int pose2,
}; };
dfunc->vkCmdBindDescriptorSets (cmd, dfunc->vkCmdBindDescriptorSets (cmd,
VK_PIPELINE_BIND_POINT_GRAPHICS, VK_PIPELINE_BIND_POINT_GRAPHICS,
layout, 1, 2, sets, 0, 0); layout, 2, 2, sets, 0, 0);
} else { } else {
VkDescriptorSet sets[] = { VkDescriptorSet sets[] = {
mesh->bones_descriptors[ctx->curFrame], mesh->bones_descriptors[ctx->curFrame],
}; };
dfunc->vkCmdBindDescriptorSets (cmd, dfunc->vkCmdBindDescriptorSets (cmd,
VK_PIPELINE_BIND_POINT_GRAPHICS, VK_PIPELINE_BIND_POINT_GRAPHICS,
layout, 2, 1, sets, 0, 0); layout, 3, 1, sets, 0, 0);
} }
dfunc->vkCmdDrawIndexed (cmd, 3 * iqm->meshes[i].num_triangles, 1, dfunc->vkCmdDrawIndexed (cmd, 3 * iqm->meshes[i].num_triangles, 1,
3 * iqm->meshes[i].first_triangle, 0, 0); 3 * iqm->meshes[i].first_triangle, 0, 0);
@ -195,12 +197,18 @@ iqm_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, bool pass)
auto iqm = (iqm_t *) model->aliashdr; auto iqm = (iqm_t *) model->aliashdr;
qfv_iqm_t *mesh = iqm->extra_data; qfv_iqm_t *mesh = iqm->extra_data;
auto skins = mesh->skins; auto skins = mesh->skins;
iqm_push_constants_t constants = {};
iqmframe_t *frame; iqmframe_t *frame;
uint16_t *matrix_base = taskctx->data;
animation_t *animation = Ent_GetComponent (ent.id, scene_animation, animation_t *animation = Ent_GetComponent (ent.id, scene_animation,
ent.reg); ent.reg);
constants.blend = R_IQMGetLerpedFrames (animation, iqm); iqm_push_constants_t constants = {
.blend = R_IQMGetLerpedFrames (animation, iqm),
.matrix_base = matrix_base ? *matrix_base : 0,
.colorA = { VEC4_EXP (skins[0].colora) },
.colorB = { VEC4_EXP (skins[0].colorb) },
.base_color = { VEC4_EXP (renderer->colormod) },
};
frame = R_IQMBlendFrames (iqm, animation->pose1, animation->pose2, frame = R_IQMBlendFrames (iqm, animation->pose1, animation->pose2,
constants.blend, 0); constants.blend, 0);
@ -236,6 +244,9 @@ iqm_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, bool pass)
{ VK_SHADER_STAGE_VERTEX_BIT, { VK_SHADER_STAGE_VERTEX_BIT,
field_offset (iqm_push_constants_t, blend), field_offset (iqm_push_constants_t, blend),
sizeof (float), &constants.blend }, sizeof (float), &constants.blend },
{ VK_SHADER_STAGE_VERTEX_BIT,
field_offset (iqm_push_constants_t, matrix_base),
sizeof (uint32_t), &constants.matrix_base },
{ VK_SHADER_STAGE_FRAGMENT_BIT, { VK_SHADER_STAGE_FRAGMENT_BIT,
field_offset (iqm_push_constants_t, colorA), field_offset (iqm_push_constants_t, colorA),
sizeof (constants.colorA), constants.colorA }, sizeof (constants.colorA), constants.colorA },
@ -250,14 +261,9 @@ iqm_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, bool pass)
sizeof (constants.fog), &constants.fog }, sizeof (constants.fog), &constants.fog },
}; };
QuatCopy (renderer->colormod, constants.base_color);
QuatCopy (skins[0].colora, constants.colorA);
QuatCopy (skins[0].colorb, constants.colorB);
QuatZero (constants.fog);
emit_commands (taskctx->cmd, animation->pose1, animation->pose2, emit_commands (taskctx->cmd, animation->pose1, animation->pose2,
pass ? skins : 0, pass ? skins : 0,
pass ? 6 : 2, push_constants, pass ? 7 : 3, push_constants,
iqm, taskctx, ent); iqm, taskctx, ent);
} }
@ -275,9 +281,10 @@ iqm_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
VkDescriptorSet sets[] = { VkDescriptorSet sets[] = {
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame), Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
Vulkan_Lighting_Descriptors (ctx, ctx->curFrame),
}; };
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
layout, 0, 1, sets, 0, 0); layout, 0, 2, sets, 0, 0);
auto queue = r_ent_queue; //FIXME fetch from scene auto queue = r_ent_queue; //FIXME fetch from scene
for (size_t i = 0; i < queue->ent_queues[mod_iqm].size; i++) { for (size_t i = 0; i < queue->ent_queues[mod_iqm].size; i++) {

View File

@ -263,12 +263,11 @@ lighting_draw_shadow_maps (const exprval_t **params, exprval_t *result,
for (size_t i = 0; i < queue->ent_queues[mod_light].size; i++) { for (size_t i = 0; i < queue->ent_queues[mod_light].size; i++) {
entity_t ent = queue->ent_queues[mod_light].a[i]; entity_t ent = queue->ent_queues[mod_light].a[i];
auto ls = get_lightstyle (ent); auto ls = get_lightstyle (ent);
if (!d_lightstylevalue[ls]) {
continue;
}
uint32_t id = get_lightid (ent); uint32_t id = get_lightid (ent);
auto r = &lctx->light_renderers.a[id]; auto r = &lctx->light_renderers.a[id];
//auto l = get_light (ent); if (!r->numLayers || !d_lightstylevalue[ls]) {
continue;
}
auto renderpass = &render->renderpasses[r->renderpass_index]; auto renderpass = &render->renderpasses[r->renderpass_index];
auto view = create_view (ctx, r); auto view = create_view (ctx, r);
auto bi = &renderpass->beginInfo; auto bi = &renderpass->beginInfo;
@ -1188,3 +1187,10 @@ Vulkan_LoadLights (scene_t *scene, vulkan_ctx_t *ctx)
lctx->ldata = scene->lights; lctx->ldata = scene->lights;
} }
} }
VkDescriptorSet
Vulkan_Lighting_Descriptors (vulkan_ctx_t *ctx, int frame)
{
auto lctx = ctx->lighting_context;
return lctx->frames.a[frame].shadowmat_set;
}