Skip to content

Enable light blocking by player weapon#714

Open
joshuarwood wants to merge 8 commits intofgsfdsfgs:portfrom
joshuarwood:weapon_light_fix_clean
Open

Enable light blocking by player weapon#714
joshuarwood wants to merge 8 commits intofgsfdsfgs:portfrom
joshuarwood:weapon_light_fix_clean

Conversation

@joshuarwood
Copy link
Copy Markdown

This PR implements a software test to account for when the player weapon blocks light artifacts on screen. It is intended to be an efficient re-implementation of the old zbuffer test on original hardware. It takes around 2e-5 to 7e-5 seconds to complete on my Ryzen 8840HS cpu with no notable impact up to a 240 FPS cap.

Screenshot_20260407_195131 Screenshot_20260407_195201

Details

The software test checks whether a ray drawn from the camera location to the screen position of a light artifact intersects a triangle in the player weapon + hand model. It is done in the camera coordinate system with all locations relative to the camera.

Visibility is determined by converting the z distance of the triangle intersection to an N64 depth integer rather than a straight distance comparison to account for the weapon draw loop using different znear/zfar (1.5/1000) compared to the background draw loop (15/10000). This is needed to replicate light bleed through the weapon geometry at close distances on original hardware. The lights in the Carrington test range are a good example of this. The first light should be visible through the Falcon muzzle but not the handle when comparing against ParaLLEl RDP emulation (a proxy for original hardware):

This PR
Screenshot_20260407_234727
Screenshot_20260407_234749

ParaLLEl RDP
Screenshot_20260407_234940
Screenshot_20260407_234959

The weapon/hand model intersection test is implemented in bgTestHitOnWeapon() inside bg.c. It is closely based on bgTestHitOnChr() with 3 notable changes:

  1. A bug fix for ptr being advanced ahead of the loop that constructs min/max bbox values from the model vertices. This bug results in memory overflow by 1 iteration, producing incorrect bbox bounds.
  2. Added a bounds pointer that returns a bbox boundary from the full model geometry. This is useful for culling extra calculations using a simple bounding box test in cases where many lights are on screen. It needs to be done manually since, as far as I can tell, the weapon models don't have bbox model nodes.
  3. Uses bgTestLineIntersectsTriangle() for the triangle intersection test instead of func0002f560(). In theory, both are implementations of the Moller-Trumbore intersection test, but func0002f560() seems to take a shortcut or has resolution issues that result in occasional light flicker through the weapon. func0002f560() might be optimized to only work for directions (0, 0, -1) since that is the direction used when applying bgTestHitOnChr() to character models.

Example of light flicker through weapon with func0002f560() intersection calculation:
Screenshot_20260407_200057

Light artifact visibility is updated just before weapon matrix information gets wiped at the end of the weapon render loop.

Performance Testing

I did some performance tests at a few locations. There was no notable impact up to a 240 FPS cap on my Ryzen 8840HS.

location Average Execution time (per visible hand) Screenshot
carrington 1.19e-05 sec Screenshot_20260408_092113
defection hall 6.59e-05 sec Screenshot_20260407_194832
defection roof covered 2.14e-05 sec Screenshot_20260407_195201
defection roof visible 1.32e-05 sec Screenshot_20260407_195131

Additional Exxamples

Left hand blocking light:
Screenshot_20260408_083632

@joshuarwood
Copy link
Copy Markdown
Author

Oh, I forgot to upload the example of cloaking behavior. It's similar to N64 where the lights become visible whenever the cloak is active or fading. Here is a video of cloak behavior from this PR:

Screencast_20260407_202948.webm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant