From 778ffadd54c2fd93261a1b3e133124b9aadfdc00 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 20 Jan 2024 19:42:28 +0900 Subject: [PATCH] [vulkan] Implement fog for the forward renderer Other than decoupled lightmap support, I think that has the vulkan forward renderer feature complete (though a little buggy with its lightmap updates and fisheye gets validation errors). --- libs/video/renderer/Makemodule.am | 13 +++++++------ libs/video/renderer/vulkan/rp_main_fwd.plist | 1 + libs/video/renderer/vulkan/shader/bsp_sky.frag | 14 +++----------- libs/video/renderer/vulkan/shader/bsp_turb.frag | 17 ++++------------- libs/video/renderer/vulkan/shader/fog.finc | 11 +++++++++++ libs/video/renderer/vulkan/shader/particle.frag | 10 +++++++++- .../video/renderer/vulkan/shader/qskin_fwd.frag | 5 ++++- libs/video/renderer/vulkan/shader/quakebsp.frag | 15 ++++----------- libs/video/renderer/vulkan/shader/sprite.frag | 5 ++++- libs/video/renderer/vulkan/vulkan_alias.c | 2 ++ libs/video/renderer/vulkan/vulkan_bsp.c | 5 ++--- libs/video/renderer/vulkan/vulkan_iqm.c | 2 ++ libs/video/renderer/vulkan/vulkan_particles.c | 4 +++- libs/video/renderer/vulkan/vulkan_sprite.c | 4 ++++ 14 files changed, 60 insertions(+), 48 deletions(-) create mode 100644 libs/video/renderer/vulkan/shader/fog.finc diff --git a/libs/video/renderer/Makemodule.am b/libs/video/renderer/Makemodule.am index 291d3b887..09334bf81 100644 --- a/libs/video/renderer/Makemodule.am +++ b/libs/video/renderer/Makemodule.am @@ -367,6 +367,7 @@ composef_c = $(vkshaderpath)/compose.frag.spvc compose_fwdf_src = $(vkshaderpath)/compose_fwd.frag compose_fwdf_c = $(vkshaderpath)/compose_fwd.frag.spvc infplane = $(vkshaderpath)/infplane.finc +fog_h = $(vkshaderpath)/fog.finc oit_blend = $(vkshaderpath)/oit_blend.finc oit_store = $(vkshaderpath)/oit_store.finc oit_h = $(vkshaderpath)/oit.h @@ -416,9 +417,9 @@ $(partphysicsc_c): $(partphysicsc_src) $(partupdatec_c): $(partupdatec_src) $(particlev_c): $(particlev_src) $(matrices_h) $(particleg_c): $(particleg_src) $(matrices_h) -$(particlef_c): $(particlef_src) $(oit_store) $(oit_h) +$(particlef_c): $(particlef_src) $(oit_store) $(oit_h) $(fog_h) -$(spritef_c): $(spritef_src) +$(spritef_c): $(spritef_src) $(fog_h) $(sprite_gbufv_c): $(sprite_gbufv_src) $(matrices_h) @@ -436,7 +437,7 @@ $(twodf_c): $(twodf_src) $(quakebspv_c): $(quakebspv_src) $(entity_h) $(matrices_h) -$(quakebspf_c): $(quakebspf_src) +$(quakebspf_c): $(quakebspf_src) $(fog_h) $(bsp_depth_c): $(bsp_depth_src) $(entity_h) $(matrices_h) @@ -448,9 +449,9 @@ $(bsp_gbuff_c): $(bsp_gbuff_src) $(bsp_shadow_c): $(bsp_shadow_src) $(entity_h) -$(bsp_skyf_c): $(bsp_skyf_src) $(oit_store) $(oit_h) +$(bsp_skyf_c): $(bsp_skyf_src) $(oit_store) $(oit_h) $(fog_h) -$(bsp_turbf_c): $(bsp_turbf_src) $(oit_store) $(oit_h) +$(bsp_turbf_c): $(bsp_turbf_src) $(oit_store) $(oit_h) $(fog_h) $(debug_c): $(debug_src) $(lighting_h) @@ -484,7 +485,7 @@ $(aliasv_c): $(aliasv_src) $(matrices_h) $(alias_depth_c): $(alias_depth_src) $(matrices_h) -$(qskin_fwdf_c): $(qskin_fwdf_src) +$(qskin_fwdf_c): $(qskin_fwdf_src) $(fog_h) $(qskin_gbuf_c): $(qskin_gbuf_src) diff --git a/libs/video/renderer/vulkan/rp_main_fwd.plist b/libs/video/renderer/vulkan/rp_main_fwd.plist index f6799f035..b9fc87264 100644 --- a/libs/video/renderer/vulkan/rp_main_fwd.plist +++ b/libs/video/renderer/vulkan/rp_main_fwd.plist @@ -496,6 +496,7 @@ properties = { descriptorSets = (matrix_set, texture_set, oit_set); pushConstants = { vertex = { Model = mat4; }; + fragment = { fog = vec4; }; }; }; physics = { diff --git a/libs/video/renderer/vulkan/shader/bsp_sky.frag b/libs/video/renderer/vulkan/shader/bsp_sky.frag index a574bec37..f9c90edd8 100644 --- a/libs/video/renderer/vulkan/shader/bsp_sky.frag +++ b/libs/video/renderer/vulkan/shader/bsp_sky.frag @@ -2,6 +2,8 @@ #extension GL_GOOGLE_include_directive : enable #extension GL_EXT_multiview : enable +#include "fog.finc" + #include "oit_store.finc" layout (constant_id = 0) const bool doSkyBox = false; @@ -26,16 +28,6 @@ layout(early_fragment_tests) in; const float SCALE = 189.0 / 64.0; -vec4 -fogBlend (vec4 color) -{ - float az = fog.a * gl_FragCoord.z / gl_FragCoord.w; - vec3 fog_color = fog.rgb; - float fog_factor = exp (-az * az); - - return vec4 (mix (fog_color.rgb, color.rgb, fog_factor), color.a); -} - vec4 sky_sheet (vec3 dir, float time) { @@ -100,6 +92,6 @@ main (void) } else { c = vec4 (0, 0, 0, 1); } - //frag_color = c;//fogBlend (c); + c = FogBlend (c, fog); StoreFrag (c, gl_FragCoord.z); } diff --git a/libs/video/renderer/vulkan/shader/bsp_turb.frag b/libs/video/renderer/vulkan/shader/bsp_turb.frag index 7254eee87..6f454748c 100644 --- a/libs/video/renderer/vulkan/shader/bsp_turb.frag +++ b/libs/video/renderer/vulkan/shader/bsp_turb.frag @@ -2,6 +2,8 @@ #extension GL_GOOGLE_include_directive : enable #extension GL_EXT_multiview : enable +#include "fog.finc" + #include "oit_store.finc" layout (set = 3, binding = 0) uniform sampler2DArray Texture; @@ -18,7 +20,6 @@ layout (location = 1) in vec3 direction; layout (location = 2) in vec4 color; layout(early_fragment_tests) in; -//layout (location = 0) out vec4 frag_color; const float PI = 3.14159265; const float SPEED = 20.0; @@ -35,16 +36,6 @@ warp_st (vec2 st, float time) return st + turb_scale * (sin ((angle + phase) * FACTOR) + BIAS) / SCALE; } -vec4 -fogBlend (vec4 color) -{ - float az = fog.a * gl_FragCoord.z / gl_FragCoord.w; - vec3 fog_color = fog.rgb; - float fog_factor = exp (-az * az); - - return vec4 (mix (fog_color.rgb, color.rgb, fog_factor), color.a); -} - void main (void) { @@ -54,6 +45,6 @@ main (void) float a = c.a * e.a * alpha; c += e; c.a = a; - //frag_color = c * color;//fogBlend (c); - StoreFrag (c * color, gl_FragCoord.z); + c = FogBlend (c * color, fog); + StoreFrag (c, gl_FragCoord.z); } diff --git a/libs/video/renderer/vulkan/shader/fog.finc b/libs/video/renderer/vulkan/shader/fog.finc new file mode 100644 index 000000000..af572a27b --- /dev/null +++ b/libs/video/renderer/vulkan/shader/fog.finc @@ -0,0 +1,11 @@ +vec4 +FogBlend (vec4 color, vec4 fog) +{ + float az = fog.a * 1 / gl_FragCoord.w; + //float az = fog.a * (4 - gl_FragCoord.w); + vec4 fog_color = vec4 (fog.rgb, 1.0); + + float fog_factor = exp (-az * az); + //return vec4 (mix (fog_color.rgb, color.rgb, fog_factor), color.a); + return mix (fog_color, color, fog_factor); +} diff --git a/libs/video/renderer/vulkan/shader/particle.frag b/libs/video/renderer/vulkan/shader/particle.frag index 304f07d2d..55bc15b85 100644 --- a/libs/video/renderer/vulkan/shader/particle.frag +++ b/libs/video/renderer/vulkan/shader/particle.frag @@ -2,8 +2,15 @@ #extension GL_GOOGLE_include_directive : enable #extension GL_EXT_multiview : enable +#include "fog.finc" + #include "oit_store.finc" +layout (push_constant) uniform PushConstants { + layout (offset = 64) + vec4 fog; +}; + layout (location = 0) in vec4 uv_tr; layout (location = 1) in vec4 color; @@ -19,6 +26,7 @@ main (void) if (a <= 0) { discard; } - c *= (a); + //c = c * a; + c = FogBlend (c * a, fog); StoreFrag (c, gl_FragCoord.z); } diff --git a/libs/video/renderer/vulkan/shader/qskin_fwd.frag b/libs/video/renderer/vulkan/shader/qskin_fwd.frag index b9b75cbfd..d61e1ab62 100644 --- a/libs/video/renderer/vulkan/shader/qskin_fwd.frag +++ b/libs/video/renderer/vulkan/shader/qskin_fwd.frag @@ -1,4 +1,7 @@ #version 450 +#extension GL_GOOGLE_include_directive : enable + +#include "fog.finc" layout (set = 1, binding = 0) uniform sampler2D Palette; layout (set = 2, binding = 0) uniform sampler2DArray Skin; @@ -35,5 +38,5 @@ main (void) light -= d * shadelight; light = max (light, 0.0) / 255; - frag_color = light * c + e;//fogBlend (c); + frag_color = FogBlend (light * c + e, fog); } diff --git a/libs/video/renderer/vulkan/shader/quakebsp.frag b/libs/video/renderer/vulkan/shader/quakebsp.frag index 32942539e..eb83e7991 100644 --- a/libs/video/renderer/vulkan/shader/quakebsp.frag +++ b/libs/video/renderer/vulkan/shader/quakebsp.frag @@ -1,4 +1,7 @@ #version 450 +#extension GL_GOOGLE_include_directive : enable + +#include "fog.finc" layout (set = 3, binding = 0) uniform sampler2DArray Texture; layout (set = 4, binding = 0) uniform sampler2D Lightmap; @@ -17,16 +20,6 @@ layout (location = 4) in vec4 color; layout (location = 0) out vec4 frag_color; -vec4 -fogBlend (vec4 color) -{ - float az = fog.a * gl_FragCoord.z / gl_FragCoord.w; - vec3 fog_color = fog.rgb; - float fog_factor = exp (-az * az); - - return vec4 (mix (fog_color.rgb, color.rgb, fog_factor), color.a); -} - void main (void) { @@ -38,5 +31,5 @@ main (void) vec4 e = texture (Texture, e_st); vec4 l = texture (Lightmap, l_st); - frag_color = c * l + e;//fogBlend (c); + frag_color = FogBlend (c * l + e, fog); } diff --git a/libs/video/renderer/vulkan/shader/sprite.frag b/libs/video/renderer/vulkan/shader/sprite.frag index 50bddebab..7a8a9fb28 100644 --- a/libs/video/renderer/vulkan/shader/sprite.frag +++ b/libs/video/renderer/vulkan/shader/sprite.frag @@ -1,4 +1,7 @@ #version 450 +#extension GL_GOOGLE_include_directive : enable + +#include "fog.finc" layout (set = 1, binding = 1) uniform sampler2DArray Texture; @@ -27,5 +30,5 @@ main (void) if (pix.a < 0.5) { discard; } - frag_color = pix; + frag_color = FogBlend (pix, fog); } diff --git a/libs/video/renderer/vulkan/vulkan_alias.c b/libs/video/renderer/vulkan/vulkan_alias.c index edca4594a..76a085386 100644 --- a/libs/video/renderer/vulkan/vulkan_alias.c +++ b/libs/video/renderer/vulkan/vulkan_alias.c @@ -122,6 +122,7 @@ push_alias_constants (const mat4f_t mat, float blend, byte *colors, .blend = blend, .colors = { VEC4_EXP (colors) }, .base_color = base_color, + .fog = Fog_Get (), }; qfv_push_constants_t push_constants[] = { @@ -161,6 +162,7 @@ push_fwd_constants (const mat4f_t mat, float blend, byte *colors, .shadelight = lighting->shadelight, .lightvec = { VectorExpand (lighting->lightvec) }, .base_color = base_color, + .fog = Fog_Get (), }; qfv_push_constants_t push_constants[] = { diff --git a/libs/video/renderer/vulkan/vulkan_bsp.c b/libs/video/renderer/vulkan/vulkan_bsp.c index 62abf2355..7f6c89728 100644 --- a/libs/video/renderer/vulkan/vulkan_bsp.c +++ b/libs/video/renderer/vulkan/vulkan_bsp.c @@ -77,7 +77,7 @@ #define LIGHTMAP_SET 4 typedef struct bsp_push_constants_s { - quat_t fog; + vec4f_t fog; float time; float alpha; float turb_scale; @@ -862,9 +862,8 @@ static void push_fragconst (QFV_BspQueue queue, VkPipelineLayout layout, qfv_device_t *device, VkCommandBuffer cmd) { - //XXX glsl_Fog_GetColor (fog); - //XXX fog[3] = glsl_Fog_GetDensity () / 64.0; bsp_frag_constants_t constants = { + .fog = Fog_Get (), .time = vr_data.realtime, .alpha = queue == QFV_bspTurb ? r_wateralpha : 1, .turb_scale = queue == QFV_bspTurb ? 1 : 0, diff --git a/libs/video/renderer/vulkan/vulkan_iqm.c b/libs/video/renderer/vulkan/vulkan_iqm.c index b685f0123..3a82576f9 100644 --- a/libs/video/renderer/vulkan/vulkan_iqm.c +++ b/libs/video/renderer/vulkan/vulkan_iqm.c @@ -213,6 +213,7 @@ push_iqm_constants (const mat4f_t mat, float blend, byte *colors, .blend = blend, .colors = { VEC4_EXP (colors) }, .base_color = base_color, + .fog = Fog_Get (), }; qfv_push_constants_t push_constants[] = { @@ -252,6 +253,7 @@ push_fwd_constants (const mat4f_t mat, float blend, byte *colors, .shadelight = lighting->shadelight, .lightvec = { VectorExpand (lighting->lightvec) }, .base_color = base_color, + .fog = Fog_Get (), }; qfv_push_constants_t push_constants[] = { diff --git a/libs/video/renderer/vulkan/vulkan_particles.c b/libs/video/renderer/vulkan/vulkan_particles.c index 830ac58d1..d8e26c53a 100644 --- a/libs/video/renderer/vulkan/vulkan_particles.c +++ b/libs/video/renderer/vulkan/vulkan_particles.c @@ -182,10 +182,12 @@ particles_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx) mat4f_t mat; mat4fidentity (mat); + vec4f_t fog = Fog_Get (); qfv_push_constants_t push_constants[] = { { VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof (mat4f_t), &mat }, + { VK_SHADER_STAGE_FRAGMENT_BIT, 64, sizeof (fog), &fog }, }; - QFV_PushConstants (device, cmd, layout, 1, push_constants); + QFV_PushConstants (device, cmd, layout, 2, push_constants); VkDeviceSize offsets[] = { 0 }; VkBuffer buffers[] = { pframe->states, diff --git a/libs/video/renderer/vulkan/vulkan_sprite.c b/libs/video/renderer/vulkan/vulkan_sprite.c index 3984df75f..38e9b391a 100644 --- a/libs/video/renderer/vulkan/vulkan_sprite.c +++ b/libs/video/renderer/vulkan/vulkan_sprite.c @@ -156,10 +156,14 @@ sprite_draw_ent (qfv_taskctx_t *taskctx, entity_t ent) mat4f_t mat = {}; uint32_t frame; + vec4f_t fog = Fog_Get (); qfv_push_constants_t push_constants[] = { { VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof (mat), mat }, { VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 64, sizeof (frame), &frame }, + { VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, + 64, sizeof (frame), &frame }, + { VK_SHADER_STAGE_FRAGMENT_BIT, 72, sizeof (fog), &fog }, }; auto animation = Entity_GetAnimation (ent);