[video output=day572 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Scrolling the Lighting Voxel" vod_platform=youtube id=YJI3cZGZ3eA annotator=Miblo]
[0:02][Recap and set the stage for the day][:speech]
[1:19][Demo the current state of our :lighting solution][:run]
[3:27][Switch to the test sphere path in EndLightingComputation()][:lighting]
[5:23][Demo our test light-field interpolation][:lighting :run]
[6:19][Disable trilinear blending in OpenGLInit()][:hardware :lighting :rendering]
[7:13][Demo the coarseness of our :lighting storage resolution][:run]
[7:36][Re-enable trilinear blending in OpenGLInit()][:hardware :lighting :rendering]
[7:54][Demo our beguilingly smooth test light-field interpolation][:lighting :run]
[8:44][Switch to the test transfer path in EndLightingComputation()][:lighting]
[8:51][Briefly demo our ray casting to the closest light source][:lighting :run]
[9:13][Describe TestCastFromProbes()][:geometry :lighting :research]
[10:30][Make TestCastFromProbes() only use the light above the hero's head, to aid testing][:lighting]
[10:51][Demo the ray casting to our single light source, considering blending of light sources and secondary bounces][:lighting :run]
[15:22][Embark on delayed light blending, first preventing TestCastFromProbes() from clearing the voxel of :lighting information]
[15:50][See that our light stops getting updated in areas we leave][:lighting :run]
[16:38][Make TestCastFromProbes() and SpamVoxelSlice() decay and accumulate light across frames, augmenting lighting_solution with IrrBlendU and IrrBlendV][:lighting]
[21:38][Check out our delayed, but over-bright :lighting][:run]
[22:16][On the need to weight our light accumulation to prevent over-brightness][:lighting]
[24:26][Introduce light_computation_cell for lighting_solution to contain as NewCells, augmenting light_voxel_cell with TotalWeight, LightCAccumulator and LightNAccumulator][:"data structure" :lighting]
[26:24][Make TestCastFromProbes() stably accumulate, blend and clear our :lighting across frames, and SpamVoxelSlice() preserve the weighting][:lighting]
[31:13][Check out our lagged and not over-bright light blending][:lighting :run]
[32:18][Let TestCastFromProbes() ray cast from the entire spatial hierarchy][:lighting]
[32:33][Check out our (incorrect) blending of multiple light sources, noting that our :lighting voxel is not pinned to the world][:lighting :run]
[35:10][Reacquaint ourselves with BeginLightingComputation()][:lighting :research]
[35:39][Check out our two :lighting voxel bounds][:"debug visualisation" :run]
[37:08][Scrolling the Lighting Voxel: Aligning and pinning it to the world][:lighting :research]
[40:06][Enable the checkerboard path in EndLightingComputation(), and disable trilinear filtering in OpenGLInit()][:hardware :lighting :rendering]
[40:50][Check out the varying alignment of our light voxel in the world][:lighting :run]
[42:39][Make BeginLightingComputation() align our light voxel in the world][:lighting]
[44:52][Check out our consistently aligned light voxel in the world][:lighting :run]
[45:23][Spot some possible X-fighting or a voxel edge :sampling bug][:lighting :run]
[46:17][Distinguish between voxel–world alignment and placement consistency][:lighting :run]
[47:38][Switch to the test transfer path in EndLightingComputation()][:lighting]
[48:19][Check out the light transfer with inconsistent voxel placement][:lighting :run]
[48:51][Make BeginLightingComputation() identify the need to maintain consistent voxel placement across frames, augmenting lighting_solution with LastOriginP and introducing a v3s version of Hadamard()][:"data structure" :lighting]
[57:51][Check out the non-copied, but ready :lighting][:run]
[58:20][Break in to BeginLightingComputation() and inspect our voxel placement preservation values][:lighting :run]
[1:00:24][Begin to make BeginLightingComputation() consistently position light voxel data in Y across frames][:lighting]
[1:03:06][Voxel Scrolling][:blackboard :lighting]
[1:07:41][Make BeginLightingComputation() consistently position light voxel data in Y][:lighting]
[1:14:40][Hit an access violation in BeginLightingComputation()][:lighting :run]
[1:14:58][Fix typo in BeginLightingComputation()][:lighting]
[1:16:14][Hello, [@Molly puss]!][:speech]
[1:17:10][Find that our voxel copy did not work correctly][:lighting :run]
[1:18:21][Fix two more typos in BeginLightingComputation()][:lighting]
[1:19:55][Hit an access violation in BeginLightingComputation()][:lighting :run]
[1:20:15][Unfix typo in BeginLightingComputation()][:lighting]
[1:20:46][Admire our stable downward copy, but broken upward copy][:lighting :run]
[1:21:10][Toggle off the upward copy in BeginLightingComputation()][:lighting]
[1:21:30][Check out the supposed downward copy][:lighting :run]
[1:21:48][Toggle off the downward copy in BeginLightingComputation()][:lighting]
[1:22:01][Find that the downward lighting does not go to black][:lighting :run]
[1:22:37][Toggle on the downward copy in BeginLightingComputation()][:lighting]
[1:22:49][Consider the downward copy to be continuous][:lighting :run]
[1:23:04][Fix the upward copy in BeginLightingComputation()][:lighting]
[1:27:55][Admire our light, stably copied in Y][:lighting :run]
[1:28:37][Begin to compress the voxel copying routine in BeginLightingComputation()][:lighting]
[1:29:25][Find that nothing changed][:lighting :run]
[1:29:34][Continue to compress the voxel copying routine in BeginLightingComputation()][:lighting]
[1:32:57][Find that that doesn't work at all][:lighting :run]
[1:33:04][Fix the upward clearing loop in BeginLightingComputation()][:lighting]
[1:33:16][Find that it's working][:lighting :run]
[1:33:25][Complete the compression of our voxel copying routine in BeginLightingComputation()][:lighting]
[1:35:28][Hit an access violation in BeginLightingComputation()][:lighting :run]
[1:35:42][Fix the voxel copying routine in BeginLightingComputation() to set the InitialY anew each time through][:lighting]
[1:36:04][Find that nothing changed][:lighting :run]
[1:36:21][Make BeginLightingComputation() consistently position light voxel data in X and Z][:lighting]
[1:41:18][Find that the voxel placement is not consistent in X][:lighting :run]
[1:41:34][Fix the voxel copying in X and Z][:lighting]
[1:42:08][Admire our consistently placed voxel][:lighting :run]
[1:42:42][Introduce BlockCopyVoxel(), and try writing it more and more succinctly][:lighting]
[1:50:21][Q&A][:speech]
[1:51:11][Re-enable trilinear blending in OpenGLInit()][:hardware :lighting :rendering]
[1:51:26][Admire our blended and consistently placed light voxel][:lighting :run]
[1:53:48][@roam00010011][Q: handmadehero.org[ref
    site="Handmade Hero"
    url=https://handmadehero.org/] time did not reflect the correct start time. What happened?]
[1:54:58][@ccaxothor][Q: I'm really early in the episodes, only just finished 10. Reviewing where you are at now, what are some libraries that are added so I can study before I get to the episode they are added, i.e. OpenGL or something along those lines?][:library]
[1:56:22][@aidsjorb][Q: Care to give a guess completion percentage on the "final" :lighting solution?]
[1:58:35][@synchronizerman][Q: I'm exploring spatial grids for :collision detection and am finding it challenging to reason about how to handle collision responses. Do you have any tips for using that sort of data structure as opposed to the usual trees (kd, quad, oct, etc.)?]
[2:00:29][@synchronizerman][Q: Don't you normally need to put colliders inside the grid and somehow map those to entities, or perhaps enqueue into a procedure that handles the collisions? I guess more precisely, what is the pipeline for using the grids in the first place?][:collision]
[2:01:32][@ccaxothor][Q: What episode do you talk about the blending problem you are facing? Not sure what you mean. Like color blending or some numerical blending?][:lighting]
[2:04:09][Wrap it up][:speech]
[/video]
