diff --git a/cmuratori/hero/code/code646.hmml b/cmuratori/hero/code/code646.hmml new file mode 100644 index 0000000..e07a600 --- /dev/null +++ b/cmuratori/hero/code/code646.hmml @@ -0,0 +1,176 @@ +[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]