Handmade Hero»Episode Guide
Entity-based Lighting Storage
?
?

Keyboard Navigation

Global Keys

[, < / ], > Jump to previous / next episode
W, K, P / S, J, N Jump to previous / next marker
t / T Toggle theatre / SUPERtheatre mode
V Revert filter to original state Y Select link (requires manual Ctrl-c)

Menu toggling

q Quotes r References f Filter y Link c Credits

In-Menu Movement

a
w
s
d
h j k l


Quotes and References Menus

Enter Jump to timecode

Quotes, References and Credits Menus

o Open URL (in new tab)

Filter Menu

x, Space Toggle category and focus next
X, ShiftSpace Toggle category and focus previous
v Invert topics / media as per focus

Filter and Link Menus

z Toggle filter / linking mode

Credits Menu

Enter Open URL (in new tab)
0:07Recap and set the stage for the day, improving the runtime performance of the lighting
🗩
0:07Recap and set the stage for the day, improving the runtime performance of the lighting
🗩
0:07Recap and set the stage for the day, improving the runtime performance of the lighting
🗩
0:56Run the game to show our whole world, only excepting the trees, lit
🏃
0:56Run the game to show our whole world, only excepting the trees, lit
🏃
0:56Run the game to show our whole world, only excepting the trees, lit
🏃
4:43Consider the two ways of optimising the lighting solution to only process the necessary elements
🗩
4:43Consider the two ways of optimising the lighting solution to only process the necessary elements
🗩
4:43Consider the two ways of optimising the lighting solution to only process the necessary elements
🗩
6:11Prevent PushCube() from pushing on elements outside the bounds of the lighting solution, using a new LightBounds in render_group
6:11Prevent PushCube() from pushing on elements outside the bounds of the lighting solution, using a new LightBounds in render_group
6:11Prevent PushCube() from pushing on elements outside the bounds of the lighting solution, using a new LightBounds in render_group
10:58Run the game and hit the assert in GetHashFromID()
🏃
10:58Run the game and hit the assert in GetHashFromID()
🏃
10:58Run the game and hit the assert in GetHashFromID()
🏃
11:18Make PushCube() clear the first LightIndexStore
11:18Make PushCube() clear the first LightIndexStore
11:18Make PushCube() clear the first LightIndexStore
11:33Run the game to see no lighting on anything
🏃
11:33Run the game to see no lighting on anything
🏃
11:33Run the game to see no lighting on anything
🏃
12:06Make EnableLighting() take a rectangle3 LightingBounds, and UpdateAndRenderWorld() pass the entire SimBounds to it
12:06Make EnableLighting() take a rectangle3 LightingBounds, and UpdateAndRenderWorld() pass the entire SimBounds to it
12:06Make EnableLighting() take a rectangle3 LightingBounds, and UpdateAndRenderWorld() pass the entire SimBounds to it
13:24Run the game to see the whole world lit
🏃
13:24Run the game to see the whole world lit
🏃
13:24Run the game to see the whole world lit
🏃
13:49Introduce smaller LightBounds in UpdateAndRenderWorld() to pass to EnableLighting()
13:49Introduce smaller LightBounds in UpdateAndRenderWorld() to pass to EnableLighting()
13:49Introduce smaller LightBounds in UpdateAndRenderWorld() to pass to EnableLighting()
15:00Run the game to see a speed increase because some of the world is not participating in the lighting solution
🏃
15:00Run the game to see a speed increase because some of the world is not participating in the lighting solution
🏃
15:00Run the game to see a speed increase because some of the world is not participating in the lighting solution
🏃
15:26Further shrink the LightBounds in UpdateAndRenderWorld()
15:26Further shrink the LightBounds in UpdateAndRenderWorld()
15:26Further shrink the LightBounds in UpdateAndRenderWorld()
15:38Run the game to see yet more speedup, but buggy behaviour with the light apparently wrapping
🏃
15:38Run the game to see yet more speedup, but buggy behaviour with the light apparently wrapping
🏃
15:38Run the game to see yet more speedup, but buggy behaviour with the light apparently wrapping
🏃
20:01Consider how to visualise the lighting solution
🗩
20:01Consider how to visualise the lighting solution
🗩
20:01Consider how to visualise the lighting solution
🗩
23:41Potential bugs - correctness and performance - in the lighting solution
🖌
23:41Potential bugs - correctness and performance - in the lighting solution
🖌
23:41Potential bugs - correctness and performance - in the lighting solution
🖌
32:08Run the game and note the impossibility of diagnosing our lighting bug without visualising lighting elements
🏃
32:08Run the game and note the impossibility of diagnosing our lighting bug without visualising lighting elements
🏃
32:08Run the game and note the impossibility of diagnosing our lighting bug without visualising lighting elements
🏃
34:58Read carefully through PushCube() for potential bugs
📖
34:58Read carefully through PushCube() for potential bugs
📖
34:58Read carefully through PushCube() for potential bugs
📖
36:14Determine to allocate lighting elements responsibly
36:14Determine to allocate lighting elements responsibly
36:14Determine to allocate lighting elements responsibly
38:02Introduce a free list for the lighting solution, replacing LightPointCount in game_render_commands with a u16 FirstFreeLightingChunk, adding NextFree to lighting_point and making PushCube() free and reuse light chunks
38:02Introduce a free list for the lighting solution, replacing LightPointCount in game_render_commands with a u16 FirstFreeLightingChunk, adding NextFree to lighting_point and making PushCube() free and reuse light chunks
38:02Introduce a free list for the lighting solution, replacing LightPointCount in game_render_commands with a u16 FirstFreeLightingChunk, adding NextFree to lighting_point and making PushCube() free and reuse light chunks
53:36Consider how to determine when an entity holding light indices no longer needs them
🗩
53:36Consider how to determine when an entity holding light indices no longer needs them
🗩
53:36Consider how to determine when an entity holding light indices no longer needs them
🗩
54:24Add a LightPointUsed array to game_render_commands for PushCube() to store light point usage
54:24Add a LightPointUsed array to game_render_commands for PushCube() to store light point usage
54:24Add a LightPointUsed array to game_render_commands for PushCube() to store light point usage
55:53Implement FreeLightChunk() and LightChunkFrameSweep()
55:53Implement FreeLightChunk() and LightChunkFrameSweep()
55:53Implement FreeLightChunk() and LightChunkFrameSweep()
1:00:17Make WinMain() clear the lighting memory every frame before rendering, and fix compile errors
1:00:17Make WinMain() clear the lighting memory every frame before rendering, and fix compile errors
1:00:17Make WinMain() clear the lighting memory every frame before rendering, and fix compile errors
1:03:58Encounter the problem of handling lights scattered about the array, and avoiding processing stuff that doesn't exist
🗩
1:03:58Encounter the problem of handling lights scattered about the array, and avoiding processing stuff that doesn't exist
🗩
1:03:58Encounter the problem of handling lights scattered about the array, and avoiding processing stuff that doesn't exist
🗩
1:10:37Replace Solution->PointCount with LIGHT_POINTS_PER_CHUNK in OutputLightingPoints() and OutputLightingTextures()
1:10:37Replace Solution->PointCount with LIGHT_POINTS_PER_CHUNK in OutputLightingPoints() and OutputLightingTextures()
1:10:37Replace Solution->PointCount with LIGHT_POINTS_PER_CHUNK in OutputLightingPoints() and OutputLightingTextures()
1:13:45Prevent LightingTest() from setting the PointCount, and make it copy the whole set of lighting indices
1:13:45Prevent LightingTest() from setting the PointCount, and make it copy the whole set of lighting indices
1:13:45Prevent LightingTest() from setting the PointCount, and make it copy the whole set of lighting indices
1:15:28Note that we are doing everything on an allocation basis
🗩
1:15:28Note that we are doing everything on an allocation basis
🗩
1:15:28Note that we are doing everything on an allocation basis
🗩
1:16:05Make DefaultRenderCommands() take and initialise LightChunkUsed
1:16:05Make DefaultRenderCommands() take and initialise LightChunkUsed
1:16:05Make DefaultRenderCommands() take and initialise LightChunkUsed
1:17:25Note that LightChunkFrameSweep() skips Chunk 0 and builds the free list backwards
🗩
1:17:25Note that LightChunkFrameSweep() skips Chunk 0 and builds the free list backwards
🗩
1:17:25Note that LightChunkFrameSweep() skips Chunk 0 and builds the free list backwards
🗩
1:19:44Replace Solution->PointCount with LIGHT_POINTS_PER_CHUNK in ComputeLightPropagation()
1:19:44Replace Solution->PointCount with LIGHT_POINTS_PER_CHUNK in ComputeLightPropagation()
1:19:44Replace Solution->PointCount with LIGHT_POINTS_PER_CHUNK in ComputeLightPropagation()
1:24:23Add u8 *LightChunkUsed to lighting_solution
1:24:23Add u8 *LightChunkUsed to lighting_solution
1:24:23Add u8 *LightChunkUsed to lighting_solution
1:25:03Run the game and hit the assert in FreeLightChunk()
🏃
1:25:03Run the game and hit the assert in FreeLightChunk()
🏃
1:25:03Run the game and hit the assert in FreeLightChunk()
🏃
1:26:28Consider how to confirm which entity occupied a light chunk
🗩
1:26:28Consider how to confirm which entity occupied a light chunk
🗩
1:26:28Consider how to confirm which entity occupied a light chunk
🗩
1:28:48Temporarily make PushCube() take a u32 EntityID
1:28:48Temporarily make PushCube() take a u32 EntityID
1:28:48Temporarily make PushCube() take a u32 EntityID
1:30:20Consider making entities store their previous lighting information, and use a hot list of regions rather than a free list
1:30:20Consider making entities store their previous lighting information, and use a hot list of regions rather than a free list
1:30:20Consider making entities store their previous lighting information, and use a hot list of regions rather than a free list
1:32:01Make PushCube() instead take a lighting_point *LightStore and u32 LightCount
1:32:01Make PushCube() instead take a lighting_point *LightStore and u32 LightCount
1:32:01Make PushCube() instead take a lighting_point *LightStore and u32 LightCount
1:34:29Add an array of lighting_point Points to the entity struct
1:34:29Add an array of lighting_point Points to the entity struct
1:34:29Add an array of lighting_point Points to the entity struct
1:37:40The problem of sharing lighting points between entities
🖌
1:37:40The problem of sharing lighting points between entities
🖌
1:37:40The problem of sharing lighting points between entities
🖌
1:41:43Large sets of lighting points
🖌
1:41:43Large sets of lighting points
🖌
1:41:43Large sets of lighting points
🖌
1:45:55Spatially merging lighting points
🖌
1:45:55Spatially merging lighting points
🖌
1:45:55Spatially merging lighting points
🖌
1:47:55Prevent PushCube() from taking LightCount and managing a free list
1:47:55Prevent PushCube() from taking LightCount and managing a free list
1:47:55Prevent PushCube() from taking LightCount and managing a free list
1:48:52Replace EmitC0 from game_render_commands with Emission in lighting_box, and add lighting_point *Storage to lighting_box
1:48:52Replace EmitC0 from game_render_commands with Emission in lighting_box, and add lighting_point *Storage to lighting_box
1:48:52Replace EmitC0 from game_render_commands with Emission in lighting_box, and add lighting_point *Storage to lighting_box
1:55:22Remove FreeLightChunk() and LightChunkFrameSweep()α
1:55:22Remove FreeLightChunk() and LightChunkFrameSweep()α
1:55:22Remove FreeLightChunk() and LightChunkFrameSweep()α
1:55:55Restore PointCount to lighting_solution and move the light point generation code from PushCube() into LightingTest()
1:55:55Restore PointCount to lighting_solution and move the light point generation code from PushCube() into LightingTest()
1:55:55Restore PointCount to lighting_solution and move the light point generation code from PushCube() into LightingTest()
1:59:18Store full arrays rather than pointers in lighting_solution, and introduce lighting_point_state for lighting_box to store
1:59:18Store full arrays rather than pointers in lighting_solution, and introduce lighting_point_state for lighting_box to store
1:59:18Store full arrays rather than pointers in lighting_solution, and introduce lighting_point_state for lighting_box to store
2:01:47Make LightingTest() copy out the lighting solution per element
2:01:47Make LightingTest() copy out the lighting solution per element
2:01:47Make LightingTest() copy out the lighting solution per element
2:03:14Replace LastIsValid in lighting_solution with StorageContentsAreValid in lighting_box and propagate this change to LightingTest()
2:03:14Replace LastIsValid in lighting_solution with StorageContentsAreValid in lighting_box and propagate this change to LightingTest()
2:03:14Replace LastIsValid in lighting_solution with StorageContentsAreValid in lighting_box and propagate this change to LightingTest()
2:11:37Move the finalisation code from ComputeLightPropagation() to LightingTest()
2:11:37Move the finalisation code from ComputeLightPropagation() to LightingTest()
2:11:37Move the finalisation code from ComputeLightPropagation() to LightingTest()
2:13:08Consider a better way to solve the lighting across frames
🗩
2:13:08Consider a better way to solve the lighting across frames
🗩
2:13:08Consider a better way to solve the lighting across frames
🗩
2:16:18Begin to enable LightingTest() to handle both cases of storage contents validity
2:16:18Begin to enable LightingTest() to handle both cases of storage contents validity
2:16:18Begin to enable LightingTest() to handle both cases of storage contents validity
2:18:39Consider packing the lighting data tighter
🗩
2:18:39Consider packing the lighting data tighter
🗩
2:18:39Consider packing the lighting data tighter
🗩
2:22:37Make LightingTest() use alternate storage if the storage contents are not valid, and prevent OutputLightingTextures() from looping over the chunks
2:22:37Make LightingTest() use alternate storage if the storage contents are not valid, and prevent OutputLightingTextures() from looping over the chunks
2:22:37Make LightingTest() use alternate storage if the storage contents are not valid, and prevent OutputLightingTextures() from looping over the chunks
2:26:05Finish enabling LightingTest() to blend the lighting if the storage contents are valid, and fix compile errors
2:26:05Finish enabling LightingTest() to blend the lighting if the storage contents are valid, and fix compile errors
2:26:05Finish enabling LightingTest() to blend the lighting if the storage contents are valid, and fix compile errors
2:37:25Remove StorageContentsAreValid from lighting_box and instead make LightingTest() check if the normal of the first lighting point is valid
2:37:25Remove StorageContentsAreValid from lighting_box and instead make LightingTest() check if the normal of the first lighting point is valid
2:37:25Remove StorageContentsAreValid from lighting_box and instead make LightingTest() check if the normal of the first lighting point is valid
2:39:34Run the game and crash in LightingTest()
🏃
2:39:34Run the game and crash in LightingTest()
🏃
2:39:34Run the game and crash in LightingTest()
🏃
2:39:57Try to make LightingTest() correctly set the FirstPoint
2:39:57Try to make LightingTest() correctly set the FirstPoint
2:39:57Try to make LightingTest() correctly set the FirstPoint
2:40:29Run the game, crash in LightingTest() and inspect the values to find that Box->Storage is not valid
🏃
2:40:29Run the game, crash in LightingTest() and inspect the values to find that Box->Storage is not valid
🏃
2:40:29Run the game, crash in LightingTest() and inspect the values to find that Box->Storage is not valid
🏃
2:41:36Assert in LightingTest() that LightPointIndex <= LIGHT_DATA_WIDTH, and temporarily try hard setting the LightStore->Direction to 1, 1, 1
2:41:36Assert in LightingTest() that LightPointIndex <= LIGHT_DATA_WIDTH, and temporarily try hard setting the LightStore->Direction to 1, 1, 1
2:41:36Assert in LightingTest() that LightPointIndex <= LIGHT_DATA_WIDTH, and temporarily try hard setting the LightStore->Direction to 1, 1, 1
2:42:14Run the game to determine that the pulling out, rather than pushing on, of boxes is the problem
🏃
2:42:14Run the game to determine that the pulling out, rather than pushing on, of boxes is the problem
🏃
2:42:14Run the game to determine that the pulling out, rather than pushing on, of boxes is the problem
🏃
2:42:55Step in to LightingTest() and inspect the Solution->Boxes to find that they are all garbage
🏃
2:42:55Step in to LightingTest() and inspect the Solution->Boxes to find that they are all garbage
🏃
2:42:55Step in to LightingTest() and inspect the Solution->Boxes to find that they are all garbage
🏃
2:43:29Make UpdateAndRenderWorld() run the lighting solution before EndSim()
2:43:29Make UpdateAndRenderWorld() run the lighting solution before EndSim()
2:43:29Make UpdateAndRenderWorld() run the lighting solution before EndSim()
2:44:19Run the game to see that the Boxes look valid, but that the LightBoxCount is greater than expected, and investigate why
🏃
2:44:19Run the game to see that the Boxes look valid, but that the LightBoxCount is greater than expected, and investigate why
🏃
2:44:19Run the game to see that the Boxes look valid, but that the LightBoxCount is greater than expected, and investigate why
🏃
2:46:09Step in to LightingTest() and realise that it is erroneously operating on the new set of boxes
🏃
2:46:09Step in to LightingTest() and realise that it is erroneously operating on the new set of boxes
🏃
2:46:09Step in to LightingTest() and realise that it is erroneously operating on the new set of boxes
🏃
2:46:46Make LightingTest() store and iterate over the OriginalBoxCount
2:46:46Make LightingTest() store and iterate over the OriginalBoxCount
2:46:46Make LightingTest() store and iterate over the OriginalBoxCount
2:47:04Run the game to see that we're at least running but totally wrong
🏃
2:47:04Run the game to see that we're at least running but totally wrong
🏃
2:47:04Run the game to see that we're at least running but totally wrong
🏃
2:48:16Q&A
🗩
2:48:16Q&A
🗩
2:48:16Q&A
🗩
2:49:58billdstrong Q: The 148 Mil was the number of cycles the lighting took
🗪
2:49:58billdstrong Q: The 148 Mil was the number of cycles the lighting took
🗪
2:49:58billdstrong Q: The 148 Mil was the number of cycles the lighting took
🗪
2:50:18mallesbixie Q: Is this your usual design process, a bit ad hoc?
🗪
2:50:18mallesbixie Q: Is this your usual design process, a bit ad hoc?
🗪
2:50:18mallesbixie Q: Is this your usual design process, a bit ad hoc?
🗪
2:52:14Wrap it up
🗩
2:52:14Wrap it up
🗩
2:52:14Wrap it up
🗩