[video output=day646 member=cmuratori stream_platform=twitch stream_username=handmade_hero  project=code title="Removing Z from Lighting" vod_platform=youtube id=B22gfqVJo3w annotator=Miblo]
[0:00][Welcome to the stream, with admiration of our :lighting][:run]
[0:52][Consider :lighting improvements, e.g. speeding up our long-term average blend][:run]
[1:38][70% frame time on ComputeLightPropagationWork][:lighting :performance :run]
[2:50][Moving to 2D :lighting][:performance :run]
[3:01][Moving to 2D :lighting: 1) Eliminating Z-stacking][:memory :performance :run]
[3:17][Reducing the :lighting voxel :memory footprint][:memory :performance :research]
[7:00][Decrease LIGHT_LOOKUP_VOXEL_DIM_Z from 16 to 1][:lighting]
[7:21][Check the ramifications of removing Z from the :lighting][:research]
[14:51][Toggle on :lighting voxel drawing in PushLightingRenderValues()][:"debug visualisation"]
[16:01][Our world is completely black][:lighting :run]
[16:29][Increase LIGHT_LOOKUP_VOXEL_DIM_Z from 1 to 8][:lighting]
[16:34][Our world is lit][:lighting :run]
[16:46][Decrease LIGHT_LOOKUP_VOXEL_DIM_Z from 8 to 4][:lighting]
[16:54][Our world remains lit][:lighting :run]
[16:57][Decrease LIGHT_LOOKUP_VOXEL_DIM_Z from 4 to 2][:lighting]
[17:09][Our world remains lit][:lighting :run]
[17:14][Decrease LIGHT_LOOKUP_VOXEL_DIM_Z from 2 to 1][:lighting]
[17:22][Is the voxel too thin to pick up light sources?][:lighting :run]
[17:43][Increase LIGHT_LOOKUP_VOXEL_DIM_Z from 1 to 2][:lighting]
[17:52][Consider keeping the :lighting voxel 2-high, with vertical movement sampling fixed][:run]
[19:14][Plan our Z-elimination strategy][:lighting :research]
[21:49][Try making UpdateLighting() zero out all the incoming Z-values][:lighting]
[22:36][Our :lighting bounds are relatively too low, but tall enough][:run]
[24:03][Check the call stack of UpdateLighting() for sources of Z][:lighting :research]
[25:19][Prevent UpdateLighting() from zeroing out all the incoming Z-values][:lighting]
[25:26][Check where to clamp Z][:lighting :research]
[27:50][Toggle on WorldCameraRect drawing in UpdateAndRenderWorld()][:camera :"debug visualisation"]
[28:06][Check out our :camera and :lighting volumes][:"debug visualisation" :run]
[29:19][Make UpdateAndRenderWorld() draw a -1 to 1 origin cube][:"debug visualisation"]
[30:05][Check out our -1 to 1 origin cube][:"debug visualisation" :run]
[31:15][Determine to lock the simulation center Z][:research]
[33:05][Try making UpdateCameraForEntityMovement() set SimulationCenter.Z to 0]
[33:29][The game looks good][:run]
[33:40][Consider drawing the simulation region][:"debug visualisation" :research]
[34:09][The simulation region does not follow us downstairs][:"debug visualisation" :run]
[35:03][Make UpdateAndRenderWorld() zero out the LightingCenter.ChunkZ and LightingCenter.Offset_.z][:lighting]
[36:15][The :camera bounds wobble][:run]
[37:44][Assert in UpdateLighting() that Z is 0][:lighting]
[38:54][Never hit our assertions in UpdateLighting()][:lighting :run]
[39:27][Consider making Z == 0 the lowest point in the world][:lighting :run]
[40:49][Consider Z simplifications][:lighting :research]
[42:30][Reacquaint ourselves with the alignment code in UpdateLighting][:lighting :research]
[43:45][Determine to keep Z == 0 at the center point][:lighting :research]
[45:57][Make GetTotalVolume() offset the MinP negatively by half a tile]
[48:18][Our world is lit again][:lighting :run]
[50:16][Make GetTotalVolume() zero out the MinP.Z]
[51:12][Our world looks fine, but the :lighting and :camera are offset][:run]
[51:39][Investigate why the :camera is incorrectly positioned][:research]
[54:27][Make UpdateAndRenderWorld() set FocusZ to 0][:camera]
[54:46][Our :camera remains incorrectly positioned][:run]
[55:05][Reacquaint ourselves with FocusZ relativity][:camera :research]
[56:37][Simplify the FocusZ values in game_camera down to ExpectedFocusZ][:camera :"data structure"]
[1:01:50][Make UpdateAndRenderWorld() compute ExpectedFocusZ][:camera]
[1:09:18][Our :camera remains incorrectly positioned][:run]
[1:09:37][Reacquaint ourselves with GetCameraRectangleAtDistance()][:camera :research]
[1:10:47][Break in to UpdateAndRenderWorld() in -Od, and inspect CameraZ and DeltaFromSim][:camera :run]
[1:13:10][Reacquaint ourselves with UpdateCameraForEntityMovement()][:camera :research]
[1:15:30][Break in to UpdateCameraForEntityMovement(), and never enter the InRoom branch][:camera :run]
[1:16:04][Reacquaint ourselves with the :"procedural generation" code in terms of Z][:camera :research]
[1:19:55][Make BeginGridEdit() enlarge rooms by 5 units in Z][:"procedural generation"]
[1:20:52][Enter the InRoom branch in UpdateCameraForEntityMovement()][:camera :run]
[1:21:03][Our :camera is now correctly positioned, and our frame rate is far higher][:run]
[1:21:40][\~30% frame time on ComputeLightPropagationWork, but our fogging is incorrect][:lighting :performance :run]
[1:23:05][Make UpdateAndRenderWorld() set the camera's fogging FocusMinZ and FocusMaxZ based on the ExpectedFocusZ][:camera]
[1:24:55][Our focused level is no longer fogged out][:camera :run]
[1:25:28][Determine to position light probes relative to the floor and ceiling][:lighting :run]
[1:27:16][Make UpdateLighting() call DebugDrawOctahedralValues()][:"debug visualisation" :lighting]
[1:29:14][Hit a read access violation on DebugDrawColorDir()][:"debug visualisation" :lighting :run]
[1:29:53][Hit a read access violation on Texel.Value in DebugDrawColorDir() in -Od][:"debug visualisation" :lighting :run]
[1:30:36][Fix DebugDrawOctahedralValues() to account for our "Z-less" world][:"debug visualisation" :lighting]
[1:31:23][:Run correctly][:"debug visualisation" :lighting]
[1:31:41][Check out our light probes in -O2][:"debug visualisation" :lighting :run]
[1:32:26][Try letting DebugDrawOctahedralValues() draw all the light probes][:"debug visualisation" :lighting]
[1:32:41][Hit our "overflow" assertion in PushQuad()][:"debug visualisation" :lighting :run]
[1:32:44][Try making DebugDrawOctahedralValues() draw half the light probes][:"debug visualisation" :lighting]
[1:32:54][Check out our light probes, with potential bugs][:"debug visualisation" :lighting :run]
[1:34:08][Make UpdateAndRenderEntities() draw the colliders][:collision :"debug visualisation" :"entity system" :lighting]
[1:34:44][Based on the colliders, our light probes look buggy][:"debug visualisation" :lighting :run]
[1:37:43][Reflect on our :lighting simplifications, and consider next steps][:performance :speech]
[1:40:00][Consider removing spatial partitioning of our 2D :lighting grid, raycasting directly on it][:performance :run]
[1:43:25][Determine to investigate our buggy light probes][:lighting :run]
[1:45:24][Force all light probes through the not-inside branch in FullCast()][:lighting]
[1:45:53][Those buggy light probes now pick up light][:lighting :run]
[1:46:12][Let light probes enter the inside branch in FullCast()][:lighting]
[1:46:32][Consider debugging versus simplifying the spatial partition for raycasting][:lighting :research]
[1:50:00][Simplifying raycasting spatial partition: 1) Removing Z][:lighting :research]
[1:50:12][Simplifying raycasting spatial partition: 2) Turning it into a grid][:lighting :research]
[1:50:28][Plan to remove Z from GridBuildSpatialPartition()][:lighting :research]
[1:54:36][Step in to UpdateLighting() and inspect the VoxCellDim and SpatialCellCount][:lighting :run]
[1:57:52][Make UpdateLighting() set the AtlasToSpatialGridIndexOffset.Z to 0][:lighting]
[1:58:47][Make PushLightingRenderValues() draw the spatial grid][:"debug visualisation" :lighting]
[1:59:07][Our spatial grid is too low][:"debug visualisation" :lighting :run]
[1:59:39][Make UpdateLighting() give the spatial grid three layers of height][:lighting]
[2:00:38][Our spatial grid remains too low][:"debug visualisation" :lighting :run]
[2:00:53][Reacquaint ourselves with the spatial grid alignment code][:lighting :research]
[2:01:53][Make UpdateLighting() offset the spatial grid in Z by a third of the usual amount][:lighting]
[2:02:12][Our spatial grid is now correctly aligned][:"debug visualisation" :lighting :run]
[2:02:45][Remove the Z loop from ComputeWalkTable(), respecifying GetOctantFor() as GetQuadrantFor()][:lighting]
[2:10:18][Hit our assertion in GetQuadrantFor()][:lighting :run]
[2:11:16][Make FullCast() zero out the Remainder.z][:lighting]
[2:11:47][Our quadrant table should be being computed correctly][:lighting :run]
[2:13:57][Step through FullCast() watching that HalfAtlasIndex.z remains 0][:lighting :run]
[2:16:01][Determine to inspect the spatial partition][:lighting :research]
[2:17:04][Disable light probe direction drawing in DebugDrawOctahedralValues()][:"debug visualisation" :lighting]
[2:17:33][Check out our light probe boxes][:"debug visualisation" :lighting :run]
[2:17:44][Try making DebugDrawOctahedralValues() draw all the light probes][:"debug visualisation" :lighting]
[2:17:58][Check out our complete set of light probes][:"debug visualisation" :lighting :run]
[2:18:06][Relieve UpdateAndRenderEntities() of drawing the colliders][:collision :"debug visualisation" :"entity system" :lighting]
[2:18:15][Check our set of :"debug visualisation"][:run]
[2:18:31][Introduce DebugDrawSpatialGrid() for UpdateLighting() to call][:"debug visualisation" :lighting]
[2:21:34][Check out our spatial grid, with eight probes per cell][:"debug visualisation" :lighting :run]
[2:23:02][Make DebugDrawSpatialGrid() checkerboard the spatial grid colouring][:"debug visualisation" :lighting]
[2:24:27][Check out our checkerboard spatial grid][:"debug visualisation" :lighting :run]
[2:24:38][Make DebugDrawSpatialGrid() enlarge the cells slightly][:"debug visualisation" :lighting]
[2:25:43][Check out our enlarged checkerboard spatial grid][:"debug visualisation" :lighting :run]
[2:26:10][Fix DebugDrawSpatialGrid() to shrink the cells][:"debug visualisation" :lighting]
[2:26:22][Check out our shrunken checkerboard spatial grid][:"debug visualisation" :lighting :run]
[2:26:47][Make DebugDrawSpatialGrid() draw the leaves][:"debug visualisation" :lighting]
[2:32:36][Try to view our spatial grid leaves][:"debug visualisation" :lighting :run]
[2:32:46][Prevent DebugDrawSpatialGrid() from drawing the cell boundaries][:"debug visualisation" :lighting]
[2:33:13][Our spatial grid contains no leaves][:"debug visualisation" :lighting :run]
[2:33:19][Scour GridBuildSpatialPartition() for bugs][:lighting :research]
[2:34:26][Fix GridBuildSpatialPartition() to retain Z in the ClippingRegion][:lighting]
[2:34:59][Our spatial grid still contains no leaves][:"debug visualisation" :lighting :run]
[2:35:20][Scour GridBuildSpatialPartition() for bugs (cont.)][:lighting :research]
[2:36:14][Assert(Z == 0) in GridBuildSpatialPartition()][:lighting]
[2:36:31][Scour GridBuildSpatialPartition() for bugs (cont.)][:lighting :research]
[2:37:04][Fix GridBuildSpatialPartition() to not consider Z as part of the apron][:lighting]
[2:37:33][Hit our "overflow" assertion in PushQuad()][:"debug visualisation" :lighting :run]
[2:37:45][Toggle off DebugDrawOctahedralValues() in UpdateLighting()][:"debug visualisation" :lighting]
[2:38:12][Check out the spatial partition leaves of our lit world][:"debug visualisation" :lighting :run]
[2:41:53][Check GridRayCast() for the source of light emission][:lighting :research]
[2:43:20][Leave a TODO to handle light probes inside a light source][:lighting]
[2:44:26][Try to make sense of the tangled mess of spatial partition leaves][:"debug visualisation" :lighting :run]
[2:45:41][Toggle off DebugDrawSpatialGrid() in UpdateLighting()][:"debug visualisation" :lighting]
[2:46:00][Check out the world's :lighting, at 16ms per frame][:performance :run]
[2:47:18][Increase tUpdateBlend from 1/60 to 30/60 in UpdateLighting()][:lighting]
[2:47:30][Our :lighting flickers][:run]
[2:48:15][Decrease tUpdateBlend from 30/60 to 15/60 in UpdateLighting()][:lighting]
[2:48:27][Our :lighting still flickers][:run]
[2:48:41][Decrease tUpdateBlend from 15/60 to 5/60 in UpdateLighting()][:lighting]
[2:49:03][Our :lighting flicker may be eliminated by casting four times as many rays][:run]
[2:50:09][Increase tUpdateBlend from 5/60 to 20/60 in UpdateLighting()][:lighting]
[2:50:36][Our shading rate is pretty responsive][:lighting :run]
[2:51:32][Reacquaint ourselves with GridRayCast()][:lighting :research]
[2:56:14][Reacquaint ourselves with the entropy-based light :sampling][:lighting :research]
[2:56:50][Remove EntropyFrameCount and LightPointEntropy][:lighting]
[2:57:51][Reacquaint ourselves with the entropy-based light :sampling (cont.)][:lighting :research]
[2:58:53][Try making ComputeLightPropagationWork() increment the EntropyIndex by 1 (rather than 234987)][:lighting]
[2:59:04][Our :lighting looks broadly similar][:run]
[2:59:18][Make FullCast() take EntopyIndex as a pointer so that it may increment it][:lighting]
[3:00:32][Our :lighting looks the same][:run]
[3:00:38][Add a SampleBatch loop to FullCast() to perform the GridRayCast() code eight times][:lighting]
[3:01:15][Our :lighting works, but is not as smooth as hoped][:run]
[3:01:43][Increase the SampleBatch loop from 8 to 16 in FullCast()][:lighting]
[3:01:56][Our :lighting remains flickery][:run]
[3:02:27][Rethink how casting more rays may affect the smoothing][:lighting :research]
[3:03:14][Check out our :lighting flicker][:run]
[3:04:20][Remove the SampleBatch loop from FullCast()][:lighting]
[3:04:34][Add a SampleBatch loop to ComputeLightPropagationWork() to perform the FullCast() code sixteen times][:lighting]
[3:05:17][Our :lighting remains flickery][:run]
[3:05:23][Increase the SampleBatch loop from 16 to 32 in ComputeLightPropagationWork()][:lighting]
[3:05:41][Our :lighting remains flickery][:run]
[3:05:50][Decrease tUpdateBlend from 20/60 to 1/60 in UpdateLighting()][:lighting]
[3:06:05][We see other :lighting issues][:run]
[3:06:25][Move the SampleBatch loop from ComputeLightPropagationWork() in to FullCast()][:lighting]
[3:06:58][Our :performance is great, just with other :lighting bugs to fix][:run]
[3:07:43][Plan to meticulously remove Z from the :lighting][:research]
[3:10:17][Consider :lighting to be good enough, once debugged][:run]
[3:10:56][Decrease the SampleBatch loop from 32 to 16 in FullCast()][:lighting]
[3:11:12][\~20ms per frame, and \~84% frame time on ComputeLightPropagationWork][:lighting :performance :run]
[3:11:42][That's good enough for today, planning next time to clean up the spatial partition and intersect rays properly][:speech]
[3:13:01][@technicbeam][Soon = before next Sunday?]
[3:13:07][Thanks, everybody][:speech]
[/video]
