From 93d860472d32133dbc96da14172a39959d58875d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 19 Jan 2024 23:31:18 +0900 Subject: [PATCH] [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". --- libs/video/renderer/Makemodule.am | 17 +++-- libs/video/renderer/vulkan/rp_main_def.plist | 29 ++++---- libs/video/renderer/vulkan/rp_main_fwd.plist | 44 +++++------ libs/video/renderer/vulkan/shader.c | 7 +- libs/video/renderer/vulkan/shader/iqm.vert | 17 +---- .../renderer/vulkan/shader/iqm_shadow.vert | 74 +++++++++++++++++++ .../shader/{alias.frag => qskin_fwd.frag} | 0 libs/video/renderer/vulkan/vulkan_iqm.c | 8 +- 8 files changed, 129 insertions(+), 67 deletions(-) create mode 100644 libs/video/renderer/vulkan/shader/iqm_shadow.vert rename libs/video/renderer/vulkan/shader/{alias.frag => qskin_fwd.frag} (100%) diff --git a/libs/video/renderer/Makemodule.am b/libs/video/renderer/Makemodule.am index c1f5a8ba1..d2d2954fd 100644 --- a/libs/video/renderer/Makemodule.am +++ b/libs/video/renderer/Makemodule.am @@ -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) \ diff --git a/libs/video/renderer/vulkan/rp_main_def.plist b/libs/video/renderer/vulkan/rp_main_def.plist index 13f3b51bb..b91529316 100644 --- a/libs/video/renderer/vulkan/rp_main_def.plist +++ b/libs/video/renderer/vulkan/rp_main_def.plist @@ -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; - }; }; }; }; diff --git a/libs/video/renderer/vulkan/rp_main_fwd.plist b/libs/video/renderer/vulkan/rp_main_fwd.plist index 15ccad42a..00036522b 100644 --- a/libs/video/renderer/vulkan/rp_main_fwd.plist +++ b/libs/video/renderer/vulkan/rp_main_fwd.plist @@ -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; diff --git a/libs/video/renderer/vulkan/shader.c b/libs/video/renderer/vulkan/shader.c index 0ff1ed694..380301d39 100644 --- a/libs/video/renderer/vulkan/shader.c +++ b/libs/video/renderer/vulkan/shader.c @@ -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) }, diff --git a/libs/video/renderer/vulkan/shader/iqm.vert b/libs/video/renderer/vulkan/shader/iqm.vert index 0ac7ff2b6..0325da691 100644 --- a/libs/video/renderer/vulkan/shader/iqm.vert +++ b/libs/video/renderer/vulkan/shader/iqm.vert @@ -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; diff --git a/libs/video/renderer/vulkan/shader/iqm_shadow.vert b/libs/video/renderer/vulkan/shader/iqm_shadow.vert new file mode 100644 index 000000000..0ac7ff2b6 --- /dev/null +++ b/libs/video/renderer/vulkan/shader/iqm_shadow.vert @@ -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; + } +} diff --git a/libs/video/renderer/vulkan/shader/alias.frag b/libs/video/renderer/vulkan/shader/qskin_fwd.frag similarity index 100% rename from libs/video/renderer/vulkan/shader/alias.frag rename to libs/video/renderer/vulkan/shader/qskin_fwd.frag diff --git a/libs/video/renderer/vulkan/vulkan_iqm.c b/libs/video/renderer/vulkan/vulkan_iqm.c index dfba8d256..0c5254f16 100644 --- a/libs/video/renderer/vulkan/vulkan_iqm.c +++ b/libs/video/renderer/vulkan/vulkan_iqm.c @@ -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);