[vulkan] Use the same fragment shader for alias and iqm

In a quake context, I suspect iqm models should use the same skin
concepts as alias models. I'll probably be proven wrong, but it should
make things nicer for now, especially with forward lighting. However,
Mr Fixit is too bright because the skin isn't set up correctly.

Deferred is getting more and more smashed, but I'll fix that up when
I've got forward "done".
This commit is contained in:
Bill Currie 2024-01-19 23:31:18 +09:00
parent 58b42ed1b7
commit 93d860472d
8 changed files with 129 additions and 67 deletions

View file

@ -374,8 +374,8 @@ matrices_h = $(vkshaderpath)/matrices.h
entity_h = $(vkshaderpath)/entity.h
aliasv_src = $(vkshaderpath)/alias.vert
aliasv_c = $(vkshaderpath)/alias.vert.spvc
aliasf_src = $(vkshaderpath)/alias.frag
aliasf_c = $(vkshaderpath)/alias.frag.spvc
qskin_fwdf_src = $(vkshaderpath)/qskin_fwd.frag
qskin_fwdf_c = $(vkshaderpath)/qskin_fwd.frag.spvc
alias_depth_src = $(vkshaderpath)/alias_depth.vert
alias_depth_c = $(vkshaderpath)/alias_depth.vert.spvc
alias_gbuf_src = $(vkshaderpath)/alias_gbuf.frag
@ -388,6 +388,8 @@ iqmf_src = $(vkshaderpath)/iqm.frag
iqmf_c = $(vkshaderpath)/iqm.frag.spvc
iqm_fwd_src = $(vkshaderpath)/iqm_fwd.frag
iqm_fwd_c = $(vkshaderpath)/iqm_fwd.frag.spvc
iqm_shadow_src = $(vkshaderpath)/iqm_shadow.vert
iqm_shadow_c = $(vkshaderpath)/iqm_shadow.vert.spvc
output_src = $(vkshaderpath)/output.frag
output_c = $(vkshaderpath)/output.frag.spvc
passthrough_src = $(vkshaderpath)/passthrough.vert
@ -482,7 +484,7 @@ $(aliasv_c): $(aliasv_src) $(matrices_h)
$(alias_depth_c): $(alias_depth_src) $(matrices_h)
$(aliasf_c): $(aliasf_src)
$(qskin_fwdf_c): $(qskin_fwdf_src)
$(alias_gbuf_c): $(alias_gbuf_src)
@ -494,6 +496,8 @@ $(iqmf_c): $(iqmf_src)
$(iqm_fwd_c): $(iqm_fwd_src)
$(iqm_shadow_c): $(iqm_shadow_src)
$(output_c): $(output_src) $(matrices_h)
$(passthrough_c): $(passthrough_src)
@ -552,12 +556,13 @@ vkshader_c = \
$(compose_fwdf_c) \
$(aliasv_c) \
$(alias_depth_c) \
$(aliasf_c) \
$(qskin_fwdf_c) \
$(alias_gbuf_c) \
$(alias_shadow_c) \
$(iqmv_c) \
$(iqmf_c) \
$(iqm_fwd_c) \
$(iqm_shadow_c) \
$(output_c) \
$(passthrough_c) \
$(fstriangle_c) \
@ -651,13 +656,15 @@ EXTRA_DIST += \
$(composef_src) \
$(compose_fwdf_src) \
$(aliasv_src) \
$(aliasf_src) \
$(qskin_fwdf_src) \
$(alias_depth_src) \
$(alias_gbuf_src) \
$(alias_shadow_src) \
$(iqmv_src) \
$(iqmf_src) \
$(iqm_fwd_src) \
$(iqm_shadow_src) \
$(iqm_shadow_src) \
$(output_src) \
$(passthrough_src) \
$(fstriangle_src) \

View file

@ -409,17 +409,16 @@ properties = {
mapEntries = (
// IQMDepthOnly
{ size = 4; offset = 0; constantID = 0; },
{ size = 4; offset = 4; constantID = 1; },
);
};
shadow_vertex = {
stage = vertex;
name = main;
module = $builtin/iqm.vert;
module = $builtin/iqm_shadow.vert;
specializationInfo = {
@inherit = $iqm.shader.specialization;
// IQMDepthOnly, IQMShadow
data = "array(1, 1)";
// IQMDepthOnly
data = "array(1)";
};
};
depth_vertex = {
@ -428,8 +427,8 @@ properties = {
module = $builtin/iqm.vert;
specializationInfo = {
@inherit = $iqm.shader.specialization;
// IQMDepthOnly, IQMShadow
data = "array(1, 0)";
// IQMDepthOnly
data = "array(1)";
};
};
gbuf_vertex = {
@ -438,8 +437,8 @@ properties = {
module = $builtin/iqm.vert;
specializationInfo = {
@inherit = $iqm.shader.specialization;
// IQMDepthOnly, IQMShadow
data = "array(0, 0)";
// IQMDepthOnly
data = "array(0)";
};
};
gbuf_fragment = {
@ -470,16 +469,18 @@ properties = {
primitiveRestartEnable = false;
};
layout = {
// skin
descriptorSets = (matrix_set, shadowmat_set, texture_set, bone_set);
pushConstants = {
vertex = { Model = mat4; blend = float; };
fragment = { colors = uint; base_color = vec4; fog = vec4; };
};
};
shadow_layout = {
// skin
descriptorSets = (matrix_set, shadowmat_set, texture_set, bone_set);
pushConstants = {
vertex = { Model = mat4; blend = float; MatrixBase = uint; };
fragment = {
colorA = uint;
colorB = uint;
base_color = vec4;
fog = vec4;
};
};
};
};

View file

@ -314,11 +314,6 @@ properties = {
name = main;
module = $builtin/alias.vert;
};
fragment = {
stage = fragment;
name = main;
module = $builtin/alias.frag;
};
};
vertexInput = {
bindings = (
@ -347,6 +342,15 @@ properties = {
};
};
};
qskin = {
shader = {
fragment = {
stage = fragment;
name = main;
module = $builtin/qskin_fwd.frag;
};
};
};
iqm = {
shader = {
specialization = {
@ -362,14 +366,9 @@ properties = {
specializationInfo = {
@inherit = $iqm.shader.specialization;
// IQMDepthOnly
data = "array(0, 0)";
data = "array(0)";
};
};
fragment = {
stage = fragment;
name = main;
module = $builtin/iqm_fwd.frag;
};
};
vertexInput = {
bindings = (
@ -393,20 +392,11 @@ properties = {
primitiveRestartEnable = false;
};
layout = {
// skin
descriptorSets = (matrix_set, shadowmat_set, texture_set, bone_set);
// palette skin
descriptorSets = (matrix_set, texture_set, texture_set, bone_set);
pushConstants = {
vertex = {
Model = mat4;
blend = float;
MatrixBase = uint;
};
fragment = {
colorA = uint;
colorB = uint;
base_color = vec4;
fog = vec4;
};
vertex = { Model = mat4; blend = float; };
fragment = { colors = uint; base_color = vec4; fog = vec4; };
};
};
};
@ -722,7 +712,7 @@ descriptorSetLayouts = {
binding = 1;
descriptorType = storage_buffer;
descriptorCount = 1;
stageFlags = vertex|fragment;
stageFlags = vertex;
},
);
};
@ -1128,7 +1118,7 @@ renderpasses = {
stages = (
$alias.shader.vertex,
$alias.shader.fragment,
$qskin.shader.fragment,
);
vertexInput = $alias.vertexInput;
inputAssembly = $alias.inputAssembly;
@ -1143,7 +1133,7 @@ renderpasses = {
stages = (
$iqm.shader.vertex,
$iqm.shader.fragment,
$qskin.shader.fragment,
);
vertexInput = $iqm.vertexInput;
inputAssembly = $iqm.inputAssembly;

View file

@ -121,7 +121,7 @@ static
static
#include "libs/video/renderer/vulkan/shader/alias_depth.vert.spvc"
static
#include "libs/video/renderer/vulkan/shader/alias.frag.spvc"
#include "libs/video/renderer/vulkan/shader/qskin_fwd.frag.spvc"
static
#include "libs/video/renderer/vulkan/shader/alias_gbuf.frag.spvc"
static
@ -133,6 +133,8 @@ static
static
#include "libs/video/renderer/vulkan/shader/iqm_fwd.frag.spvc"
static
#include "libs/video/renderer/vulkan/shader/iqm_shadow.vert.spvc"
static
#include "libs/video/renderer/vulkan/shader/output.frag.spvc"
static
#include "libs/video/renderer/vulkan/shader/passthrough.vert.spvc"
@ -199,12 +201,13 @@ static shaderdata_t builtin_shaders[] = {
{ "compose_fwd.frag", compose_fwd_frag, sizeof (compose_fwd_frag) },
{ "alias.vert", alias_vert, sizeof (alias_vert) },
{ "alias_depth.vert", alias_depth_vert, sizeof (alias_depth_vert) },
{ "alias.frag", alias_frag, sizeof (alias_frag) },
{ "qskin_fwd.frag", qskin_fwd_frag, sizeof (qskin_fwd_frag) },
{ "alias_gbuf.frag", alias_gbuf_frag, sizeof (alias_gbuf_frag) },
{ "alias_shadow.vert", alias_shadow_vert, sizeof (alias_shadow_vert) },
{ "iqm.vert", iqm_vert, sizeof (iqm_vert) },
{ "iqm.frag", iqm_frag, sizeof (iqm_frag) },
{ "iqm_fwd.frag", iqm_fwd_frag, sizeof (iqm_fwd_frag) },
{ "iqm_shadow.vert", iqm_shadow_vert, sizeof (iqm_shadow_vert) },
{ "output.frag", output_frag, sizeof (output_frag) },
{ "passthrough.vert", passthrough_vert, sizeof (passthrough_vert) },
{ "fstriangle.vert", fstriangle_vert, sizeof (fstriangle_vert) },

View file

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

View file

@ -0,0 +1,74 @@
#version 450
#extension GL_GOOGLE_include_directive : enable
#extension GL_EXT_multiview : enable
layout (constant_id = 0) const bool IQMDepthOnly = false;
layout (constant_id = 1) const bool IQMShadow = false;
layout (set = 0, binding = 0) uniform
#include "matrices.h"
;
layout (set = 1, binding = 0) buffer ShadowView {
mat4x4 shadowView[];
};
layout (set = 1, binding = 1) buffer ShadowId {
uint shadowId[];
};
layout (set = 3, binding = 0) buffer Bones {
// NOTE these are transposed, so v * m
mat3x4 bones[];
};
layout (push_constant) uniform PushConstants {
mat4 Model;
float blend;
uint MatrixBase;
};
layout (location = 0) in vec3 vposition;
layout (location = 1) in uvec4 vbones;
layout (location = 2) in vec4 vweights;
layout (location = 3) in vec2 vtexcoord;
layout (location = 4) in vec3 vnormal;
layout (location = 5) in vec4 vtangent;
layout (location = 6) in vec4 vcolor;
layout (location = 0) out vec2 texcoord;
layout (location = 1) out vec4 position;
layout (location = 2) out vec3 normal;
layout (location = 3) out vec3 tangent;
layout (location = 4) out vec3 bitangent;
layout (location = 5) out vec4 color;
void
main (void)
{
mat3x4 m = bones[vbones.x] * vweights.x;
m += bones[vbones.y] * vweights.y;
m += bones[vbones.z] * vweights.z;
m += bones[vbones.w] * vweights.w;
m += mat3x4(1,0,0,0,0,1,0,0,0,0,1,0) * (1 - dot(vweights, vec4(1,1,1,1)));
vec4 pos = Model * vec4 (vec4(vposition, 1) * m, 1);
if (IQMShadow) {
uint matid = shadowId[MatrixBase + gl_ViewIndex];
gl_Position = shadowView[matid] * pos;
} else {
gl_Position = Projection3d * (View[gl_ViewIndex] * pos);
}
if (!IQMDepthOnly) {
position = pos;
mat3 adjTrans = mat3 (cross(m[1].xyz, m[2].xyz),
cross(m[2].xyz, m[0].xyz),
cross(m[0].xyz, m[1].xyz));
normal = normalize (mat3 (Model) * vnormal * adjTrans);
tangent = mat3 (Model) * vtangent.xyz * adjTrans;
tangent = normalize (tangent - dot (tangent, normal) * normal);
bitangent = cross (normal, tangent) * vtangent.w;
texcoord = vtexcoord;
color = vcolor;
}
}

View file

@ -42,6 +42,7 @@
#include "QF/Vulkan/qf_iqm.h"
#include "QF/Vulkan/qf_lighting.h"
#include "QF/Vulkan/qf_matrices.h"
#include "QF/Vulkan/qf_palette.h"
#include "QF/Vulkan/qf_texture.h"
#include "QF/Vulkan/debug.h"
#include "QF/Vulkan/device.h"
@ -278,10 +279,11 @@ iqm_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
auto dfunc = device->funcs;
auto layout = taskctx->pipeline->layout;
auto cmd = taskctx->cmd;
bool shadow = !!taskctx->data;
VkDescriptorSet sets[] = {
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
Vulkan_Lighting_Descriptors (ctx, ctx->curFrame),
shadow ? Vulkan_Lighting_Descriptors (ctx, ctx->curFrame)
: Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
Vulkan_Palette_Descriptor (ctx),
};
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
layout, 0, 2, sets, 0, 0);