Conversation
The-E
force-pushed
the
fix/vulkan-rt-cockpit-shadow-parity
branch
2 times, most recently
from
August 15, 2026 11:02
0181d81 to
580c076
Compare
BMagnu
reviewed
Sep 11, 2026
Comment on lines
+1101
to
+1102
| vec3d world_offset = (Lighting_mode == lighting_mode::COCKPIT && Viewer_obj != nullptr) ? Viewer_obj->pos : vmd_zero_vector; | ||
| bool allow_viewer_self_shadow = Lighting_mode == lighting_mode::COCKPIT && ship_render_player_ship_casts_shadow_on_cockpit(); |
Member
There was a problem hiding this comment.
Have you tested this beyond 10km away from mission origin?
That looks suspiciously like the pattern that will start noticeably and badly vibrating once you reach roughly that far, which is why mapped shadows refuse to render anything for cockpit shadows non-zero offset (you can notice for non-cockpit shadows as well, but only once you're 20, 30km out or you look closely, but it's not as disturbing due to the lower precision patterns that are shaded).
- Introduced `shadow_ray_params` to simplify ray origin and cull mask management. - Shifted shadow ray origins to TLAS-relative space for improved precision and consistency, especially for cockpit rendering. - Refactored cascade bind functions, adding `shadow_cascade_params_bind_deferred()` for consolidated offset/count handling in deferred lighting. - Expanded TLAS to include cockpits and additional object types, ensuring parity with rasterized shadows. - Introduced per-instance cull masks to address cockpit self-shadowing issues. - Improved Vulkan depth isolation for cockpit rendering via backup/restore mechanism, ensuring correct depth sampling in later passes. - Extracted reusable helper functions for cockpit rendering state logic.
The-E
force-pushed
the
fix/vulkan-rt-cockpit-shadow-parity
branch
from
September 19, 2026 14:42
580c076 to
3555180
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 three 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. Together, these problems meant that cockpits did not
receive shadows.
Changes:
gatherCockpitShadowCasterInstance()). AddOBJ_RAW_POFandOBJ_PROPobjects too. This matches the object set that the rasterizedshadow path already uses. The gate is the new
shadows_cockpit_casts_shadow(), which both paths share.TLAS_MASK_*inshadows.h). Tag the viewer'sown ship hull with
TLAS_MASK_VIEWER_HULL. Shadow rays exclude this bit outside thecockpit pass, so the hull does not shadow itself. During the cockpit pass,
ship_render_player_ship_casts_shadow_on_cockpit()still lets the hull cast a shadow onto the cockpit.shadow_ray_view_originandshadow_ray_cull_maskto the shadow uniform block(
shadow_cascade_static_data, std140, 96 bytes, checked by astatic_assert). Thecockpit pass renders in a camera-relative frame, so the shader cannot rebuild the ray
origin from
inv_view_matrixalone. The shader now usesmat3(inv_view) * viewPos + shadow_ray_view_origin.shadow_ray_params.shadow_cascade_params_bind()takes it, so the hull draw and thecockpit draw in
ship_render_player_ship()each bind their own ray origin and cull mask.The old two-argument overload stays for ordinary passes.
shadow_cascade_params_bind_deferred(). This function removes duplicatecascade-selection code from the OpenGL and Vulkan deferred-lighting passes.
ship_cockpit_render_offset(). This function computes the cockpit's rotatedand swayed offset in one place. The render path, the rasterized shadow path, and
the TLAS path all call it, so the three paths cannot drift apart.
gr_update_buffer_data()call. The bindnow runs several times each frame with different content. The Vulkan streaming buffer
bump-allocates fresh memory only for a full update, so the partial update overwrote data that was still in use.
Fix 2: TLAS-relative coordinates
Float32 has about 1 mm steps at 10 km and about 8 mm at 100 km. Cockpit-scale RT shadows
shimmered far from the mission origin.
-Shadow_rt_tlas_origin. The TLAS build sets thisorigin to
Eye_positiononce each frame.shadow_rt_relative()converts a world position.shadow_ray_view_originfrom exact differences, so the shader neveradds two large numbers.
Fix 3: 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 nothing in
vulkan_post_process_save_zbuffer()andvulkan_post_process_restore_zbuffer(), sothe hull could block the view of the cockpit.
VulkanPostProcessor.saveSceneDepth(). It copies the scene depth into the backup image. The savefunction then clears the live depth buffer for the cockpit draw, as OpenGL does.
restoreSceneDepth(). It copies the backup image back after the cockpit draw, solater passes that read scene depth (for example lightshafts) see the scene depth.
VulkanRendererintoendScenePassForDepthCopy()andresumeScenePassAfterDepthCopy(). The new save and restore code shares them.With MSAA, only the scene depth image is parked. The G-buffer pass clears the multisampled
depth, and the MSAA resolve writes back into the scene depth before the restore.
Known gaps
can apply only one ray origin 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.
a cockpit-relative eye position. The TLAS walk does not compute this position.
Testing
ninja codeandninja Freespace2build with no errors.