[video output=day609 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Reducing Light Contributions from Inaccessible Voxels" vod_platform=youtube id=yZnBUU-pQKE annotator=Miblo]
[0:01][Welcome to the stream, having dreamt up the source of our current bug[ref
    author="Casey Muratori"
    title="Regarding today's @handmade_hero, I was just taking a nap on the sofa and realized what the bug in the debug drawing code was. Like I said on stream, it's an indexing error (it always is). Hint for those who haven't found it yet"
    publisher=Twitter
    url=https://twitter.com/cmuratori/status/1269778778806312960]][:speech]
[1:58][Demo our nonsensical light direction bug, even in the old AABB raytracer][:"debug visualisation" :lighting :run]
[3:47][Walk through DebugDrawOctahedralValues()][:"debug visualisation" :lighting :research]
[5:12][Fix DebugDrawOctahedralValues() to correctly index in to the SpecAtlas][:"debug visualisation" :lighting]
[5:43][Our octahedral maps all now point at our light source][:"debug visualisation" :lighting :run]
[6:14][Decrease the line length scaling factor in DebugDrawColorDir() from 1 to 0.15][:"debug visualisation" :lighting]
[6:40][Admire our octahedral map :lighting directions][:"debug visualisation" :run]
[7:19][Let GenerateRoom() add lamps again][:lighting :"procedural generation"]
[7:38][Check out our octahedral map :lighting directions][:"debug visualisation" :run]
[9:18][Make GenerateRoom() increase the lamps' light intensity][:lighting :"procedural generation"]
[10:46][Check out our octahedral map :lighting directions, and consider increasing the casting density of our rays][:"debug visualisation" :run]
[14:01][Enable LIGHTING_USE_GRID][:lighting]
[14:26][Our octahedral map :lighting directions exhibit a positive feedback loop][:"debug visualisation" :run]
[15:00][Determine to debug the grid ray caster from the perspective of a :lighting quality pass][:speech]
[17:16][Make UpdateAndRenderWorld() call UpdateLighting() when we press F9][:"input handling" :lighting]
[17:38][Step the :lighting frame-by-frame with F9][:"debug visualisation" :"input handling" :run]
[19:04][Temporarily prevent GenerateRoom() from adding lamps][:lighting :"procedural generation"]
[19:22][Step the :lighting and see the light leaking through the wall][:"debug visualisation" :"input handling" :run]
[21:25][Temporarily prevent UpdateAndRenderEntities() from drawing occluders][:"entity system" :rendering]
[22:21][Octahedral maps embedded in geometry see lots of light][:"debug visualisation" :"input handling" :run]
[24:09][Disable LIGHTING_USE_GRID][:lighting]
[24:20][Octahedral maps embedded in geometry do not see lots of light][:"debug visualisation" :"input handling" :run]
[26:09][Temporarily make UpdateAndRenderEntities() draw occluders as outlines][:"entity system" :rendering]
[27:05][Check out our occluder outlines][:"entity system" :rendering :run]
[27:13][Reduce the thickness of our occluder outlines][:"entity system" :rendering]
[27:28][Check out our occluder outlines, step the :lighting and consider how to treat rays embedded in geometry][:"debug visualisation" :"entity system" :rendering :run]
[30:08][Determine to try zeroing out rays embedded in geometry][:lighting :run]
[30:52][Let UpdateAndRenderWorld() call UpdateLighting() every frame, and enable LIGHTING_USE_GRID][:lighting]
[31:36][Watch our :lighting feed back][:run]
[32:05][Enable FullCast() to detect and handle rays embedded in geometry][:lighting]
[41:12][Our :lighting feeds back more slowly][:run]
[41:48][Make UpdateAndRenderWorld() call UpdateLighting() when we press F9][:"input handling" :lighting]
[42:05][Step the :lighting to see embedded rays remain in the dark][:"debug visualisation" :"input handling" :run]
[43:03][Try to disable LIGHTING_USE_GRID, before leaving it enabled][:lighting]
[43:40][Determine to focus on light directional propagation][:lighting :run]
[43:56][Let UpdateAndRenderEntities() draw occluders like normal][:"entity system" :rendering]
[44:35][Step the :lighting to an attractive state][:lighting :run]
[45:11][Determine to address the light emanating from the underside of our floor][:lighting :run]
[47:00][Make DebugDrawOctahedralValues() draw the DiffuseAtlas][:"debug visualisation" :lighting]
[48:24][Check out our octahedral map :lighting directions into the DiffuseAtlas][:"debug visualisation" :run]
[51:40][Determine not to sample from obstructed light probes][:"debug visualisation" :lighting :run :sampling]
[53:23][@abnercoimbre][That's impressive!]
[53:52][Use the clear :lighting leakage to guide our debugging][:lighting :run]
[55:20][Determine to enable ComputeVoxelIrradianceAt() to mask out obstructed light probes][:lighting :research :sampling]
[56:27][Weighted Blend][:blackboard :lighting :mathematics]
[1:01:01][Flattening our recursive weighted blend equation][:blackboard :lighting :mathematics]
[1:04:29][How flattening the weighted blend equation helps us][:lighting :mathematics :research]
[1:08:00][Disable LIGHTING_USE_GRID and fix the resulting compile errors][:lighting]
[1:08:31][See the AABB raycasted :lighting][:run]
[1:08:41][Let UpdateAndRenderWorld() call UpdateLighting() every frame, and enable LIGHTING_USE_GRID][:lighting]
[1:08:55][Check the AABB raycasted :lighting][:run]
[1:09:18][Change the 2D Tiles array in ComputeVoxelIrradianceAt() to be 1D][:lighting :sampling]
[1:11:21][The :lighting results look the same][:run :sampling]
[1:11:44][Transform ComputeVoxelIrradianceAt() to blend the light using a weighted blend][:lighting :sampling]
[1:16:39][The :lighting results look the same][:run :sampling]
[1:17:09][Make ComputeVoxelIrradianceAt() take a set of Coefficients to omit tiles from the blend][:lighting :sampling]
[1:24:31][The :lighting results look the same][:run :sampling]
[1:25:31][Try making UpdateAndRenderEntities() omit the Green and Blue components of the occluders][:"entity system" :lighting :sampling]
[1:26:39][Check out the bounce :lighting][:run :sampling]
[1:27:07][Disable the moonlight in AABBRayCast()][:lighting :sampling]
[1:27:28][Our single-source bounce :lighting looks reasonable][:run :sampling]
[1:28:35][Try making AABBRayCast() omit all the left-side tiles from the GatherC][:lighting :sampling]
[1:29:10][That screwed up our :lighting][:run :sampling]
[1:29:31][Briefly eyeball the weights in ComputeVoxelIrradianceAt()][:lighting :research :sampling]
[1:30:40][Build in -Od]
[1:30:56][Step in to ComputeVoxelIrradianceAt() and inspect the W][:lighting :run :sampling]
[1:32:43][Prevent a divide-by-0 error in ComputeVoxelIrradianceAt()][:mathematics]
[1:33:37][Our :lighting is no longer screwed up][:run :sampling]
[1:34:48][Let AABBRayCast() instruct ComputeVoxelIrradianceAt() to gather light from all tiles][:lighting :sampling]
[1:34:58][See red fringing on the right side of the fall-off area][:lighting :run :sampling]
[1:36:18][Enable LIGHTING_USE_GRID and fix the resulting compile errors][:lighting]
[1:36:48][Our whole world is tinted red, indicating that the propagation occurs in secondary bounces][:lighting :run :sampling]
[1:37:03][Set up to prevent ComputeVoxelIrradianceAt() from :sampling obstructed light probes][:lighting]
[1:38:53][Preventing light propagation from obstructed light probes][:blackboard :lighting]
[1:41:41][Look into preventing ComputeVoxelIrradianceAt() from :sampling obstructed light probes][:lighting :research]
[1:42:55][Our eventual light propagation][:blackboard :lighting]
[1:44:25][Determine to classify surface obstruction based on the normal][:lighting :research]
[1:45:33][Deriving the surface normal from the SampleP][:blackboard :lighting]
[1:48:32][Make ComputeVoxelIrradianceAt() classify surface obstruction based on the normal][:lighting]
[1:51:08][Our obstructed octahedral :lighting directions are now zeroed out][:lighting :run]
[1:52:45][A few words on visualisation versus unit testing][:"debug visualisation" :lighting :run]
[1:56:27][Q&A][:speech]
[1:56:40][@mattiamanzati][Q: Is this the cube raycasting or the old AABB raycast?][:lighting]
[1:57:12][@x1bzzr][Q: Do you have any suggestions regarding how to study and better retain information? I remember you said you learned math only because you realized you needed to in order to program things. So particularly in relation to math, do you have any advice on how to learn in ways that are more efficient?][:mathematics]
[2:03:28][@krrsplat][Q: When you were building the weight table, why were the negative values 1-UVW.x instead of 0-UVW.x? Sorry if you already answered this, I tuned in late]
[2:04:30][@pragmascrypt][Q: The Nvidia paper you were using in the beginning was using depth info on the light probes to avoid light leaking. Is this something you also want to try?][:lighting]
[2:06:06][@billdstrong][Q: [@abnercoimbre Abner] said all the info was on the site. He had to go]
[2:06:38][Plug Handmade Seattle 2020[ref
    site="Handmade Seattle"
    url=https://www.handmade-seattle.com/]][:research]
[2:10:06][@erdomina][Q: Any thoughts on the Nanite Unreal engine demo?]
[2:11:08][@marchin7][Q: My common way to see math and programming is to see the sub-concepts of the concept I'm trying to learn. And do like a tree until I get to the "leafs" which are concepts I already know or axioms. Then I go upwards from there and try to specially understand the how and why of the concepts' connections. Works well for both programming and math][:mathematics]
[2:11:34][@billdstrong][Q: Could we just create a distance limit to stop bouncing light?][:lighting]
[2:12:11][@read_my_code][Q: In what way does a custom engine affect the feel of a game? Is it always a question of having better :performance allowing for more flexibility? I've always thought there's nothing you can't do in Unity or Unreal. It's just going to be slower][:"game engine"]
[2:15:41][The various feels of ColecoVision games[ref
    site=Wikipedia
    page=ColecoVision
    url=https://en.wikipedia.org/wiki/ColecoVision]][:"game engine" :research]
[2:19:44][@malfuri][I would argue it's not the fault of the engines, but rather lazy devs. You can roll a lot of things on your own in pre-made engines. You could even go some custom / pre-made hybrid][:"game engine"]
[2:22:47][@bommes][My opinion is that this issue of uncreative games arises mostly due to people wanting to earn money with the work they put in. The same happens in music, movies, writing]
[2:27:01][@philliptrudeau][Superhot did that]
[2:27:36][@miltondts][So to make a creative game, look at the constraints of Unity and Unreal, and specifically break them?]
[2:29:01][@long_march][@handmade_hero have you ever worked with HRTF based :audio, and do you have an opinion on it?]
[2:30:21][@teitv][Do you live under rock? What about Cyberpunk 2077, @handmade_hero?]
[2:33:28][Thank you, everyone][:speech]
[/video]
