[video member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Raycasting AABBs Directly" vod_platform=youtube id=c4Q-6aMUh-k annotator=Miblo] [0:01][Recap and set the stage for the day][:speech] [0:53][:Run the game with the determination to raycast :lighting boxes directly][:rendering] [3:07][Move the Surface computations from LightingTest() into RayCast()][:lighting :rendering] [6:30][Replace HitSurface in AccumulateSample() and RayCast() with a lighting_box][:lighting :rendering] [16:10][:Run the game to see our slow :lighting solution, and determine to investigate the slowness][:rendering] [18:01][Add a TIMED_FUNCTION in RayCast()][:"debug system"] [18:22][:Run the game and consult the profiler to see that RayCast() is our most costly function][:lighting :performance :rendering] [19:48][Check the day[ref site="Handmade Hero" page="Annotated Episode Guide" url=https://hero.handmade.network/episode/code][ref site=YouTube page="Handmade Hero" url=https://www.youtube.com/user/handmadeheroarchive/videos]][:admin] [20:30][Raycasting Against AABB][:blackboard :geometry :lighting :optimisation :rendering] [24:14][Relieve RayCast() of testing RaySourceN for every surface][:lighting :optimisation :rendering] [29:17][:Run the game to see that we halved the cost of RayCast()][:lighting :optimisation :rendering] [29:56][Relieve RayCast() of using redundant data][:lighting :optimisation :rendering] [32:26][:Run the game to see that that didn't speed it up][:lighting :optimisation :rendering] [32:34][Make RayCast() perform inline the functionality of GetBoxSurface()][:lighting :optimisation :rendering] [34:25][:Run the game to see that that halved the cost of RayCast()][:lighting :optimisation :rendering] [35:00][Relieve RayCast() of performing redundant work originally necessitated by GetBoxSurface()][:lighting :optimisation :rendering] [38:52][:Run the game to see that the :lighting is busted][:optimisation :rendering][quote 609] [39:22][Reenable RayCast() to actually compute all the :lighting][:optimisation :rendering] [42:05][:Run the game to see that our :lighting is back][:optimisation :rendering] [42:38][Optimise the Normal value out of RayCast() and introduce a Sign value][:lighting :optimisation :rendering] [50:30][:Run the game to see that we're a little faster][:lighting :optimisation :rendering] [50:34][Optimise the SignX value out of RayCast()][:lighting :optimisation :rendering] [53:22][Optimise the HalfWidth and HalfHeight values out of RayCast()][:lighting :optimisation :rendering] [54:21][Optimise the Width and Height inner product computations out of RayCast()][:lighting :optimisation :rendering] [58:39][:Run the game to see that we are down below 60ms][:lighting :optimisation :rendering] [58:55][Change RelOrigin to be relative to the MinCorner in RayCast()][:lighting :optimisation :rendering] [1:03:16][:Run the game to see that the :lighting is different and investigate why][:optimisation :rendering] [1:04:39][Revert that RelOrigin change][:lighting :optimisation :rendering] [1:05:11][Determining the ray intersection point more efficiently][:blackboard :geometry :lighting :rendering] [1:06:53][Try again to make RayCast() use the HalfWidth and HalfHeight instead of Width and Height][:lighting :optimisation :rendering] [1:07:25][:Run the game to see that the :lighting is wrong again][:optimisation :rendering] [1:08:09][Make RayCast() correctly compute the Width and Height][:lighting :optimisation :rendering] [1:08:40][:Run the game to see that the :lighting remains correct][:optimisation :rendering] [1:08:43][Consider storing the Span and P in the Box][:lighting :optimisation :rendering :speech] [1:09:17][:Run the game to see that we are at ~52ms][:lighting :optimisation :rendering] [1:09:37][Toggle off the snake in PlayWorld()][:"entity system"] [1:09:54][:Run the game to see that we are at ~26ms][:lighting :optimisation :rendering] [1:10:07][Relieve RayCast() of doing an extra comparison of XCheck and YCheck with Width and Height respectively][:lighting :optimisation :rendering] [1:10:30][:Run the game to see that we are about the same][:lighting :optimisation :rendering] [1:10:46][Add P and Radius to lighting_box for RayCast(), GetBoxSurface() and PushCube() to use][:lighting :optimisation :rendering] [1:21:54][:Run the game to see black :lighting][:optimisation :rendering] [1:23:16][Step in to GetBoxSurface() and inspect its values][:lighting :optimisation :rendering :run] [1:25:34][Make PushCube() correctly set the P and Radius][:lighting :optimisation :rendering] [1:26:24][:Run the game to see that the :lighting is better][:lighting :optimisation :rendering] [1:27:13][Toggle back on the snake in PlayWorld()][:"entity system"] [1:27:24][:Run the game to see that we're at ~47ms][:lighting :optimisation :rendering] [1:28:43][Toggle off the TIMED_FUNCTION in RayCast()][:"debug system"] [1:28:52][:Run the game to see that we are below 40ms][:lighting :optimisation :rendering] [1:29:14][Try to unroll the Axis loop in RayCast()][:lighting :optimisation :rendering] [1:33:08][:Run the game to see that we are below 30ms][:lighting :optimisation :rendering] [1:33:50][Further compress the Axis "cases" in RayCast()][:lighting :optimisation :rendering] [1:37:28][:Run the game to see that we remain below 30ms][:lighting :optimisation :rendering] [1:37:38][Relieve RayCast() of multiplying the Sign in to RaySourceN and d][:lighting :optimisation :rendering] [1:38:53][:Run the game to see that we remain below 30ms][:lighting :optimisation :rendering] [1:39:21][Consider removing the Sign computation from RayCast()][:lighting :optimisation :rendering :speech] [1:41:13][Switch back to the looped version of RayCast() and relive that of multiplying the Sign in to the RaySourceN and d][:lighting :optimisation :rendering] [1:42:04][:Run the game] [1:42:16][Q&A][:speech] [1:43:32][@gprincip][Q: Is the :lighting done after this?][:rendering] [1:43:48][@Miblo][Q: You may now sort the episode guide entries from "new to old"[ref site="Handmade Hero" page="Annotated Episode Guide" url=https://hero.handmade.network/episode/code]] [1:44:12][@stuckpanda][Q: Which headers do you include for working with OpenGL?][:hardware] [1:44:31][@0lpbm][Q: How long until you'll move all of this to the GPU?][:hardware] [1:46:12][@praet_a51][Q: Why did inlining GetBoxSurface() in RayCast() result in such an improvement?][:optimisation] [1:47:54][@frostyninja][Q: Will the :lighting boxes remain sort of separate from the rest of the render commands flow?][:rendering] [1:48:09][@praet_a51][Q: Great stream by the way and the :lighting looks great][:rendering] [1:48:43][@filiadelski][Q: In my engine I have 3D models that contain a buffer of uint8 which is cast to a struct which contains OpenGL handles for the model. My instinct is to hide the OpenGL stuff from the game engine itself - is this a good idea or should I just give in to the OpenGL overlords and put #include in my game code? Maybe I'm just being dogmatic][:hardware] [1:50:14][@skyvaultgames][Q: When the Jai programming :language stabilizes, will you be considering using it for future handmade projects?] [1:50:52][@stuckpanda][Q: Is there an episode that explains some generalities about what OpenGL shaders are?[ref site="Handmade Hero" page="Compiling and Linking Shaders in OpenGL" url=https://hero.handmade.network/episode/code/day368/][ref site="Handmade Hero" page="Introduction to Vertex and Fragment Shaders" url=https://hero.handmade.network/episode/code/day369/]][:hardware] [1:51:54][Wrap it up][:speech] [/video]