Handmade Hero»Episode Guide
Debugging Octahedral Shading
?
?

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:03Recap and set the stage for the day
🗩
0:03Recap and set the stage for the day
🗩
0:03Recap and set the stage for the day
🗩
0:31Demo our octahedral light map
🏃
0:31Demo our octahedral light map
🏃
0:31Demo our octahedral light map
🏃
3:23Understanding the Octahedron1
📖
3:23Understanding the Octahedron1
📖
3:23Understanding the Octahedron1
📖
4:55Orienting the octahedral wrapping by importance
🏃
4:55Orienting the octahedral wrapping by importance
🏃
4:55Orienting the octahedral wrapping by importance
🏃
6:06Determine to fill in the cracks and sample the octahedron in the shaders
🗩
6:06Determine to fill in the cracks and sample the octahedron in the shaders
🗩
6:06Determine to fill in the cracks and sample the octahedron in the shaders
🗩
7:36Make SampleLighting() in CompileZBiasProgram() light the pixels by their position within voxels
7:36Make SampleLighting() in CompileZBiasProgram() light the pixels by their position within voxels
7:36Make SampleLighting() in CompileZBiasProgram() light the pixels by their position within voxels
9:32Check out our lit voxels
🏃
9:32Check out our lit voxels
🏃
9:32Check out our lit voxels
🏃
10:43Determine to sample from our octahedral map
🏃
📖
10:43Determine to sample from our octahedral map
🏃
📖
10:43Determine to sample from our octahedral map
🏃
📖
12:28Set up SampleLighting() to sample from the octahedral light map
12:28Set up SampleLighting() to sample from the octahedral light map
12:28Set up SampleLighting() to sample from the octahedral light map
15:54Make SampleLighting() compute the location from where to sample the octahedral light map
15:54Make SampleLighting() compute the location from where to sample the octahedral light map
15:54Make SampleLighting() compute the location from where to sample the octahedral light map
27:33Set up CompileZBiasProgram() to pass the values required by SampleLighting() to lookup into the octahedral light map
27:33Set up CompileZBiasProgram() to pass the values required by SampleLighting() to lookup into the octahedral light map
27:33Set up CompileZBiasProgram() to pass the values required by SampleLighting() to lookup into the octahedral light map
28:43Consider not using different resolutions for the light and depth maps2
📖
28:43Consider not using different resolutions for the light and depth maps2
📖
28:43Consider not using different resolutions for the light and depth maps2
📖
34:04Set up CompileZBiasProgram() to pass the LIGHT_LOOKUP_SQUARE_DIM to SampleLighting()
34:04Set up CompileZBiasProgram() to pass the LIGHT_LOOKUP_SQUARE_DIM to SampleLighting()
34:04Set up CompileZBiasProgram() to pass the LIGHT_LOOKUP_SQUARE_DIM to SampleLighting()
34:50Voxel Atlas UVs
🖌
34:50Voxel Atlas UVs
🖌
34:50Voxel Atlas UVs
🖌
40:40Make SampleLighting() compute the dimensions required to lookup into the octahedral light map
40:40Make SampleLighting() compute the dimensions required to lookup into the octahedral light map
40:40Make SampleLighting() compute the dimensions required to lookup into the octahedral light map
48:19Hit shader errors
🏃
48:19Hit shader errors
🏃
48:19Hit shader errors
🏃
49:18Fix the Result assignments in SampleLighting()
49:18Fix the Result assignments in SampleLighting()
49:18Fix the Result assignments in SampleLighting()
49:51See our darkly and incorrectly lit world
🏃
49:51See our darkly and incorrectly lit world
🏃
49:51See our darkly and incorrectly lit world
🏃
50:49Change SampleLighting() to orient our lookup around the octahedron centres
50:49Change SampleLighting() to orient our lookup around the octahedron centres
50:49Change SampleLighting() to orient our lookup around the octahedron centres
55:22Hit shader errors
🏃
55:22Hit shader errors
🏃
55:22Hit shader errors
🏃
55:30Fix naming in SampleLighting()
55:30Fix naming in SampleLighting()
55:30Fix naming in SampleLighting()
55:42See our discontinuously lit world
🏃
55:42See our discontinuously lit world
🏃
55:42See our discontinuously lit world
🏃
58:13Try making SampleLighting() lookup into a shrunken area of the octahedral light map
58:13Try making SampleLighting() lookup into a shrunken area of the octahedral light map
58:13Try making SampleLighting() lookup into a shrunken area of the octahedral light map
58:48See no improvement
🏃
58:48See no improvement
🏃
58:48See no improvement
🏃
59:41Introduce VOXEL_OFFSET_C() and VOXEL_OFFSET_D() for EndLightingComputation() to call
59:41Introduce VOXEL_OFFSET_C() and VOXEL_OFFSET_D() for EndLightingComputation() to call
59:41Introduce VOXEL_OFFSET_C() and VOXEL_OFFSET_D() for EndLightingComputation() to call
1:03:57Verify that our new macros work
🏃
1:03:57Verify that our new macros work
🏃
1:03:57Verify that our new macros work
🏃
1:04:09Set up to copy the values at the seams around the octahedron3
📖
1:04:09Set up to copy the values at the seams around the octahedron3
📖
1:04:09Set up to copy the values at the seams around the octahedron3
📖
1:06:40Make EndLightingComputation() copy the values at the seams around the octahedron4
1:06:40Make EndLightingComputation() copy the values at the seams around the octahedron4
1:06:40Make EndLightingComputation() copy the values at the seams around the octahedron4
1:09:12Check out the light map
🏃
1:09:12Check out the light map
🏃
1:09:12Check out the light map
🏃
1:09:39Toggle on the coloured octahedron in EndLightingComputation(), and make OpenGLChangeToSettings() zoom in to it
1:09:39Toggle on the coloured octahedron in EndLightingComputation(), and make OpenGLChangeToSettings() zoom in to it
1:09:39Toggle on the coloured octahedron in EndLightingComputation(), and make OpenGLChangeToSettings() zoom in to it
1:10:31Check out the light map to see no copying
🏃
1:10:31Check out the light map to see no copying
🏃
1:10:31Check out the light map to see no copying
🏃
1:10:47Make EndLightingComputation() copy in to the bottom row of the octahedron
1:10:47Make EndLightingComputation() copy in to the bottom row of the octahedron
1:10:47Make EndLightingComputation() copy in to the bottom row of the octahedron
1:11:39See copying in the light map
🏃
1:11:39See copying in the light map
🏃
1:11:39See copying in the light map
🏃
1:11:58Make EndLightingComputation() copy in to the top row of the octahedron
1:11:58Make EndLightingComputation() copy in to the top row of the octahedron
1:11:58Make EndLightingComputation() copy in to the top row of the octahedron
1:12:38See copying in the light map
🏃
1:12:38See copying in the light map
🏃
1:12:38See copying in the light map
🏃
1:12:52Temporarily make EndLightingComputation() copy in coloured values
1:12:52Temporarily make EndLightingComputation() copy in coloured values
1:12:52Temporarily make EndLightingComputation() copy in coloured values
1:13:05See our correctly flipped copying in the light map
🏃
1:13:05See our correctly flipped copying in the light map
🏃
1:13:05See our correctly flipped copying in the light map
🏃
1:13:19Make EndLightingComputation() copy in to the left and right columns of the octahedron
1:13:19Make EndLightingComputation() copy in to the left and right columns of the octahedron
1:13:19Make EndLightingComputation() copy in to the left and right columns of the octahedron
1:16:56See copying in the light map, only missing the corners
🏃
1:16:56See copying in the light map, only missing the corners
🏃
1:16:56See copying in the light map, only missing the corners
🏃
1:17:10Check our left–right vertical copies with the paper5
📖
1:17:10Check our left–right vertical copies with the paper5
📖
1:17:10Check our left–right vertical copies with the paper5
📖
1:17:46Make EndLightingComputation() copy in to the corners of our octahedron
1:17:46Make EndLightingComputation() copy in to the corners of our octahedron
1:17:46Make EndLightingComputation() copy in to the corners of our octahedron
1:19:30See our fully filled light map
🏃
1:19:30See our fully filled light map
🏃
1:19:30See our fully filled light map
🏃
1:19:41Let EndLightingComputation() populate the light map with real values
1:19:41Let EndLightingComputation() populate the light map with real values
1:19:41Let EndLightingComputation() populate the light map with real values
1:19:49See our full light map, with no improvement to our discontinuity
🏃
1:19:49See our full light map, with no improvement to our discontinuity
🏃
1:19:49See our full light map, with no improvement to our discontinuity
🏃
1:21:05Scour CompileZBiasProgram() for octahedral mapping bugs
📖
1:21:05Scour CompileZBiasProgram() for octahedral mapping bugs
📖
1:21:05Scour CompileZBiasProgram() for octahedral mapping bugs
📖
1:24:11Explicitly write out the OctMapCenterUV and OctExteriorUVDim initialisations in SampleLighting(), and continue to scour this function for bugs
🖮
📖
1:24:11Explicitly write out the OctMapCenterUV and OctExteriorUVDim initialisations in SampleLighting(), and continue to scour this function for bugs
🖮
📖
1:24:11Explicitly write out the OctMapCenterUV and OctExteriorUVDim initialisations in SampleLighting(), and continue to scour this function for bugs
🖮
📖
1:28:21Fix OctMapInteriorUVDimC.y in SampleLighting()
1:28:21Fix OctMapInteriorUVDimC.y in SampleLighting()
1:28:21Fix OctMapInteriorUVDimC.y in SampleLighting()
1:29:43Hit shader error
🏃
1:29:43Hit shader error
🏃
1:29:43Hit shader error
🏃
1:29:59Fix typo in SampleLighting()
1:29:59Fix typo in SampleLighting()
1:29:59Fix typo in SampleLighting()
1:30:20See different lighting discontinuities
🏃
1:30:20See different lighting discontinuities
🏃
1:30:20See different lighting discontinuities
🏃
1:30:40Continue to scour SampleLighting() for bugs
📖
1:30:40Continue to scour SampleLighting() for bugs
📖
1:30:40Continue to scour SampleLighting() for bugs
📖
1:31:58Take a close look at our lighting discontinuities, and wonder if we have a blending error
🏃
1:31:58Take a close look at our lighting discontinuities, and wonder if we have a blending error
🏃
1:31:58Take a close look at our lighting discontinuities, and wonder if we have a blending error
🏃
1:33:58Centred, Padded Lookup
🖌
1:33:58Centred, Padded Lookup
🖌
1:33:58Centred, Padded Lookup
🖌
1:34:51Consider SampleLighting() to be doing a correct lookup
📖
1:34:51Consider SampleLighting() to be doing a correct lookup
📖
1:34:51Consider SampleLighting() to be doing a correct lookup
📖
1:35:52Toggle on the coloured octahedron in EndLightingComputation()
1:35:52Toggle on the coloured octahedron in EndLightingComputation()
1:35:52Toggle on the coloured octahedron in EndLightingComputation()
1:36:25Observe the lighting discontinuities along with the light map
🏃
1:36:25Observe the lighting discontinuities along with the light map
🏃
1:36:25Observe the lighting discontinuities along with the light map
🏃
1:37:41Make CompileZBiasProgram() colour the world directly with light
1:37:41Make CompileZBiasProgram() colour the world directly with light
1:37:41Make CompileZBiasProgram() colour the world directly with light
1:37:58Observe the lighting discontinuities with the world coloured with light
🏃
1:37:58Observe the lighting discontinuities with the world coloured with light
🏃
1:37:58Observe the lighting discontinuities with the world coloured with light
🏃
1:39:31Let EndLightingComputation() populate the light map with real values
1:39:31Let EndLightingComputation() populate the light map with real values
1:39:31Let EndLightingComputation() populate the light map with real values
1:39:37Note that the lighting discontinuities are not at copy points
🏃
1:39:37Note that the lighting discontinuities are not at copy points
🏃
1:39:37Note that the lighting discontinuities are not at copy points
🏃
1:39:54Toggle on the coloured octahedron in EndLightingComputation()
1:39:54Toggle on the coloured octahedron in EndLightingComputation()
1:39:54Toggle on the coloured octahedron in EndLightingComputation()
1:39:58Realise why we're not smoothly interpolating between adjacent, non-copied octants
🏃
1:39:58Realise why we're not smoothly interpolating between adjacent, non-copied octants
🏃
1:39:58Realise why we're not smoothly interpolating between adjacent, non-copied octants
🏃
1:40:55Toggle on linear blending in OpenGLChangeToSettings()
1:40:55Toggle on linear blending in OpenGLChangeToSettings()
1:40:55Toggle on linear blending in OpenGLChangeToSettings()
1:41:22Admire our continuous lighting
🏃
1:41:22Admire our continuous lighting
🏃
1:41:22Admire our continuous lighting
🏃
1:41:28Let EndLightingComputation() populate the light map with real values
1:41:28Let EndLightingComputation() populate the light map with real values
1:41:28Let EndLightingComputation() populate the light map with real values
1:41:54Admire our continuous, yet popping lighting
🏃
1:41:54Admire our continuous, yet popping lighting
🏃
1:41:54Admire our continuous, yet popping lighting
🏃
1:42:24Shoulder the Owl of Shame
🦉
1:42:24Shoulder the Owl of Shame
🦉
1:42:24Shoulder the Owl of Shame
🦉
1:42:50Admire our lighting
🏃
🦉
1:42:50Admire our lighting
🏃
🦉
1:42:50Admire our lighting
🏃
🦉
1:43:07Revert CompileZBiasProgram() to modulate the world's real colours with light
🦉
1:43:07Revert CompileZBiasProgram() to modulate the world's real colours with light
🦉
1:43:07Revert CompileZBiasProgram() to modulate the world's real colours with light
🦉
1:43:21Admire our lighting, noting its directionality
🏃
🦉
1:43:21Admire our lighting, noting its directionality
🏃
🦉
1:43:21Admire our lighting, noting its directionality
🏃
🦉
1:44:54Make CompileZBiasProgram() colour the world directly with light
🦉
🖮
1:44:54Make CompileZBiasProgram() colour the world directly with light
🦉
🖮
1:44:54Make CompileZBiasProgram() colour the world directly with light
🦉
🖮
1:44:59Check out our lighting seam
🏃
🦉
1:44:59Check out our lighting seam
🏃
🦉
1:44:59Check out our lighting seam
🏃
🦉
1:45:21Toggle on the coloured octahedron in EndLightingComputation()
🦉
🖮
1:45:21Toggle on the coloured octahedron in EndLightingComputation()
🦉
🖮
1:45:21Toggle on the coloured octahedron in EndLightingComputation()
🦉
🖮
1:45:30Consider the seam to be along the wrapping border
🏃
🦉
1:45:30Consider the seam to be along the wrapping border
🏃
🦉
1:45:30Consider the seam to be along the wrapping border
🏃
🦉
1:45:39Let EndLightingComputation() populate the light map with real values
🦉
🖮
1:45:39Let EndLightingComputation() populate the light map with real values
🦉
🖮
1:45:39Let EndLightingComputation() populate the light map with real values
🦉
🖮
1:45:50Consider the seam not to be along the wrapping border
🏃
🦉
1:45:50Consider the seam not to be along the wrapping border
🏃
🦉
1:45:50Consider the seam not to be along the wrapping border
🏃
🦉
1:45:59Toggle on the coloured octahedron in EndLightingComputation()
🦉
🖮
1:45:59Toggle on the coloured octahedron in EndLightingComputation()
🦉
🖮
1:45:59Toggle on the coloured octahedron in EndLightingComputation()
🦉
🖮
1:46:00Consider the seam to be straight down the middle of the pink
🏃
🦉
1:46:00Consider the seam to be straight down the middle of the pink
🏃
🦉
1:46:00Consider the seam to be straight down the middle of the pink
🏃
🦉
1:46:39Let EndLightingComputation() populate the light map with real values
🦉
🖮
1:46:39Let EndLightingComputation() populate the light map with real values
🦉
🖮
1:46:39Let EndLightingComputation() populate the light map with real values
🦉
🖮
1:46:49See the seam run in a different orientation
🏃
🦉
1:46:49See the seam run in a different orientation
🏃
🦉
1:46:49See the seam run in a different orientation
🏃
🦉
1:46:59Toggle on the coloured octahedron in EndLightingComputation()
🦉
🖮
1:46:59Toggle on the coloured octahedron in EndLightingComputation()
🦉
🖮
1:46:59Toggle on the coloured octahedron in EndLightingComputation()
🦉
🖮
1:47:06Inspect our seam
🏃
🦉
1:47:06Inspect our seam
🏃
🦉
1:47:06Inspect our seam
🏃
🦉
1:47:58Let EndLightingComputation() populate the light map with real values
🦉
🖮
1:47:58Let EndLightingComputation() populate the light map with real values
🦉
🖮
1:47:58Let EndLightingComputation() populate the light map with real values
🦉
🖮
1:48:13Note the brightening as the character hops up
🏃
🦉
1:48:13Note the brightening as the character hops up
🏃
🦉
1:48:13Note the brightening as the character hops up
🏃
🦉
1:49:42Try making SumLight() sample the lighting from the direction you're pointing, ignoring the actual reflection vector
🦉
🖮
1:49:42Try making SumLight() sample the lighting from the direction you're pointing, ignoring the actual reflection vector
🦉
🖮
1:49:42Try making SumLight() sample the lighting from the direction you're pointing, ignoring the actual reflection vector
🦉
🖮
1:49:57See no lighting discontinuities
🏃
🦉
1:49:57See no lighting discontinuities
🏃
🦉
1:49:57See no lighting discontinuities
🏃
🦉
1:51:21Revert SumLight() to use the reflection vector
🦉
🖮
1:51:21Revert SumLight() to use the reflection vector
🦉
🖮
1:51:21Revert SumLight() to use the reflection vector
🦉
🖮
1:52:02Wonder if EndLightingComputation() is populating the octahedron incorrectly
🦉
📖
1:52:02Wonder if EndLightingComputation() is populating the octahedron incorrectly
🦉
📖
1:52:02Wonder if EndLightingComputation() is populating the octahedron incorrectly
🦉
📖
1:53:16Sampling Within Pixels
🖌
1:53:16Sampling Within Pixels
🖌
1:53:16Sampling Within Pixels
🖌
1:55:08Fix EndLightingComputation() to offset the light population by half a pixel
🦉
🖮
1:55:08Fix EndLightingComputation() to offset the light population by half a pixel
🦉
🖮
1:55:08Fix EndLightingComputation() to offset the light population by half a pixel
🦉
🖮
1:56:29Still see the seam
🏃
🦉
1:56:29Still see the seam
🏃
🦉
1:56:29Still see the seam
🏃
🦉
1:56:49Toggle EndLightingComputation() between offsetting the light population and not, to see difference but no improvement
🏃
🦉
🖮
1:56:49Toggle EndLightingComputation() between offsetting the light population and not, to see difference but no improvement
🏃
🦉
🖮
1:56:49Toggle EndLightingComputation() between offsetting the light population and not, to see difference but no improvement
🏃
🦉
🖮
1:58:29Q&A
🗩
1:58:29Q&A
🗩
1:58:29Q&A
🗩
1:59:01somebody_took_my_name Q: Can you vary the light height to see its impact?
🗪
1:59:01somebody_took_my_name Q: Can you vary the light height to see its impact?
🗪
1:59:01somebody_took_my_name Q: Can you vary the light height to see its impact?
🗪
1:59:29somebody_took_my_name Either way
🗪
1:59:29somebody_took_my_name Either way
🗪
1:59:29somebody_took_my_name Either way
🗪
1:59:30uplinkcoder Q: Can you draw in the light probe positions?
🗪
1:59:30uplinkcoder Q: Can you draw in the light probe positions?
🗪
1:59:30uplinkcoder Q: Can you draw in the light probe positions?
🗪
2:00:15Make EndLightingComputation() draw the light probes, introducing IsInDebugVoxDim()
2:00:15Make EndLightingComputation() draw the light probes, introducing IsInDebugVoxDim()
2:00:15Make EndLightingComputation() draw the light probes, introducing IsInDebugVoxDim()
2:07:18See our misplaced light probes
🏃
2:07:18See our misplaced light probes
🏃
2:07:18See our misplaced light probes
🏃
2:07:39Fix the position of the light probe drawing in EndLightingComputation()
2:07:39Fix the position of the light probe drawing in EndLightingComputation()
2:07:39Fix the position of the light probe drawing in EndLightingComputation()
2:09:52See our light probes, and consider the brightening to be due to a Z-discontinuity
🏃
2:09:52See our light probes, and consider the brightening to be due to a Z-discontinuity
🏃
2:09:52See our light probes, and consider the brightening to be due to a Z-discontinuity
🏃
2:11:36snubbykins Q: Should you gutter copy from the opposite / flipped sides of the octal mapping so the bilinear blend will blend correctly?6
🗪
2:11:36snubbykins Q: Should you gutter copy from the opposite / flipped sides of the octal mapping so the bilinear blend will blend correctly?6
🗪
2:11:36snubbykins Q: Should you gutter copy from the opposite / flipped sides of the octal mapping so the bilinear blend will blend correctly?6
🗪
2:12:50Make UpdateAndRenderWorld() vary the height of the light
2:12:50Make UpdateAndRenderWorld() vary the height of the light
2:12:50Make UpdateAndRenderWorld() vary the height of the light
2:14:35See no light popping
🏃
2:14:35See no light popping
🏃
2:14:35See no light popping
🏃
2:14:48Increase the height variance of the light in UpdateAndRenderWorld()
2:14:48Increase the height variance of the light in UpdateAndRenderWorld()
2:14:48Increase the height variance of the light in UpdateAndRenderWorld()
2:15:02See light popping as the light passes through probes
🏃
2:15:02See light popping as the light passes through probes
🏃
2:15:02See light popping as the light passes through probes
🏃
2:18:48Remove the light height varying code
2:18:48Remove the light height varying code
2:18:48Remove the light height varying code
2:18:58Call it for today
🗩
2:18:58Call it for today
🗩
2:18:58Call it for today
🗩