[video output=day403 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Off-line Lighting and Per-vertex Reflectors" vod_platform=youtube id=m67dhh85fFQ annotator=Miblo]
[0:07][Introduce the new location, recap and set the stage for the day]
[1:58][Run the game and consider the current state of the block lighting]
[5:59][Blackboard: Multiresolution and Quality]
[16:45][Blackboard: Aggregating reflectors]
[18:52][Run the game and consider switching to rectangular reflectors]
[22:27][Blackboard: Figuring out a multiresolution raycasting scheme]
[29:25][Run the game and consider switching to an offline lighting solution, for experimentation purposes]
[30:50][handmade_render_group.cpp: Make LightingTest() cast out 64 and then 256 rays and run the game to demonstrate how unusable this is]
[32:32][handmade_render_group.cpp: Set up LightingTest() to compute the lighting offline]
[34:55][handmade_render_group.h: Introduce lighting_solution for LightingTest() to use]
[36:24][handmade_world_mode.cpp: Set up UpdateAndRenderWorld() to output the lighting on a key press]
[36:54][handmade_render_group.cpp: Split out some of LightingTest() into a new OutputLighting() function]
[49:37][handmade_world_mode.cpp: Make LightingTest() store the bitmaps when copying the lighting in]
[52:21][win32_handmade.cpp: Enable Win32ProcessPendingMessages() to handle the F-keys]
[56:28][handmade_world_mode.cpp: Enable UpdateAndRenderWorld() to toggle ShowLighting mode on a key press]
[59:07][Run the game, try toggling to ShowLighting mode and hit an assert in PushQuad()]
[1:00:51][handmade_render_group.cpp: Make OutputLighting() call GetCurrentQuads() up front]
[1:01:46][Run the game and toggle to ShowLighting mode]
[1:02:25][Infinite waters][quote 594]
[1:03:07][handmade_render_group.cpp: Make OutputLighting() loop through all the Elements, and LightingTest() write out the correct Bitmaps]
[1:04:21][Run the game and toggle to ShowLighting mode]
[1:04:41][win32_handmade.cpp: Make Win32ProcessPendingMessages() correctly clear the pressed key]
[1:05:56][Run the game, toggle to ShowLighting mode and consider the solution]
[1:08:50][handmade_render_group.cpp: Temporarily make ComputeLighting() set the lighting to full white, and run the game to confirm that we are correctly writing out the lighting]
[1:09:56][Get some water]
[1:10:38][Return with water]
[1:11:08][handmade_render_group.cpp: Make LightingTest() cast 8 rays, run the game and consider if we are accumulating and not averaging]
[1:12:42][handmade_render_group.cpp: Make LightingTest() correctly accumulate the rays]
[1:14:04][Run the game to see that our lighting solution is a lot better]
[1:15:25][handmade_render_group.cpp: Make OutputLighting() wind the vectors in the correct order]
[1:16:10][Run the game and consider using the quad structures themselves as reflectors]
[1:21:06][handmade_render_group.cpp: Make LightingTest() cast 256 rays, run the game and consider using the ray count as a divisor]
[1:23:06][handmade_render_group.cpp: Make LightingTest() factor in the ray count]
[1:23:57][Run the game to see a more stable lighting solution, in terms of its brightness]
[1:26:03][Run the game and consider smoothing out the lighting solution across reflectors]
[1:35:22][handmade_render_group.cpp: Split out LightingTest() into a new ExtractReflectorsFromQuads() function]
[1:38:46][handmade_render_group.cpp: Introduce ExtractReflectorsFromVerts()]
[1:43:44][Run the game and view just the reflectors]
[1:46:02][handmade_render_group.cpp: Make ExtractReflectorsFromVerts() correctly create the four vertices]
[1:46:32][Run the game to see our reflectors' vertices]
[1:48:12][Run the game and temporarily believe that it is correct]
[1:49:19][handmade_render_group.cpp: Consider making ExtractReflectorsFromVerts() position the vertices correctly]
[1:50:27][Blackboard: Evenly distributing reflectors across a face]
[1:51:24][handmade_render_group.cpp: Make ExtractReflectorsFromVerts() distribute the reflectors]
[1:53:46][Run the game and take a look at the fairly regularly tiled reflectors]
[1:54:19][handmade_render_group.cpp: Introduce OutputLightingQuads() and OutputLightingVerts()]
[1:59:20][Run the game and check out the lighting solution, now with vertex-based banding]
[2:00:52][Q&A][:speech]
[2:02:21][@Till_us][You can triangle order the verts for the banding issue?]
[2:02:43][Blackboard: Triangle vertex order picking]
[2:04:29][@Brian][Forgive me, but is the game currently running in the hardware renderer, or software?]
[2:04:44][@garryjohanson][So I had the idea of maintaining all geometry in a geometrically determined hash table, computing the trajectory of the reflections and looking up where the resulting geometry is. Is that something that would be workable, or am I missing something?]
[2:05:20][Blackboard: Using a geometrically determined hash table to compute the trajectory of reflections]
[2:13:36][@Brian][WeeChat works pretty well, if this is on Linux]
[2:14:26][@kriminator117][If you figure it out, tell Autodesk how to fix how MAYA's weight painting looks]
[2:15:21][@derpzerker][Would it be possible to write a transpiler so that we could take this C code and run it on the GPU trivially after debugging on CPU?]
[2:17:23][@chaoscom][In your lighting formulae, you use negative spans like "-0.25f*Span10". What if everything is supposed to be a displacement off Vertex0? Shouldn't you have "+0.75f" at some point instead of something negative?]
[2:18:15][@username_password_admin][You're using square, so why not filter bilinearly along the square axes rather than interpolating over the triangles? That should avoid the diagonal seams]
[2:19:01][Blackboard: Interpolating perpendicularly between the squares' edges]
[2:21:07][@chaoscom][Light doesn't behave linearily. That's why the banding occurs in the first place]
[2:22:12][Wrap it up][:speech]
[2:22:53]["It's not live now"][:speech][quote 595]
[/video]
