mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-22 12:31:10 +00:00
[vulkan] Use palette lookups for top/bottom colors
As the RGB curves for many of the color rows are not linearly related, my idea of scaling the brightest color in the row just didn't work. Using a masked palette lookup works much better as it allows any curves. Also, because the palette is uploaded as a grid and the coordinates are calculated on the CPU, the system is extendable beyond 8-bit palettes. This isn't quite complete as the top and bottom colors are still in separate layers but their indices and masks can fit in just one, but this requires reworking the texture setup (for another commit).
This commit is contained in:
parent
4d7f72948d
commit
668f7f2cd2
7 changed files with 54 additions and 24 deletions
|
@ -58,8 +58,7 @@ typedef struct qfv_alias_skin_s {
|
|||
VkDeviceMemory memory;
|
||||
VkImage image;
|
||||
VkImageView view;
|
||||
byte colora[4];
|
||||
byte colorb[4];
|
||||
byte colors[4];
|
||||
VkDescriptorSet descriptor;
|
||||
} qfv_alias_skin_t;
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
typedef struct palettectx_s {
|
||||
struct qfv_tex_s *palette;
|
||||
VkSampler sampler;
|
||||
VkDescriptorSet descriptor;
|
||||
} palettectx_t;
|
||||
|
||||
struct vulkan_ctx_s;
|
||||
|
@ -45,5 +46,6 @@ struct vulkan_ctx_s;
|
|||
void Vulkan_Palette_Update (struct vulkan_ctx_s *ctx, const byte *palette);
|
||||
void Vulkan_Palette_Init (struct vulkan_ctx_s *ctx, const byte *palette);
|
||||
void Vulkan_Palette_Shutdown (struct vulkan_ctx_s *ctx);
|
||||
VkDescriptorSet Vulkan_Palette_Descriptor (struct vulkan_ctx_s *ctx) __attribute__((pure));
|
||||
|
||||
#endif//__QF_Vulkan_qf_palette_h
|
||||
|
|
|
@ -125,8 +125,7 @@ Vulkan_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skinpix, int skinsize,
|
|||
int w, h;
|
||||
|
||||
skin = Hunk_Alloc (0, sizeof (qfv_alias_skin_t));
|
||||
QuatCopy (vid.palette32 + (TOP_RANGE + 15) * 4, skin->colora);
|
||||
QuatCopy (vid.palette32 + (BOTTOM_RANGE + 15) * 4, skin->colorb);
|
||||
QuatSet (TOP_RANGE + 7, BOTTOM_RANGE + 7, 0, 0, skin->colors);
|
||||
skindesc->skin = (byte *) skin - (byte *) header;
|
||||
//FIXME move all skins into arrays(?)
|
||||
w = header->mdl.skinwidth;
|
||||
|
@ -175,13 +174,31 @@ Vulkan_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skinpix, int skinsize,
|
|||
skinsize);
|
||||
Mod_ClearFullbright (tskin, tskin, skinsize);
|
||||
|
||||
static byte map_palette[] = {
|
||||
0x08, 0x00, 0x00,
|
||||
0x18, 0xff, 0x00,
|
||||
0x28, 0xff, 0x00,
|
||||
0x38, 0xff, 0x00,
|
||||
0x48, 0xff, 0x00,
|
||||
0x58, 0xff, 0x00,
|
||||
0x68, 0xff, 0x00,
|
||||
0x78, 0xff, 0x00,
|
||||
0x88, 0xff, 0x00,
|
||||
0x98, 0xff, 0x00,
|
||||
0xa8, 0xff, 0x00,
|
||||
0xb8, 0xff, 0x00,
|
||||
0xc8, 0xff, 0x00,
|
||||
0xd8, 0xff, 0x00,
|
||||
0xe8, 0xff, 0x00,
|
||||
0xf8, 0xff, 0x00,
|
||||
};
|
||||
Skin_CalcTopColors (tskin + skinsize, tskin, skinsize);
|
||||
Vulkan_ExpandPalette (cola_data, tskin + skinsize, vid.palette, 1,
|
||||
Vulkan_ExpandPalette (cola_data, tskin + skinsize, map_palette, 1,
|
||||
skinsize);
|
||||
Skin_ClearTopColors (tskin, tskin, skinsize);
|
||||
|
||||
Skin_CalcBottomColors (tskin + skinsize, tskin, skinsize);
|
||||
Vulkan_ExpandPalette (colb_data, tskin + skinsize, vid.palette, 1,
|
||||
Vulkan_ExpandPalette (colb_data, tskin + skinsize, map_palette, 1,
|
||||
skinsize);
|
||||
Skin_ClearBottomColors (tskin, tskin, skinsize);
|
||||
|
||||
|
|
|
@ -426,7 +426,7 @@
|
|||
);
|
||||
};
|
||||
alias_layout = {
|
||||
setLayouts = (matrix_set, texture_set);
|
||||
setLayouts = (matrix_set, texture_set, texture_set);
|
||||
pushConstantRanges = (
|
||||
{
|
||||
stageFlags = vertex;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#version 450
|
||||
|
||||
layout (set = 1, binding = 0) uniform sampler2DArray Skin;
|
||||
layout (set = 1, binding = 0) uniform sampler2D Palette;
|
||||
layout (set = 2, binding = 0) uniform sampler2DArray Skin;
|
||||
|
||||
layout (push_constant) uniform PushConstants {
|
||||
layout (offset = 68)
|
||||
uint colorA;
|
||||
uint colorB;
|
||||
uint colors;
|
||||
vec4 base_color;
|
||||
vec4 fog;
|
||||
};
|
||||
|
@ -26,9 +26,14 @@ main (void)
|
|||
vec4 e;
|
||||
int i;
|
||||
vec3 light = vec3 (0);
|
||||
vec4 rows = unpackUnorm4x8(colors);
|
||||
vec2 cols = vec2 (texture (Skin, vec3 (st, 1)).r,
|
||||
texture (Skin, vec3 (st, 2)).r);
|
||||
vec2 mask = vec2 (texture (Skin, vec3 (st, 1)).g,
|
||||
texture (Skin, vec3 (st, 2)).g);
|
||||
c = texture (Skin, vec3 (st, 0)) * base_color;
|
||||
c += texture (Skin, vec3 (st, 1)) * unpackUnorm4x8(colorA) * 2;
|
||||
c += texture (Skin, vec3 (st, 2)) * unpackUnorm4x8(colorB) * 2;
|
||||
c += texture (Palette, vec2 (cols.x, rows.x)) * mask.x;
|
||||
c += texture (Palette, vec2 (cols.y, rows.y)) * mask.y;
|
||||
e = texture (Skin, vec3 (st, 3));
|
||||
|
||||
frag_color = c;
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include "QF/Vulkan/qf_alias.h"
|
||||
#include "QF/Vulkan/qf_matrices.h"
|
||||
#include "QF/Vulkan/qf_palette.h"
|
||||
#include "QF/Vulkan/qf_renderpass.h"
|
||||
#include "QF/Vulkan/qf_texture.h"
|
||||
#include "QF/Vulkan/debug.h"
|
||||
|
@ -54,8 +55,7 @@
|
|||
typedef struct {
|
||||
mat4f_t mat;
|
||||
float blend;
|
||||
byte colorA[4];
|
||||
byte colorB[4];
|
||||
byte colors[4];
|
||||
vec4f_t base_color;
|
||||
vec4f_t fog;
|
||||
} alias_push_constants_t;
|
||||
|
@ -108,7 +108,7 @@ emit_commands (VkCommandBuffer cmd, int pose1, int pose2,
|
|||
skin->descriptor,
|
||||
};
|
||||
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
actx->layout, 1, 1, sets, 0, 0);
|
||||
actx->layout, 2, 1, sets, 0, 0);
|
||||
}
|
||||
dfunc->vkCmdDrawIndexed (cmd, 3 * hdr->mdl.numtris, 1, 0, 0, 0);
|
||||
|
||||
|
@ -144,11 +144,8 @@ Vulkan_DrawAlias (entity_t ent, qfv_renderframe_t *rFrame)
|
|||
field_offset (alias_push_constants_t, blend),
|
||||
sizeof (float), &constants.blend },
|
||||
{ VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
field_offset (alias_push_constants_t, colorA),
|
||||
sizeof (constants.colorA), constants.colorA },
|
||||
{ VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
field_offset (alias_push_constants_t, colorB),
|
||||
sizeof (constants.colorB), constants.colorB },
|
||||
field_offset (alias_push_constants_t, colors),
|
||||
sizeof (constants.colors), constants.colors },
|
||||
{ VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
field_offset (alias_push_constants_t, base_color),
|
||||
sizeof (constants.base_color), &constants.base_color },
|
||||
|
@ -165,8 +162,7 @@ Vulkan_DrawAlias (entity_t ent, qfv_renderframe_t *rFrame)
|
|||
skin = (qfv_alias_skin_t *) ((byte *) hdr + skindesc->skin);
|
||||
}
|
||||
QuatCopy (renderer->colormod, constants.base_color);
|
||||
QuatCopy (skin->colora, constants.colorA);
|
||||
QuatCopy (skin->colorb, constants.colorB);
|
||||
QuatCopy (skin->colors, constants.colors);
|
||||
QuatZero (constants.fog);
|
||||
|
||||
emit_commands (aframe->cmdSet.a[QFV_aliasDepth],
|
||||
|
@ -174,7 +170,7 @@ Vulkan_DrawAlias (entity_t ent, qfv_renderframe_t *rFrame)
|
|||
0, 2, push_constants, hdr, rFrame, ent);
|
||||
emit_commands (aframe->cmdSet.a[QFV_aliasGBuffer],
|
||||
animation->pose1, animation->pose2,
|
||||
skin, 6, push_constants, hdr, rFrame, ent);
|
||||
skin, 5, push_constants, hdr, rFrame, ent);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -210,9 +206,10 @@ alias_begin_subpass (QFV_AliasSubpass subpass, VkPipeline pipeline,
|
|||
dfunc->vkCmdBindPipeline (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||
VkDescriptorSet sets[] = {
|
||||
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
|
||||
Vulkan_Palette_Descriptor (ctx),
|
||||
};
|
||||
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
actx->layout, 0, 1, sets, 0, 0);
|
||||
actx->layout, 0, 2, sets, 0, 0);
|
||||
dfunc->vkCmdSetViewport (cmd, 0, 1, &rFrame->renderpass->viewport);
|
||||
dfunc->vkCmdSetScissor (cmd, 0, 1, &rFrame->renderpass->scissor);
|
||||
|
||||
|
|
|
@ -78,6 +78,9 @@ Vulkan_Palette_Init (vulkan_ctx_t *ctx, const byte *palette)
|
|||
.data = (byte *) palette,
|
||||
};
|
||||
pctx->palette = Vulkan_LoadTex (ctx, &tex, 0, "palette");
|
||||
pctx->descriptor = Vulkan_CreateCombinedImageSampler (ctx,
|
||||
pctx->palette->view,
|
||||
pctx->sampler);
|
||||
|
||||
qfvPopDebug (ctx);
|
||||
}
|
||||
|
@ -94,3 +97,10 @@ Vulkan_Palette_Shutdown (vulkan_ctx_t *ctx)
|
|||
|
||||
qfvPopDebug (ctx);
|
||||
}
|
||||
|
||||
VkDescriptorSet
|
||||
Vulkan_Palette_Descriptor (struct vulkan_ctx_s *ctx)
|
||||
{
|
||||
__auto_type pctx = ctx->palette_context;
|
||||
return pctx->descriptor;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue