[video output=day574 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Experimenting with Voxel Filters" vod_platform=youtube id=NK8sJfl6o18 annotator=Miblo]
[0:01][Recap and set the stage for the day making the ray caster produce a stable set of inputs to pass to the light field interpolater, with thoughts on multiple light fields][:lighting :speech]
[5:25][Show the current state of the :lighting][:run]
[7:11][Show the current state of the :lighting, without filling in negative light values][:run]
[7:35][Consult our :lighting TODOs][:research]
[8:03][Show the absence of light flickering, thanks to our switch to floats][:lighting :run]
[9:02][Reorganise and consult our :lighting TODOs]
[9:28][Demo our need to flood fill the voxel so that unsampled portions get filled in from nearby samples][:filtering :lighting :run]
[12:03][Consider where is most appropriate to perform the flood filled interpolation][:filtering :lighting :speech]
[13:04][Consider whether or not the reconstructed edge :lighting values should persist across frames][:filtering :lighting :run]
[15:22][Consider our options for flood filling the :lighting voxel: 1) Persistently in lighting_solution; 2) In EndLightingComputation() when: a) pushing the cells to the graphics card each frame; b) accumulating light contribution over time][:filtering :research]
[19:13][Determine to make EndLightingComputation() flood fill the :lighting voxel when pushing the cells to the graphics card][:filtering :research]
[20:36][Seperable Filters][:blackboard :filtering]
[25:03][Cache implications of our light voxel[ref
    site=WikiChip
    page="Core i7-7700K - Intel"
    url=https://en.wikichip.org/wiki/intel/core_i7/i7-7700k]][:lighting :memory :research]
[30:44][Propose constraining our flood fill filter to cells predetermined to require :filtering][:filtering :lighting :memory :research]
[32:35][Abortively augment game_render_commands with a FloodIndices array][:filtering :lighting]
[35:54][Begin to make EndLightingComputation() flood fill the :lighting voxel with purple when pushing the cells to the graphics card, asserting that we're well inside the hot region][:filtering :lighting]
[38:17][Try unsuccessfully to trigger our hot region assertions][:filtering :lighting :run]
[39:02][Make EndLightingComputation() flood fill out to neighbour cells, introducing HasLight() and FloodLight()][:filtering :lighting]
[1:02:58][Directional Flood Filling][:blackboard :filtering :lighting]
[1:04:28][Fix FloodLight() to correctly fill in positive and negative directions, before welding its code in to EndLightingComputation()][:filtering :lighting]
[1:08:22][Check out our partially working flood filling][:filtering :lighting :run]
[1:08:52][Make EndLightingComputation() flood fill with purple][:"debug visualisation" :filtering :lighting]
[1:09:23][Check out our purple flood filling, and spot some erroneously unlit / interpolated areas][:filtering :lighting :run]
[1:10:28][Make CompileZBiasProgram() clamp the light to 0, introducing Clamp0Inf()[ref
    site="OpenGL Registry"
    page="The OpenGL Shading Language 1.50 Quick Reference Card"
    url=https://www.khronos.org/files/opengl-quick-reference-card.pdf]][:filtering :lighting]
[1:14:37][Still see dead zones][:filtering :lighting :run]
[1:15:49][Make CompileZBiasProgram() normalise the LightN][:filtering :lighting]
[1:16:12][Still see dead zones][:filtering :lighting :run]
[1:17:21][Prevent EndLightingComputation() from flood filling with purple][:"debug visualisation" :filtering :lighting]
[1:17:27][Still see dead zones][:filtering :lighting :run]
[1:17:46][Toggle on the purple in EndLightingComputation()][:"debug visualisation" :filtering :lighting]
[1:17:48][Change HasLight() to base its decision on LightC, rather than LightN][:filtering :lighting]
[1:18:22][Still see dead zones][:filtering :lighting :run]
[1:19:13][Make EndLightingComputation() flood fill with yellow the cells that have light][:"debug visualisation" :filtering :lighting]
[1:19:49][Find that all cells are lit either purple or yellow][:"debug visualisation" :filtering :lighting :run]
[1:20:11][Comment out the yellow in EndLightingComputation()][:"debug visualisation" :filtering :lighting]
[1:20:18][See our dead zones return][:filtering :lighting :run]
[1:20:45][Make HasLight() less permissive with a threshold][:filtering :lighting]
[1:21:50][See our dead zones flood to purple (i.e. unlit)][:filtering :lighting :run]
[1:22:36][Toggle off the purple in EndLightingComputation()][:"debug visualisation" :filtering :lighting]
[1:23:00][Check out the interpolation across the light boundaries][:filtering :lighting :run]
[1:23:40][Scrutinise the directional flood fill interpolation code in EndLightingComputation()][:filtering :lighting :research]
[1:25:12][Directional Flood Fill Interpolation][:blackboard :filtering :lighting]
[1:26:33][Scrutinise the light value lookup and clamping in CompileZBiasProgram()][:filtering :lighting :research]
[1:28:41][Closely look at the apparent interpolation bug][:filtering :lighting :run]
[1:30:19][Make EndLightingComputation() flood fill purple if the LightWeight is 0][:"debug visualisation" :filtering :lighting]
[1:30:42][See some erroneously purple areas][:filtering :lighting :run]
[1:31:31][Scrutinise EndLightingComputation() for gather bugs][:filtering :lighting :research]
[1:32:12][Closely look at the erroneously purple areas][:filtering :lighting :run]
[1:32:41][Remove the threshold from HasLight() and ensure that EndLightingComputation() can blend down to 0][:filtering :lighting]
[1:34:35][Still see our interpolation artifacts][:filtering :lighting :run]
[1:36:10][Toggle off the final flood filling in EndLightingComputation()][:filtering :lighting]
[1:36:23][Still see our interpolation artifacts][:filtering :lighting :run]
[1:36:58][Try making EndLightingComputation() regularise our light normals][:filtering :lighting]
[1:37:20][See no interpolation bugs][:filtering :lighting :run]
[1:37:50][Toggle on the final flood filling in EndLightingComputation()][:filtering :lighting]
[1:38:06][See some very bizarre half-lit artifacts][:filtering :lighting :run]
[1:39:19][Investigate our half-lit artifacts][:filtering :lighting :research]
[1:40:26][Toggle off the whole flood filling code in EndLightingComputation()][:filtering :lighting]
[1:40:40][Check out our :lighting without flood filling, and spot some discontinuity across a wall][:filtering :run]
[1:41:29][Try making EndLightingComputation() regularise our light normals as 0, 0, 1][:filtering :lighting]
[1:42:04][Find that this doesn't help us][:filtering :lighting :run]
[1:42:11][Try making EndLightingComputation() regularise our light normals as 0, -1, 0][:filtering :lighting]
[1:42:23][Find that our discontinuity has gone][:filtering :lighting :run]
[1:42:33][Let EndLightingComputation() compute each voxel's normal][:filtering :lighting]
[1:42:44][Wonder if the discontinuity is due to the normal interpolation being unable to properly swing][:filtering :lighting :run]
[1:42:57][Make CompileZBiasProgram() visualise the normal][:"debug visualisation" :filtering :lighting]
[1:44:11][Determine that we are getting a 0, 0, 0 normal][:filtering :lighting :run]
[1:44:51][Prevent CompileZBiasProgram() from normalising the normal][:filtering :lighting]
[1:45:13][Find that the hard-edged 0, 0, 0 normal remains][:filtering :lighting :run]
[1:45:21][Make GetIrradiance() in CompileZBiasProgram() always visualise the normals][:"debug visualisation" :filtering :lighting]
[1:46:34][Find that the hard-edged 0, 0, 0 normal is gone][:filtering :lighting :run]
[1:46:51][Explain the problem when the light and world normals are orthogonal][:filtering :lighting :research]
[1:47:43][Make GetIrradiance() in CompileZBiasProgram() modify its result by the LightDC, and not visualise the normal][:filtering :lighting]
[1:48:16][Find that our discontinuity remains][:filtering :lighting :run]
[1:48:44][Make GetIrradiance() in CompileZBiasProgram() visualise the normal, modified by the LightDC][:"debug visualisation" :filtering :lighting]
[1:49:29][Find that our discontinuity remains][:filtering :lighting :run]
[1:49:58][Make GetIrradiance() in CompileZBiasProgram() visualise the LightDC][:"debug visualisation" :filtering :lighting]
[1:50:36][See our discontinuity][:filtering :lighting :run]
[1:50:49][Ponder our discontinuity][:filtering :lighting :research]
[1:51:50][Disable trilinear interpolation in OpenGLInit()][:hardware :lighting :rendering]
[1:52:20][Check out our non-interpolated LightDC][:filtering :lighting :run]
[1:53:20][Scrutinise GetIrradiance()][:filtering :lighting :research]
[1:54:27][Make GetIrradiance() in CompileZBiasProgram() visualise the normal][:"debug visualisation" :filtering :lighting]
[1:54:55][See smooth interpolation][:filtering :lighting :run]
[1:55:01][Make CompileZBiasProgram() visualise just the normal, without the textures][:"debug visualisation" :filtering :lighting]
[1:55:25][Check out our normals, with no – or at least less – discontinuity][:"debug visualisation" :filtering :lighting :run]
[1:57:30][Let CompileZBiasProgram() use the textures and not visualise the normals][:"debug visualisation" :filtering :lighting]
[1:57:39][Check out our discontinuity][:filtering :lighting :run]
[1:58:03][Temporarily make CompileZBiasProgram() hard set the LightDC to 0.5][:filtering :lighting]
[1:58:22][Find that our discontinuity has gone][:filtering :lighting :run]
[1:59:25][Let CompileZBiasProgram() gather in some light from perpendicular sources][:filtering :lighting]
[1:59:52][Find that our discontinuity has really gone][:filtering :lighting :run]
[2:01:10][Re-enable the flood filling code in EndLightingComputation()][:filtering :lighting]
[2:01:29][See that our flood filling brightens the light][:filtering :lighting :run]
[2:01:48][Prevent EndLightingComputation() from hard setting the normal to 0, 0, 1][:filtering :lighting]
[2:02:30][See that our flood filling fills in some areas][:filtering :lighting :run]
[2:03:23][Take a close look at our flood filling][:filtering :lighting :run]
[2:04:29][Respecify HasLight() as a smoothly varying GetLightAmount() for EndLightingComputation() to use as a multiplier][:filtering :lighting]
[2:07:58][Find that our flood fill's popping artifacts have been fixed][:filtering :lighting :run]
[2:08:47][Make SpamVoxel() spam out to all voxel slices][:filtering :lighting]
[2:09:27][Check out the spamming (with flood filling)][:filtering :lighting :run]
[2:09:58][Toggle off the flood filling in EndLightingComputation()][:filtering :lighting]
[2:10:08][Check out the spamming (without flood filling)][:filtering :lighting :run]
[2:11:17][Find that the spamming does not capture negative light properly in the outdoor area][:filtering :lighting :run]
[2:11:38][Prevent SpamVoxelSlice() from clamping the light's distance falloff to 0 to 1][:filtering :lighting]
[2:11:57][See that we're still not getting negative light interpolation][:filtering :lighting :run]
[2:12:50][Prevent EndLightingComputation() from clamping the light values][:filtering :lighting]
[2:13:53][See that we're still not getting negative light interpolation][:filtering :lighting :run]
[2:14:24][Scan the code for any more 0-clamping][:filtering :lighting :research]
[2:15:40][Make CompileZBiasProgram() draw negative values in red][:"debug visualisation" :filtering :lighting]
[2:16:22][See no negative values][:filtering :lighting :run]
[2:16:44][Scan the code for any more 0-clamping][:filtering :lighting :research]
[2:18:06][Add an assertion in SpamVoxelSlice that LightDF >= 0.0f][:filtering :lighting]
[2:18:37][Fail to hit that assertion][:filtering :lighting :run]
[2:18:43][Scrutinise the LightDF calculation in SpamVoxelSlice()][:filtering :lighting :research]
[2:20:50][:Run the game afresh and successfully hit our assertion in SpamVoxelSlice()][:filtering :lighting :run]
[2:20:53][Comment out the assertion in SpamVoxelSlice()][:filtering :lighting]
[2:21:07][Take another look at our non-interpolation of negative light][:filtering :lighting :run]
[2:21:44][Make TestCastFromProbes() fall-off the light more steeply][:filtering :lighting]
[2:21:57][Admire our steeper light falloff, and wonder where our stair-step pattern is coming from][:filtering :lighting :run]
[2:23:03][Prevent CompileZBiasProgram() from drawing negative values in red][:"debug visualisation" :filtering :lighting]
[2:23:12][Consider our entire falloff to not be that smooth][:filtering :lighting :run]
[2:23:35][Try making SpamVoxelSlice() set the light's alpha to the LightDF squared][:filtering :lighting]
[2:24:33][Admire our ring of light falloff][:filtering :lighting :run]
[2:24:51][Make SpamVoxelSlice() preserve the sign of the LightDF][:filtering :lighting]
[2:25:03][Check out our hard light falloff][:filtering :lighting :run]
[2:25:18][Try making SpamVoxelSlice() set the light's alpha to the LightDF square-root][:filtering :lighting]
[2:25:32][Check out our hard light falloff][:filtering :lighting :run]
[2:25:38][Revert SpamVoxelSlice() to setting the light's alpha to the LightDF][:filtering :lighting]
[2:25:51][Check out our hard light falloff][:filtering :lighting :run]
[2:26:04][Determine that we are doing ShaderSimTexWriteSRGB][:filtering :lighting :research]
[2:27:45][Temporarily prevent CompileZBiasProgram() from square-rooting the SurfaceReflect][:filtering :lighting]
[2:28:12][See that our light falloff is much smoother][:filtering :lighting :run]
[2:28:29][Revert CompileZBiasProgram() to square-rooting the SurfaceReflect, and try making SpamVoxelSlice() set the LightDist to LightN squared][:filtering :lighting]
[2:29:32][See a bizarrely octagonal light falloff][:filtering :lighting :run]
[2:29:41][Our problem: The falloff interpolation is being interpreted linearly][:filtering :lighting :research]
[2:31:13][Revert SpamVoxelSlice() to not square the LightN, and instead make GetIrradiance() in CompileZBiasProgram() square the LightV when setting the LightColor, introducing Square()][:filtering :lighting]
[2:32:53][Make SpamVoxelSlice() square the LightN when setting the LightDist, and GetIrradiance() in CompileZBiasProgram() preserve the sign[ref
    site="OpenGL Registry"
    page="The OpenGL Shading Language 1.50 Quick Reference Card"
    url=https://www.khronos.org/files/opengl-quick-reference-card.pdf]][:filtering :lighting]
[2:35:12][See our brighter light][:filtering :lighting :run]
[2:36:30][Fix the sign-preservation in GetIrradiance() in CompileZBiasProgram()][:filtering :lighting]
[2:36:44][See our falloff][:filtering :lighting :run]
[2:37:13][Make SpamVoxelSlice() square-root the LightC0, introducing SignedSquareRoot()][:filtering :lighting]
[2:38:23][Admire our softer falloff][:filtering :lighting :run]
[2:38:38][Make TestCastFromProbes() fall-off the light more gradually][:filtering :lighting]
[2:39:03][Admire our softer, yet wobbly falloff][:filtering :lighting :run]
[2:39:36][Make TestCastFromProbes() darken the LightC][:filtering :lighting]
[2:39:45][Admire our darker light, but doubt that the falloff is softer][:filtering :lighting :run]
[2:41:00][Make TestCastFromProbes() further darken the LightC][:filtering :lighting]
[2:41:03][Admire our darker light][:filtering :lighting :run]
[2:41:26][Toggle off the square-rooting / squaring][:filtering :lighting]
[2:42:03][Check out our less gradual light falloff][:filtering :lighting :run]
[2:42:52][Make TestCastFromProbes() brighten the LightC][:filtering :lighting]
[2:43:04][Check out our brighter and less gradual light falloff][:filtering :lighting :run]
[2:44:16][Q&A][:speech]
[2:44:49][@cemuzunlar][Q: Solution->HasCornerI.x + X + 2*dZ]
[2:45:10][Fix typo in EndLightingComputation() and toggle on the flood filling][:filtering :lighting]
[2:45:25][Check out the blotchy flood filling][:filtering :lighting :run]
[2:46:15][Toggle off flood filling][:filtering :lighting]
[2:46:23][Consider our flood filling not to be close to working][:filtering :lighting :run]
[2:47:04][@0lpbm][Damn, it wasn't that][:filtering :lighting]
[2:48:29][Wrap it up][:speech]
[/video]
