I recommend you read it to best understand this post.
In the following several hours, I have worked on optimization and updating the system by which the lighting was calculated. It now runs in real-time, at 60 FPS in my current test scene. The performance is extremely dependent on the size of the scene, but the scene in this test game–a similar size to Elttob’s example place–performs significantly better and achieves what is effectively the same thing.
Here is the test place: https://www.roblox.com/games/9996248227/Real-Time-Global-Illumination Note: There is one major issue, it’s very “noisy”, as in the colors kind offlickerwhich can be annoying, I’ve attempted to use Tweening and larger buffers to cover this up but it doesn’t seem to work enough.
Let me know how performance is on your devices. I’m very curious, as I have a solid 60 FPS when I test it in Studio.
I’m getting a solid 105~115 FPS using an unlocker on 2K resolution, which is phenomenal. Considering the engine’s scale seems to cap off after a certain spec point, I wonder how this would perform on average device or toaster device such as a phone. One thing I’ve noticed testing my own GI system in studio is even when I have the lights not do any updates, they still lag as if there was rays still firing.
I’ve been trying to tinker with methods to not update them unless a part in their range changes position, rotation, or size, but to no luck. For the noisy stuff I’ve got an array of 10 colors values that will shift in the sample color every update and averages it out when updating point lights. I’ve also implemented a very primitive support method for transparent parts which will change the reflection’s color depending on the parts color.
Adding support for point lights is probably going to be the toughest thing. I don’t know if I should ray out on a fixed set of vectors for all 6 direction faces, or randomize it, etc. Overall, I’m excited for future lighting potential this provides.
A few things about performance: do as little math as is possible. You can as much as half by just adding one extra math operation per ray, or per probe. The other thing I’d say is make sure you only update the rays as much as is necesssry, and only use as many rays as necessary. And again in regards to math, cut down on any form of arithmetic, especially in loops. I found with the buffer to only multiply the prior color value by the length of the buffer, and then calculate the average from there. That is in contrast to holding a table of Color values which are averaged together every time a probes color is to be updated. I also found that increasing the size of the buffer, and decreasing the number of rays cast per update significantly improved performance, while not losing out on my quality. I also only update probe color once per second in the test game, which helps greatly. Once per frame is unnecessary. Doing this also leaves time for each probe to take its time calculating. This leads into the final tip: disperse the load. Have each probe shoot out a ray with as much time between as is possible. (Something like task.wait(updateTime/rayCount) between each raycast in a probe.`
PS: If you aren’t already, take advantage of Parallel Lua.
Switching to a multiplied average method helped greatly with the color averaging. But when Elttob mentions 60 rays (per probe?) a second in his video that seems incredibly hard to believe unless it’s for probes close to the player. Would love to be able to eventually do lights that aren’t the sun as GI sources too, but holy dooly that would be intense math.
This is more of a feedback report.
50-70 FPS. Not bad! But judging by the delay from the rocket launcher I’d imagine the server isn’t taking this too well.
I do like the lighting. The probing seems more stable than recording studio in a low bitrate. Would I use this in my game? No, I would use Future lighting as-is, it seems good enough and somewhat does this already.
In his video, Elttob mentions (at least I thought) 60 rays per frame, which is insane. My method is is doing ~32 rays per second per probe. Also, Roblox light’s may not work as GI sources, but emissive materials would. It would simply be an extra check of the material of the object hit, if it’s an emissive material, the brightness factor would be increased when calculating.
When testing in Studio, where the server is run locally, performance is great on the server and the client. However, when playing the published game I see what you mean. That is simply a limitation of the Roblox servers. I would love to make it run locally, but as of right now there seems to be an issue with Parallel Lua on the client with local scripts (or at least I can’t figure it out).
I also wouldn’t use this in a game, Real-Time GI is not practically useful at it’s current performance. However, the baked GI I (and many others) have made would be a very nice touch for a showcase. Many artists on Roblox make their own lighting in showcases, but baked GI could be a good method of getting realistic-looking lighting quickly.
Tested on a 2018 iPad Pro on highest graphics and the performance is solid 60 frames even with the rocket launcher breaking stuff! Performance is clean