mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 06:10:56 +00:00
[vulkan] Implement BSP surface transparency
Surfaces marked with SURF_DRAWALPHA but not SURF_DRAWTURB are put in a separate queue for the water shader and run with a turb scale of 0. Also, entities with colormod alpha < 1 are marked to go in the same queue as SURF_DRAWALPHA surfaces (ie, no SURF_DRAWTURB unless the model's texture indicated such).
This commit is contained in:
parent
a936336e84
commit
3603f90718
9 changed files with 51 additions and 16 deletions
|
@ -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;
|
||||
|
|
|
@ -365,7 +365,7 @@
|
|||
{
|
||||
stageFlags = fragment;
|
||||
offset = 0;
|
||||
size = "4 * 4 + 4 + 4";
|
||||
size = "4 * 4 + 4 + 4 + 4";
|
||||
},
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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++) {
|
||||
|
|
Loading…
Reference in a new issue