diff --git a/include/QF/Vulkan/qf_bsp.h b/include/QF/Vulkan/qf_bsp.h index 376eaa181..a6d2b379a 100644 --- a/include/QF/Vulkan/qf_bsp.h +++ b/include/QF/Vulkan/qf_bsp.h @@ -110,6 +110,7 @@ typedef struct bsp_draw_s { typedef struct bsp_drawset_s DARRAY_TYPE (bsp_draw_t) bsp_drawset_t; +#define INST_ALPHA (1u<<31) typedef struct instface_s { uint32_t inst_id; uint32_t face; diff --git a/libs/video/renderer/vulkan/qfpipeline.plist b/libs/video/renderer/vulkan/qfpipeline.plist index 9c16a5556..4e4f59e9e 100644 --- a/libs/video/renderer/vulkan/qfpipeline.plist +++ b/libs/video/renderer/vulkan/qfpipeline.plist @@ -365,7 +365,7 @@ { stageFlags = fragment; offset = 0; - size = "4 * 4 + 4 + 4"; + size = "4 * 4 + 4 + 4 + 4"; }, ); }; diff --git a/libs/video/renderer/vulkan/shader/bsp_gbuf.frag b/libs/video/renderer/vulkan/shader/bsp_gbuf.frag index f807f52a2..0c1df1795 100644 --- a/libs/video/renderer/vulkan/shader/bsp_gbuf.frag +++ b/libs/video/renderer/vulkan/shader/bsp_gbuf.frag @@ -12,6 +12,7 @@ layout (location = 0) in vec4 tl_st; layout (location = 1) in vec3 direction; layout (location = 2) in vec3 normal; layout (location = 3) in vec4 position; +layout (location = 4) in vec4 color; layout (location = 0) out vec4 frag_color; layout (location = 1) out vec4 frag_emission; @@ -37,7 +38,7 @@ main (void) vec3 e_st = vec3 (tl_st.xy, 1); vec2 l_st = vec2 (tl_st.zw); - c = texture (Texture, t_st); + c = texture (Texture, t_st) * color; e = texture (Texture, e_st); frag_color = c;//fogBlend (c); frag_emission = e; diff --git a/libs/video/renderer/vulkan/shader/bsp_gbuf.geom b/libs/video/renderer/vulkan/shader/bsp_gbuf.geom index 44f17a3b1..15cb5a537 100644 --- a/libs/video/renderer/vulkan/shader/bsp_gbuf.geom +++ b/libs/video/renderer/vulkan/shader/bsp_gbuf.geom @@ -11,11 +11,13 @@ layout (triangles) in; layout (triangle_strip, max_vertices = 3) out; layout (location = 0) in vec4 v_tl_st[]; layout (location = 1) in vec3 v_direction[]; +layout (location = 2) in vec4 v_color[]; layout (location = 0) out vec4 tl_st; layout (location = 1) out vec3 direction; layout (location = 2) out vec3 normal; layout (location = 3) out vec4 position; +layout (location = 4) out vec4 color; void main() @@ -31,6 +33,7 @@ main() gl_Position = Projection3d * (View * (p)); tl_st = v_tl_st[vert]; direction = v_direction[vert]; + color = v_color[vert]; normal = n; position = p; EmitVertex (); diff --git a/libs/video/renderer/vulkan/shader/bsp_gbuf.vert b/libs/video/renderer/vulkan/shader/bsp_gbuf.vert index b5866d8b6..6cb8efb28 100644 --- a/libs/video/renderer/vulkan/shader/bsp_gbuf.vert +++ b/libs/video/renderer/vulkan/shader/bsp_gbuf.vert @@ -20,6 +20,7 @@ layout (location = 2) in uint entid; layout (location = 0) out vec4 tl_st; layout (location = 1) out vec3 direction; +layout (location = 2) out vec4 color; void main (void) @@ -29,4 +30,5 @@ main (void) gl_Position = vec4 (vert, 1); direction = (Sky * vertex).xyz; tl_st = tl_uv; + color = entities[entid].color; } diff --git a/libs/video/renderer/vulkan/shader/bsp_sky.frag b/libs/video/renderer/vulkan/shader/bsp_sky.frag index 897310930..f6e35ceee 100644 --- a/libs/video/renderer/vulkan/shader/bsp_sky.frag +++ b/libs/video/renderer/vulkan/shader/bsp_sky.frag @@ -10,10 +10,12 @@ layout (push_constant) uniform PushConstants { vec4 fog; float time; float alpha; + float turb_scale; }; layout (location = 0) in vec4 tl_st; layout (location = 1) in vec3 direction; +layout (location = 2) in vec4 color; layout (location = 0) out vec4 frag_color; diff --git a/libs/video/renderer/vulkan/shader/bsp_turb.frag b/libs/video/renderer/vulkan/shader/bsp_turb.frag index fdc7dfc10..fe7e50b71 100644 --- a/libs/video/renderer/vulkan/shader/bsp_turb.frag +++ b/libs/video/renderer/vulkan/shader/bsp_turb.frag @@ -6,10 +6,12 @@ layout (push_constant) uniform PushConstants { vec4 fog; float time; float alpha; + float turb_scale; }; layout (location = 0) in vec4 tl_st; layout (location = 1) in vec3 direction; +layout (location = 2) in vec4 color; layout (location = 0) out vec4 frag_color; @@ -25,7 +27,7 @@ warp_st (vec2 st, float time) { vec2 angle = st.ts * CYCLE / 2.0; vec2 phase = vec2 (time, time) * SPEED; - return st + (sin ((angle + phase) * FACTOR) + BIAS) / SCALE; + return st + turb_scale * (sin ((angle + phase) * FACTOR) + BIAS) / SCALE; } vec4 @@ -48,7 +50,8 @@ main (void) c = texture (Texture, t_st); e = texture (Texture, e_st); + float a = c.a * e.a * alpha; c += e; - c.a = alpha; - frag_color = c;//fogBlend (c); + c.a = a; + frag_color = c * color;//fogBlend (c); } diff --git a/libs/video/renderer/vulkan/shader/quakebsp.vert b/libs/video/renderer/vulkan/shader/quakebsp.vert index 7d1c4024e..4b379a06a 100644 --- a/libs/video/renderer/vulkan/shader/quakebsp.vert +++ b/libs/video/renderer/vulkan/shader/quakebsp.vert @@ -20,6 +20,7 @@ layout (location = 2) in uint entid; layout (location = 0) out vec4 tl_st; layout (location = 1) out vec3 direction; +layout (location = 2) out vec4 color; void main (void) @@ -28,4 +29,5 @@ main (void) gl_Position = Projection3d * (View * vec4 (vert, 1)); direction = (Sky * vertex).xyz; tl_st = tl_uv; + color = entities[entid].color; } diff --git a/libs/video/renderer/vulkan/vulkan_bsp.c b/libs/video/renderer/vulkan/vulkan_bsp.c index 070cb3874..a5beec50a 100644 --- a/libs/video/renderer/vulkan/vulkan_bsp.c +++ b/libs/video/renderer/vulkan/vulkan_bsp.c @@ -51,6 +51,7 @@ #include "QF/sys.h" #include "QF/va.h" +#include "QF/math/bitop.h" #include "QF/scene/entity.h" #include "QF/Vulkan/qf_bsp.h" @@ -79,6 +80,7 @@ typedef struct bsp_push_constants_s { quat_t fog; float time; float alpha; + float turb_scale; } bsp_push_constants_t; static const char * __attribute__((used)) bsp_pass_names[] = { @@ -604,6 +606,7 @@ R_DrawBrushModel (entity_t *e, bsp_pass_t *pass, vulkan_ctx_t *ctx) pass->ent_frame = e->animation.frame & 1; pass->inst_id = model->render_id; + pass->inst_id |= e->renderer.colormod[3] < 1 ? INST_ALPHA : 0; if (!pass->instances[model->render_id].entities.size) { bsp_model_t *m = &bctx->models[model->render_id]; bsp_face_t *face = &bctx->faces[m->first_face]; @@ -767,8 +770,11 @@ push_fragconst (bsp_push_constants_t *constants, VkPipelineLayout layout, { VK_SHADER_STAGE_FRAGMENT_BIT, field_offset (bsp_push_constants_t, alpha), sizeof (constants->alpha), &constants->alpha }, + { VK_SHADER_STAGE_FRAGMENT_BIT, + field_offset (bsp_push_constants_t, turb_scale), + sizeof (constants->turb_scale), &constants->turb_scale }, }; - QFV_PushConstants (device, cmd, layout, 3, push_constants); + QFV_PushConstants (device, cmd, layout, 4, push_constants); } static void @@ -956,6 +962,10 @@ queue_faces (bsp_pass_t *pass, bspctx_t *bctx, bspframe_t *bframe) __auto_type is = queue->a[j]; __auto_type f = bctx->faces[is.face]; + f.flags |= ((is.inst_id & INST_ALPHA) + >> (BITOP_LOG2(INST_ALPHA) + - BITOP_LOG2(SURF_DRAWALPHA))) & SURF_DRAWALPHA; + is.inst_id &= ~INST_ALPHA; if (pass->instances[is.inst_id].first_instance == -1) { uint32_t count = pass->instances[is.inst_id].entities.size; pass->instances[is.inst_id].first_instance = pass->entid_count; @@ -966,12 +976,15 @@ queue_faces (bsp_pass_t *pass, bspctx_t *bctx, bspframe_t *bframe) } int dq = 0; - if (bctx->faces[queue->a[0].face].flags & SURF_DRAWSKY) { + if (f.flags & SURF_DRAWSKY) { dq = 1; } - if (bctx->faces[queue->a[0].face].flags & SURF_DRAWTURB) { + if (f.flags & SURF_DRAWALPHA) { dq = 2; } + if (f.flags & SURF_DRAWTURB) { + dq = 3; + } size_t dq_size = pass->draw_queues[dq].size; bsp_draw_t *draw = &pass->draw_queues[dq].a[dq_size - 1]; @@ -1138,22 +1151,30 @@ Vulkan_DrawWaterSurfaces (qfv_renderframe_t *rFrame) bspctx_t *bctx = ctx->bsp_context; bspframe_t *bframe = &bctx->frames.a[ctx->curFrame]; - if (!bctx->main_pass.draw_queues[2].size) + if (!bctx->main_pass.draw_queues[3].size) return; turb_begin (rFrame); - bsp_push_constants_t frag_constants = { - .time = vr_data.realtime, - .alpha = r_wateralpha - }; - push_fragconst (&frag_constants, bctx->layout, device, - bframe->cmdSet.a[QFV_bspTurb]); VkPipelineLayout layout = bctx->layout; + bsp_push_constants_t frag_constants = { + .time = vr_data.realtime, + .alpha = 1, + .turb_scale = 0, + }; + push_fragconst (&frag_constants, layout, device, + bframe->cmdSet.a[QFV_bspTurb]); + __auto_type pass = &bctx->main_pass; pass->textures = &bctx->registered_textures; draw_queue (pass, 2, layout, device, bframe->cmdSet.a[QFV_bspTurb]); + frag_constants.alpha = r_wateralpha; + frag_constants.turb_scale = 1; + push_fragconst (&frag_constants, bctx->layout, device, + bframe->cmdSet.a[QFV_bspTurb]); + draw_queue (pass, 3, layout, device, bframe->cmdSet.a[QFV_bspTurb]); + turb_end (ctx); } @@ -1379,7 +1400,7 @@ Vulkan_Bsp_Init (vulkan_ctx_t *ctx) DARRAY_INIT (&bctx->registered_textures, 64); - bctx->main_pass.num_queues = 3;//solid, sky, water + bctx->main_pass.num_queues = 4;//solid, sky, water, transparent bctx->main_pass.draw_queues = malloc (bctx->main_pass.num_queues * sizeof (bsp_drawset_t)); for (int i = 0; i < bctx->main_pass.num_queues; i++) {