mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-24 12:42:32 +00:00
[vulkan] Implement very basic lighting for forward
Both alias and iqm (yay unified fragment shader). It's meh, but that's 1996 tech for you (hey, it was full-on 3d and we liked it!).
This commit is contained in:
parent
b22f104163
commit
8bf688748c
4 changed files with 249 additions and 54 deletions
|
@ -338,7 +338,14 @@ properties = {
|
|||
descriptorSets = (matrix_set, texture_set, texture_set);
|
||||
pushConstants = {
|
||||
vertex = { Model = mat4; blend = float; };
|
||||
fragment = { colors = uint; base_color = vec4; fog = vec4; };
|
||||
fragment = {
|
||||
colors = uint;
|
||||
ambient = float;
|
||||
shadelight = float;
|
||||
lightvec = vec4;
|
||||
base_color = vec4;
|
||||
fog = vec4;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -396,7 +403,14 @@ properties = {
|
|||
descriptorSets = (matrix_set, texture_set, texture_set, bone_set);
|
||||
pushConstants = {
|
||||
vertex = { Model = mat4; blend = float; };
|
||||
fragment = { colors = uint; base_color = vec4; fog = vec4; };
|
||||
fragment = {
|
||||
colors = uint;
|
||||
ambient = float;
|
||||
shadelight = float;
|
||||
lightvec = vec4;
|
||||
base_color = vec4;
|
||||
fog = vec4;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -1113,7 +1127,7 @@ renderpasses = {
|
|||
color = $color.alias;
|
||||
tasks = (
|
||||
{ func = alias_draw;
|
||||
params = (main, 1); },
|
||||
params = (main, 2); },
|
||||
);
|
||||
|
||||
stages = (
|
||||
|
@ -1128,7 +1142,7 @@ renderpasses = {
|
|||
color = $color.iqm;
|
||||
tasks = (
|
||||
{ func = iqm_draw;
|
||||
params = (1); },
|
||||
params = (2); },
|
||||
);
|
||||
|
||||
stages = (
|
||||
|
|
|
@ -6,6 +6,9 @@ layout (set = 2, binding = 0) uniform sampler2DArray Skin;
|
|||
layout (push_constant) uniform PushConstants {
|
||||
layout (offset = 68)
|
||||
uint colors;
|
||||
float ambient;
|
||||
float shadelight;
|
||||
vec4 lightvec;
|
||||
vec4 base_color;
|
||||
vec4 fog;
|
||||
};
|
||||
|
@ -26,5 +29,11 @@ main (void)
|
|||
c += texture (Palette, vec2 (cmap.x, rows.x)) * cmap.y;
|
||||
c += texture (Palette, vec2 (cmap.z, rows.y)) * cmap.w;
|
||||
|
||||
frag_color = c + e;//fogBlend (c);
|
||||
float light = ambient;
|
||||
float d = dot (normal, lightvec.xyz);
|
||||
d = min (d, 0.0);
|
||||
light -= d * shadelight;
|
||||
light = max (light, 0.0) / 255;
|
||||
|
||||
frag_color = light * c + e;//fogBlend (c);
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
|
||||
#include "mod_internal.h"
|
||||
#include "r_internal.h"
|
||||
#include "r_local.h"
|
||||
#include "vid_vulkan.h"
|
||||
|
||||
typedef struct {
|
||||
|
@ -62,6 +63,17 @@ typedef struct {
|
|||
vec4f_t fog;
|
||||
} alias_push_constants_t;
|
||||
|
||||
typedef struct {
|
||||
mat4f_t mat;
|
||||
float blend;
|
||||
byte colors[4];
|
||||
float ambient;
|
||||
float shadelight;
|
||||
vec4f_t lightvec;
|
||||
vec4f_t base_color;
|
||||
vec4f_t fog;
|
||||
} fwd_push_constants_t;
|
||||
|
||||
typedef struct {
|
||||
mat4f_t mat;
|
||||
float blend;
|
||||
|
@ -132,6 +144,54 @@ push_alias_constants (const mat4f_t mat, float blend, byte *colors,
|
|||
QFV_PushConstants (device, cmd, layout, pass ? 5 : 2, push_constants);
|
||||
}
|
||||
|
||||
static void
|
||||
push_fwd_constants (const mat4f_t mat, float blend, byte *colors,
|
||||
vec4f_t base_color, const alight_t *lighting,
|
||||
int pass, qfv_taskctx_t *taskctx)
|
||||
{
|
||||
auto ctx = taskctx->ctx;
|
||||
auto device = ctx->device;
|
||||
auto cmd = taskctx->cmd;
|
||||
auto layout = taskctx->pipeline->layout;
|
||||
|
||||
fwd_push_constants_t constants = {
|
||||
.blend = blend,
|
||||
.colors = { VEC4_EXP (colors) },
|
||||
.ambient = lighting->ambientlight,
|
||||
.shadelight = lighting->shadelight,
|
||||
.lightvec = { VectorExpand (lighting->lightvec) },
|
||||
.base_color = base_color,
|
||||
};
|
||||
|
||||
qfv_push_constants_t push_constants[] = {
|
||||
{ VK_SHADER_STAGE_VERTEX_BIT,
|
||||
field_offset (fwd_push_constants_t, mat),
|
||||
sizeof (mat4f_t), mat },
|
||||
{ VK_SHADER_STAGE_VERTEX_BIT,
|
||||
field_offset (fwd_push_constants_t, blend),
|
||||
sizeof (float), &constants.blend },
|
||||
{ VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
field_offset (fwd_push_constants_t, colors),
|
||||
sizeof (constants.colors), constants.colors },
|
||||
{ VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
field_offset (fwd_push_constants_t, ambient),
|
||||
sizeof (constants.ambient), &constants.ambient },
|
||||
{ VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
field_offset (fwd_push_constants_t, shadelight),
|
||||
sizeof (constants.shadelight), &constants.shadelight },
|
||||
{ VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
field_offset (fwd_push_constants_t, lightvec),
|
||||
sizeof (constants.lightvec), &constants.lightvec },
|
||||
{ VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
field_offset (fwd_push_constants_t, base_color),
|
||||
sizeof (constants.base_color), &constants.base_color },
|
||||
{ VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
field_offset (fwd_push_constants_t, fog),
|
||||
sizeof (constants.fog), &constants.fog },
|
||||
};
|
||||
QFV_PushConstants (device, cmd, layout, 8, push_constants);
|
||||
}
|
||||
|
||||
static void
|
||||
push_shadow_constants (const mat4f_t mat, float blend, uint16_t *matrix_base,
|
||||
qfv_taskctx_t *taskctx)
|
||||
|
@ -161,7 +221,7 @@ push_shadow_constants (const mat4f_t mat, float blend, uint16_t *matrix_base,
|
|||
}
|
||||
|
||||
static void
|
||||
alias_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, bool pass,
|
||||
alias_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, int pass,
|
||||
renderer_t *renderer)
|
||||
{
|
||||
auto model = renderer->model;
|
||||
|
@ -190,8 +250,9 @@ alias_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, bool pass,
|
|||
skin = (qfv_alias_skin_t *) ((byte *) hdr + skindesc->skin);
|
||||
}
|
||||
vec4f_t base_color;
|
||||
byte colors[4] = {};
|
||||
QuatCopy (renderer->colormod, base_color);
|
||||
|
||||
byte colors[4] = {};
|
||||
QuatCopy (skin->colors, colors);
|
||||
auto colormap = Entity_GetColormap (ent);
|
||||
if (colormap) {
|
||||
|
@ -235,8 +296,16 @@ alias_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, bool pass,
|
|||
push_shadow_constants (Transform_GetWorldMatrixPtr (transform),
|
||||
blend, matrix_base, taskctx);
|
||||
} else {
|
||||
push_alias_constants (Transform_GetWorldMatrixPtr (transform),
|
||||
blend, colors, base_color, pass, taskctx);
|
||||
if (pass > 1) {
|
||||
alight_t lighting;
|
||||
R_Setup_Lighting (ent, &lighting);
|
||||
push_fwd_constants (Transform_GetWorldMatrixPtr (transform),
|
||||
blend, colors, base_color, &lighting,
|
||||
pass, 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);
|
||||
|
|
|
@ -57,16 +57,31 @@
|
|||
typedef struct {
|
||||
mat4f_t mat;
|
||||
float blend;
|
||||
uint32_t matrix_base;
|
||||
byte colors[4];
|
||||
vec4f_t base_color;
|
||||
vec4f_t fog;
|
||||
} iqm_push_constants_t;
|
||||
|
||||
typedef struct {
|
||||
mat4f_t mat;
|
||||
float blend;
|
||||
byte colors[4];
|
||||
float ambient;
|
||||
float shadelight;
|
||||
vec4f_t lightvec;
|
||||
vec4f_t base_color;
|
||||
vec4f_t fog;
|
||||
} fwd_push_constants_t;
|
||||
|
||||
typedef struct {
|
||||
mat4f_t mat;
|
||||
float blend;
|
||||
uint32_t matrix_base;
|
||||
} shadow_push_constants_t;
|
||||
|
||||
static void
|
||||
emit_commands (VkCommandBuffer cmd, int pose1, int pose2,
|
||||
qfv_iqm_skin_t *skins,
|
||||
uint32_t numPC, qfv_push_constants_t *constants,
|
||||
iqm_t *iqm, qfv_taskctx_t *taskctx, entity_t ent)
|
||||
{
|
||||
auto ctx = taskctx->ctx;
|
||||
|
@ -89,7 +104,6 @@ emit_commands (VkCommandBuffer cmd, int pose1, int pose2,
|
|||
VkIndexType indexType = iqm->num_verts > 0xfff0 ? VK_INDEX_TYPE_UINT32
|
||||
: VK_INDEX_TYPE_UINT16;
|
||||
dfunc->vkCmdBindIndexBuffer (cmd, mesh->index_buffer, 0, indexType);
|
||||
QFV_PushConstants (device, cmd, layout, numPC, constants);
|
||||
for (int i = 0; i < iqm->num_meshes; i++) {
|
||||
if (skins) {
|
||||
VkDescriptorSet sets[] = {
|
||||
|
@ -187,7 +201,118 @@ Vulkan_IQMRemoveSkin (vulkan_ctx_t *ctx, qfv_iqm_skin_t *skin)
|
|||
}
|
||||
|
||||
static void
|
||||
iqm_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, bool pass, bool shadow)
|
||||
push_iqm_constants (const mat4f_t mat, float blend, byte *colors,
|
||||
vec4f_t base_color, int pass, qfv_taskctx_t *taskctx)
|
||||
{
|
||||
auto ctx = taskctx->ctx;
|
||||
auto device = ctx->device;
|
||||
auto cmd = taskctx->cmd;
|
||||
auto layout = taskctx->pipeline->layout;
|
||||
|
||||
iqm_push_constants_t constants = {
|
||||
.blend = blend,
|
||||
.colors = { VEC4_EXP (colors) },
|
||||
.base_color = base_color,
|
||||
};
|
||||
|
||||
qfv_push_constants_t push_constants[] = {
|
||||
{ VK_SHADER_STAGE_VERTEX_BIT,
|
||||
field_offset (iqm_push_constants_t, mat),
|
||||
sizeof (mat4f_t), mat },
|
||||
{ VK_SHADER_STAGE_VERTEX_BIT,
|
||||
field_offset (iqm_push_constants_t, blend),
|
||||
sizeof (float), &constants.blend },
|
||||
{ VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
field_offset (iqm_push_constants_t, colors),
|
||||
sizeof (constants.colors), constants.colors },
|
||||
{ VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
field_offset (iqm_push_constants_t, base_color),
|
||||
sizeof (constants.base_color), &constants.base_color },
|
||||
{ VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
field_offset (iqm_push_constants_t, fog),
|
||||
sizeof (constants.fog), &constants.fog },
|
||||
};
|
||||
QFV_PushConstants (device, cmd, layout, pass ? 5 : 2, push_constants);
|
||||
}
|
||||
|
||||
static void
|
||||
push_fwd_constants (const mat4f_t mat, float blend, byte *colors,
|
||||
vec4f_t base_color, const alight_t *lighting,
|
||||
int pass, qfv_taskctx_t *taskctx)
|
||||
{
|
||||
auto ctx = taskctx->ctx;
|
||||
auto device = ctx->device;
|
||||
auto cmd = taskctx->cmd;
|
||||
auto layout = taskctx->pipeline->layout;
|
||||
|
||||
fwd_push_constants_t constants = {
|
||||
.blend = blend,
|
||||
.colors = { VEC4_EXP (colors) },
|
||||
.ambient = lighting->ambientlight,
|
||||
.shadelight = lighting->shadelight,
|
||||
.lightvec = { VectorExpand (lighting->lightvec) },
|
||||
.base_color = base_color,
|
||||
};
|
||||
|
||||
qfv_push_constants_t push_constants[] = {
|
||||
{ VK_SHADER_STAGE_VERTEX_BIT,
|
||||
field_offset (fwd_push_constants_t, mat),
|
||||
sizeof (mat4f_t), mat },
|
||||
{ VK_SHADER_STAGE_VERTEX_BIT,
|
||||
field_offset (fwd_push_constants_t, blend),
|
||||
sizeof (float), &constants.blend },
|
||||
{ VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
field_offset (fwd_push_constants_t, colors),
|
||||
sizeof (constants.colors), constants.colors },
|
||||
{ VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
field_offset (fwd_push_constants_t, ambient),
|
||||
sizeof (constants.ambient), &constants.ambient },
|
||||
{ VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
field_offset (fwd_push_constants_t, shadelight),
|
||||
sizeof (constants.shadelight), &constants.shadelight },
|
||||
{ VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
field_offset (fwd_push_constants_t, lightvec),
|
||||
sizeof (constants.lightvec), &constants.lightvec },
|
||||
{ VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
field_offset (fwd_push_constants_t, base_color),
|
||||
sizeof (constants.base_color), &constants.base_color },
|
||||
{ VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
field_offset (fwd_push_constants_t, fog),
|
||||
sizeof (constants.fog), &constants.fog },
|
||||
};
|
||||
QFV_PushConstants (device, cmd, layout, 8, 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
|
||||
iqm_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, int pass, bool shadow)
|
||||
{
|
||||
auto ctx = taskctx->ctx;
|
||||
auto device = ctx->device;
|
||||
|
@ -200,6 +325,9 @@ iqm_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, bool pass, bool shadow)
|
|||
iqmframe_t *frame;
|
||||
uint16_t *matrix_base = taskctx->data;
|
||||
|
||||
vec4f_t base_color;
|
||||
QuatCopy (renderer->colormod, base_color);
|
||||
|
||||
byte colors[4] = {};
|
||||
auto colormap = Entity_GetColormap (ent);
|
||||
if (colormap) {
|
||||
|
@ -208,14 +336,9 @@ iqm_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, bool pass, bool shadow)
|
|||
}
|
||||
|
||||
auto animation = Entity_GetAnimation (ent);
|
||||
iqm_push_constants_t constants = {
|
||||
.blend = R_IQMGetLerpedFrames (animation, iqm),
|
||||
.matrix_base = matrix_base ? *matrix_base : 0,
|
||||
.colors = { VEC4_EXP (colors) },
|
||||
.base_color = { VEC4_EXP (renderer->colormod) },
|
||||
};
|
||||
float blend = R_IQMGetLerpedFrames (animation, iqm);
|
||||
frame = R_IQMBlendFrames (iqm, animation->pose1, animation->pose2,
|
||||
constants.blend, 0);
|
||||
blend, 0);
|
||||
|
||||
vec4f_t *bone_data;
|
||||
dfunc->vkMapMemory (device->dev, mesh->bones->memory, 0, VK_WHOLE_SIZE,
|
||||
|
@ -243,43 +366,23 @@ iqm_draw_ent (qfv_taskctx_t *taskctx, entity_t ent, bool pass, bool shadow)
|
|||
|
||||
transform_t transform = Entity_Transform (ent);
|
||||
if (shadow) {
|
||||
qfv_push_constants_t push_constants[] = {
|
||||
{ VK_SHADER_STAGE_VERTEX_BIT,
|
||||
field_offset (iqm_push_constants_t, mat),
|
||||
sizeof (mat4f_t), Transform_GetWorldMatrixPtr (transform) },
|
||||
{ VK_SHADER_STAGE_VERTEX_BIT,
|
||||
field_offset (iqm_push_constants_t, blend),
|
||||
sizeof (float), &constants.blend },
|
||||
{ VK_SHADER_STAGE_VERTEX_BIT,
|
||||
field_offset (iqm_push_constants_t, matrix_base),
|
||||
sizeof (uint32_t), &constants.matrix_base },
|
||||
};
|
||||
|
||||
push_shadow_constants (Transform_GetWorldMatrixPtr (transform),
|
||||
blend, matrix_base, taskctx);
|
||||
emit_commands (taskctx->cmd, animation->pose1, animation->pose2,
|
||||
nullptr, 3, push_constants, iqm, taskctx, ent);
|
||||
nullptr, iqm, taskctx, ent);
|
||||
} else {
|
||||
qfv_push_constants_t push_constants[] = {
|
||||
{ VK_SHADER_STAGE_VERTEX_BIT,
|
||||
field_offset (iqm_push_constants_t, mat),
|
||||
sizeof (mat4f_t), Transform_GetWorldMatrixPtr (transform) },
|
||||
{ VK_SHADER_STAGE_VERTEX_BIT,
|
||||
field_offset (iqm_push_constants_t, blend),
|
||||
sizeof (float), &constants.blend },
|
||||
{ VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
field_offset (iqm_push_constants_t, colors),
|
||||
sizeof (constants.colors), constants.colors },
|
||||
{ VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
field_offset (iqm_push_constants_t, base_color),
|
||||
sizeof (constants.base_color), &constants.base_color },
|
||||
{ VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
field_offset (iqm_push_constants_t, fog),
|
||||
sizeof (constants.fog), &constants.fog },
|
||||
};
|
||||
|
||||
if (pass > 1) {
|
||||
alight_t lighting;
|
||||
R_Setup_Lighting (ent, &lighting);
|
||||
push_fwd_constants (Transform_GetWorldMatrixPtr (transform),
|
||||
blend, colors, base_color, &lighting,
|
||||
pass, taskctx);
|
||||
} else {
|
||||
push_iqm_constants (Transform_GetWorldMatrixPtr (transform),
|
||||
blend, colors, base_color, pass, taskctx);
|
||||
}
|
||||
emit_commands (taskctx->cmd, animation->pose1, animation->pose2,
|
||||
pass ? skins : nullptr,
|
||||
pass ? 5 : 2, push_constants,
|
||||
iqm, taskctx, ent);
|
||||
pass ? skins : nullptr, iqm, taskctx, ent);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue