Fix shadow rendering for cockpits when raytracing is active - #7685
Open
The-E wants to merge 2 commits into
Open
Conversation
The-E
force-pushed
the
fix/vulkan-rt-cockpit-shadow-parity
branch
from
August 15, 2026 08:27
840954d to
0181d81
Compare
The raytraced shadow TLAS included only ships, asteroids, and debris. It now also includes the player's cockpit model and OBJ_RAW_POF / OBJ_PROP objects, matching the object set the rasterized shadow path already covers. The viewer's own hull was self-shadowing the cockpit as solid green. Each TLAS instance now carries a ray-cull mask, and the viewer hull gets a dedicated mask bit so shadow rays can exclude it outside the cockpit's own shading pass. The cockpit render pass uses a camera-relative view frame, not true world space, so a ray reconstructed from it needs a world-space correction before tracing against the TLAS. shadow_cascade_params_bind() now takes this offset (and a self-shadow flag) per bind, so the hull and cockpit draws inside ship_render_player_ship() can each supply their own. Also: - Extract ship_player_cockpit_model_would_render() and ship_cockpit_render_offset() so the render, shadow, and TLAS paths share one definition of "is the cockpit rendering" and "where is it". - Add shadow_cascade_params_bind_deferred() to remove the duplicated offset/count selection between the GL and Vulkan deferred-lighting backends. - Bind the shadow-cascade uniform buffer with a full replace instead of an offset-append: this buffer is now bound several times per frame with different content, and an offset-append only bump-allocates on its first call per frame on Vulkan's streaming buffer. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The cockpit model renders around the camera, inside the ship hull the scene pass already drew. OpenGL isolates the cockpit's depth from the scene's by swapping the depth attachment to a separate texture for the cockpit pass. The Vulkan backend left gr_post_process_save_zbuffer() and gr_post_process_restore_zbuffer() as no-ops, so the cockpit shared the scene's depth buffer and the hull incorrectly occluded it. A Vulkan framebuffer owns its attachments, so it cannot swap them like OpenGL does. Instead, VulkanPostProcessor::saveSceneDepth() copies the scene depth into a new backup image and the live depth buffer is cleared for the cockpit; restoreSceneDepth() copies the backup back so later passes that sample scene depth (for example lightshafts) see the scene, not the cockpit. VulkanRenderer::saveSceneDepth()/ restoreSceneDepth() end and resume the active render pass around each copy. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The-E
force-pushed
the
fix/vulkan-rt-cockpit-shadow-parity
branch
from
August 15, 2026 11:02
0181d81 to
580c076
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This branch fixes two problems with player cockpit rendering under Vulkan:
Fix 1: RT shadows on cockpits
The shadow acceleration structure (TLAS) did not include the cockpit model. It also
did not include
OBJ_RAW_POFandOBJ_PROPobjects. The shadow ray for the cockpitpass used the wrong ray origin. In combination, these problems meant that cockpits were
not receiving shadows.
Changes:
OBJ_RAW_POFandOBJ_PROPobjectstoo. This matches the object set that the rasterized shadow path already uses.
dedicated mask bit. Shadow rays exclude this bit outside the cockpit's own shading
pass, so the hull does not shadow itself.
ship_render_player_ship_casts_shadow_on_cockpit()still allows the hull to cast a shadow onto the cockpit during that pass.
a camera-relative frame, not true world space. The offset corrects the ray origin
before the shader traces the shadow ray.
shadow_cascade_params_bind()now takesthis offset as a parameter, so the hull draw and the cockpit draw can each supply
their own value.
shadow_cascade_params_bind_deferred(). This function removes duplicateoffset-selection code from the OpenGL and Vulkan deferred-lighting passes.
ship_cockpit_render_offset(). This function computes the cockpit's rotatedand swayed position in one place. The render path, the rasterized shadow path, and
the TLAS path all call this function. The three paths cannot drift apart.
Fix 2: cockpit depth in Vulkan
OpenGL swaps the depth buffer before it draws the cockpit. The swap keeps the ship
hull's depth values away from the cockpit draw. The Vulkan backend did not do this
swap. The hull's depth values stayed in the depth buffer, so the hull could block
the view of the cockpit.
Changes:
VulkanPostProcessor.saveSceneDepth(). This function copies the scene depth into the backup image,then clears the live depth buffer for the cockpit draw.
restoreSceneDepth(). This function copies the backup image back after thecockpit draw. Later passes that read scene depth, for example the lightshaft pass,
then read the correct scene depth.
Known gaps
can apply only one world-space offset per draw. This is correct for the common
case. It is not correct when
Cockpit_shares_coordinate_spaceis true, or when aship has no cockpit model. This case needs a per-pixel offset, or the offset must
move into the G-buffer data itself. This branch does not fix this case.
Eye_position. Therasterized path uses a cockpit-relative eye position instead. The TLAS walk skips
the detail-box check for the cockpit model, rather than compute the correct eye
position.
Testing
ninja codeandninja Freespace2build with no errors.