-
Notifications
You must be signed in to change notification settings - Fork 45
New lighting engine #137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
New lighting engine #137
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One overall comment: Because of how much slower point lights are than directional lights in both EX3 and EX2, and because real point lights require the scene to be triangulated a bit more in order to look good (won't always look good in vanilla scenes with gigantic tris), I think it should be a config option for whether the user wants fake or real point lights.
Generally I think this is cool and I'm looking forward to trying it.
include/ultra64/gbi.h
Outdated
| Light_t l; | ||
| Light_t l; | ||
| #ifdef F3DEX_GBI_PL | ||
| PosLight_t p; | ||
| #endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally I think one of the two existing community F3DEX2 gbi.h's which support point lights should be brought in, instead of making a new GBI implementation of point lights.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you can share these existing community gbi.h implementations I can look at what they do, but my predisposition is that I'm not especially interested in using an old implementation when this implementation is already correct and does what we want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the community's pos light GBI for use with the SGI original GBI: https://github.com/HackerN64/HackerSM64/blob/master/include/n64/PR/gbi-poslight.h This is what I based the F3DEX3 pos light GBI on.
This is the community's reverse-engineered (non SGI) implementation: https://github.com/z64tools/z64hdr/blob/main/include/ultra64/gbi.h
Out of curiosity, I checked what the MM decomp uses (I don't think this existed when F3DEX3 was being started): https://github.com/zeldaret/mm/blob/main/include/PR/gbi.h They do have the union of the light type and the point light type called Light, but they also have the point light type named PointLight_t instead of PosLight_t.
If you think there is a good reason to switch away from the first community implementation already in use (for example, easier use of F3DEX3 in MM in the future), I'm open to it, but we should switch to some other standard community implementation, not make something up just for this repo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That first header in HackerSM64 is very suspicious. This comment /* version 990705 */ suggests to me that this is probably a leaked header being appropriated as a community header. I personally have no wish to import this into HackerOoT.
The z64hdr gbi is glank's gbi with an added structure. The new geometry mode is altogether missing and the LightPos_t structure has poor field names. This implementation is simply not up to standard.
Of these choices, MM decomp's is far and away the best choice but it's still not as complete as this PR's. I'd rather upstream changes to MM's gbi.h than adopt any of these.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To recap on where we're at since this was last discussed: gbi.h has had changes in upstream decomp to incorporate the necessary definitions and structures for pointlighting, and F3DEX3's gbi.h has since had a PR merged that brings it into agreement with decomp. So I think this is resolved.
|
this PR still have changes to address, also iirc I wasn't able to build it bur idr exactly |
bump |
Reonu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
Merged the new version of the PR to my repo and I'm still getting broken point lighting (on EX3). Not sure what's up. 2025-11-22.12-34-51.mp4 |
|
fwiw it's also doing similar things for me, not sure if it's something I messed up with the merge or if it's a decomp change that I don't know about 8mb.video-mcy-k4EG82QL.mp4 |
* Merge remote-tracking branch 'upstream/main' into lighting * Set ENABLE_POINT_LIGHTS for F3DEX3 point lights
…es lower than 8 are not valid
|
Updated this The issues above were due to more recent F3DEX3 versions requiring a new flag to enable point lighting. |
|
thanks! I marked some conversations as resolved, only the obvious ones and the one that are outdated by upstream decomp changes (like the comments about I'll have to try it again to see how it goes in-game but as far as I'm concerned this is good to go (I'll just wait on sauraen's input since there's unresolved conversations, I think) |
Reonu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
after the latest fix, I can confirm that it does work perfectly fine, at least in F3DEX3 mode
| LightsBuffer sLightsBuffer; | ||
| // Obtain the 5 most significant bits of the 23-bit mantissa, | ||
| // round to nearest | ||
| mantissa = (mantissa + 63) >> (23 - 5); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
63 is not correct here, I think you want ((1 << (23 - 5)) - 1)
| * - d is the distance from the light position to the vertex | ||
| * | ||
| * In this implementation we let kc = 8 always, this is the smallest allowed value as overflows will occur for kc < 8 | ||
| * where the ucode would compute a reciprocal > 1.0. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is true for F3DEX3? But it's been quite a while since I rewrote the point lights implementation.
|
|
||
| // Select bind functions | ||
| const LightsBindFunc* bindFuncs; | ||
| if (ENABLE_F3DEX3 || realPointLights) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My main review comment from a year ago was that we should not force enable point lights just cause someone is using F3DEX3, it should be optional cause they're significantly slower. Certainly for the whole game, ideally per object. Even better would seamlessly change between using a point light and a directional light for an object based on its distance and size. It looks like none of this has been implemented and F3DEX3 will always use point lights?
| // F3DEX3 lights assignments look like (from most to least recently appended) | ||
| // gsMoveMem(...) | ||
| // gsSPNumLights(...) | ||
| #define GBI_IS_LIGHTS(gW0) \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is needlessly clever and you should just write the two functions out straight, but I won't block the PR on this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's an issue right now where the game will crash if an actor that emits a light is deleted after the metal hit effect (which also emits a light) is activated.
Here are some instructions in order to reproduce this crash easily:
Add this to EnArrow_Init:
Lights_PointGlowSetInfo(&this->lightInfoGlow, thisx->world.pos.x, thisx->world.pos.y, thisx->world.pos.z, 255, 255,
255, 1000);
this->lightNodeGlow = LightContext_InsertLight(play, &play->lightCtx, &this->lightInfoGlow);
Add this to EnArrow_Destroy:
LightContext_RemoveLight(play, &play->lightCtx, this->lightNodeGlow);
Add an include for light.h in z_en_arrow.h and add this to the arrow struct:
LightInfo lightInfoGlow;
LightNode* lightNodeGlow;
Then go to a scene with an iron knuckle (example: scene 84 - Iron Knuckle's Lair) and shoot the iron knuckle a few times. The game will crash.
The crash is a NULL pointer dereference in Lights_BindAndDraw. Specifically it crashes on this because of lightNode->info being NULL:
// Populate this lights group
FOR_EACH_LIGHTNODE(lightNode, play->lightCtx.listHead) {
LightInfo* info = lightNode->info;
bindFuncs[info->type](lights, &info->params, distances, objPos);
}
Just leaving this info here so that the issue is documented and tharo or somebody else can take a look at some point
EDIT: This is on F3DEX3. Unsure if it happens on other microcodes.
…dd NULL check for the info field of LightContext_InsertLight, Fix linked list removal
Reonu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new commits have fixed the crashing issues! Now it works perfectly
|
alright so I reran CI to make sure it wasn't just my PR that was failing for no reasons, it passed before on the last commit so you can ignore the error here |


Features
Lights_Pop()can delete the queued lighting commands to avoid loading them.Since F3DEX3 requires no additional cooperation from geometry drawn with point lights, F3DEX3 can always use point lights. For F3DEX2, a new room behavior field has been added that determines whether the room geometry is compatible with point lights. For actors, I've added a new actor flag which communicates that the geometry drawn by the actor is point-lighting compatible. At least the room behavior change will need fast64 integration.
This lighting engine is based on a lighting engine rewrite featured in the Team Dampé's Hut Escape Room competition submission (https://github.com/Dampes-Hut/escaperoom), as well as a couple of other projects in various forms. Special thanks to @Dragorn421 for contributions to that lighting engine that made it in here as well.