From 19a5cb562cad49fa60e9cef0701746d780d063ca Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 3 Aug 2023 09:22:54 +0900 Subject: [PATCH] [vulkan] Avoid bsp back-face cull in shadow pass When rendering shadow maps, all the faces are needed, not just those facing the pseudo-camera (due to the null-point of the shadow pass view). --- libs/video/renderer/vulkan/rp_main_def.plist | 4 +-- libs/video/renderer/vulkan/vulkan_bsp.c | 29 ++++++++++++++++++-- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/libs/video/renderer/vulkan/rp_main_def.plist b/libs/video/renderer/vulkan/rp_main_def.plist index 2623a883e..e108eb3f2 100644 --- a/libs/video/renderer/vulkan/rp_main_def.plist +++ b/libs/video/renderer/vulkan/rp_main_def.plist @@ -1414,9 +1414,9 @@ renderpasses = { color = $color.bsp; tasks = ( { func = bsp_draw_queue; - params = (main, translucent, 2); }, + params = (main, translucent, 1); }, { func = bsp_draw_queue; - params = (main, turbulent, 2); }, + params = (main, turbulent, 1); }, ); stages = ( diff --git a/libs/video/renderer/vulkan/vulkan_bsp.c b/libs/video/renderer/vulkan/vulkan_bsp.c index 2ba3fa2a8..05b05fbeb 100644 --- a/libs/video/renderer/vulkan/vulkan_bsp.c +++ b/libs/video/renderer/vulkan/vulkan_bsp.c @@ -685,7 +685,7 @@ get_side (const bsp_pass_t *pass, const mnode_t *node) } static inline void -visit_node (bsp_pass_t *pass, const mnode_t *node, int side) +visit_node_bfcull (bsp_pass_t *pass, const mnode_t *node, int side) { bspctx_t *bctx = pass->bsp_context; int c; @@ -714,6 +714,27 @@ visit_node (bsp_pass_t *pass, const mnode_t *node, int side) } } +static inline void +visit_node_no_bfcull (bsp_pass_t *pass, const mnode_t *node, int side) +{ + bspctx_t *bctx = pass->bsp_context; + int c; + + // chain any visible surfaces on the node that face the camera. + // not all nodes have any surfaces to draw (purely a split plane) + if ((c = node->numsurfaces)) { + const bsp_face_t *face = bctx->faces + node->firstsurface; + const int *frame = pass->face_frames + node->firstsurface; + int vis_frame = pass->vis_frame; + for (; c; c--, face++, frame++) { + if (*frame != vis_frame) + continue; + + chain_surface (face, pass, bctx); + } + } +} + static inline int test_node (const bsp_pass_t *pass, int node_id) { @@ -725,7 +746,8 @@ test_node (const bsp_pass_t *pass, int node_id) } static void -R_VisitWorldNodes (bsp_pass_t *pass, vulkan_ctx_t *ctx) +R_VisitWorldNodes (bsp_pass_t *pass, vulkan_ctx_t *ctx, + void (*visit_node) (bsp_pass_t *, const mnode_t *, int)) { const mod_brush_t *brush = pass->brush; typedef struct { @@ -1259,7 +1281,8 @@ bsp_visit_world (const exprval_t **params, exprval_t *result, exprctx_t *ectx) if (pass->instances) { DARRAY_APPEND (&pass->instances[world_id].entities, world_id); } - R_VisitWorldNodes (pass, ctx); + auto visit_node = pass_ind ? visit_node_no_bfcull : visit_node_bfcull; + R_VisitWorldNodes (pass, ctx, visit_node); if (r_drawentities) { auto queue = pass->entqueue;