[video output=day653 member=cmuratori stream_platform=twitch stream_username=handmade_hero  project=code title="Adding a Filmic Response Curve" vod_platform=youtube id=4U33fh8Lj5w annotator=Miblo]
[0:00][Recap and set the stage for the day improving the quality of single bright light sources][:lighting :run]
[1:07][Decrease RayCount from 16 to 8 in GridRayCast()][:lighting :"procedural generation"]
[1:24][Smooth framerate with good light everywhere other than around small fast-moving light sources][:lighting :run]
[2:35][Diffuse gather looks quite good, and the flicker is good enough][:lighting :run]
[5:19][Consider writing light into overlapping probes as a forward pass][:lighting :run]
[7:26][Toggle on DebugDrawSpatialGrid() in UpdateLighting()][:"debug visualisation" :lighting]
[7:39][Our light source is lower than expected][:"debug visualisation" :lighting :run]
[8:27][Make AddPlayer() elevate the head light from 0 to 0.5][:lighting :"procedural generation"]
[9:10][Our light is higher up][:lighting :run]
[9:19][Make AddPlayer() elevate the head light from 0.5 to 1][:lighting :"procedural generation"]
[9:27][Our light is less square][:lighting :run]
[10:51][Toggle on DebugDrawOctahedralValues() in UpdateLighting()][:"debug visualisation" :lighting]
[11:01][Glimpse our spatial grid and octahedral values][:"debug visualisation" :lighting :run]
[11:05][Toggle off DebugDrawOctahedralValues() and DebugDrawSpatialGrid() in UpdateLighting()][:"debug visualisation" :lighting]
[11:12][Our light is still a bit square][:lighting :run]
[11:39][Make AddPlayer() decrease the head light's intensity from 0.5 to 0.25, and add the glove light][:lighting :"procedural generation"]
[11:55][Our glove light has a fair bit of lag, and it's still a bit square][:lighting :run]
[13:30][@nomad_pixel][Wait, I grabbed some water. Is this with tone mapping now?][:lighting]
[14:08][Make AddPlayer() elevate the glove light from 0 to 0.5][:lighting :"procedural generation"]
[14:30][Consider the possibility of repairing the squareness][:lighting :run]
[15:05][Consider doing filmic tone mapping[ref
    site="Krzysztof Narkowicz"
    page="ACES Filmic Tone Mapping Curve"
    url=https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/][ref
    site=Desmos
    page="Graphic Calculator"
    url=https://www.desmos.com/calculator][ref
        site="Filmic Games"
        page="Filmic Tonemapping Operators"
        url=https://web.archive.org/web/20160211234532/filmicgames.com/archives/75]][:lighting :research]
[29:55][Introduce ACESFilm()[ref
    site="Krzysztof Narkowicz"
    page="ACES Filmic Tone Mapping Curve"
    url=https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/] and remove IrradiancePack() and stale code from SumLight()][:lighting]
[34:03][Check out our "before tone mapping" :lighting][:run]
[34:17][Make the fragment shader in CompileZBiasProgram() call ACESFilm()][:lighting]
[35:37][Our light already looks a lot more dramatic, but still square][:lighting :run]
[37:27][Enable LIGHTS_ARE_SPHERES][:lighting]
[37:32][The lights dim, but remain square][:lighting :run]
[37:57][Disable LIGHTS_ARE_SPHERES][:lighting]
[38:04][Consider rasterising light into overlapped probes as a pre-pass][:lighting :run]
[41:13][@drzool][How about jittering the light probe positions?]
[42:20][Admire the :lighting besides the squareness][:run]
[43:54][Toggle off room lights in StandardLightingPattern()][:lighting :"procedural generation"]
[44:07][Admire the indirect :lighting with only one light source][:run]
[44:34][Increase RayCount from 8 to 64 in GridRayCast()][:lighting :"procedural generation"]
[44:52][The light now has very little flicker][:lighting :run]
[45:11][Decrease RayCount from 64 to 16 in GridRayCast()][:lighting :"procedural generation"]
[45:13][Consider rasterising light into overlapped probes as a pre-pass][:lighting :run]
[46:50][Toggle on DebugDrawOctahedralValues() in UpdateLighting()][:"debug visualisation" :lighting]
[46:52][Our light fall-off has a hard edge not explained by linear interpolation][:"debug visualisation" :lighting :run]
[49:29][Make SampleLighting() use a pure diffuse material][:lighting]
[50:00][Our diffuse map doesn't quite have the same problem][:lighting :run]
[50:21][Toggle off DebugDrawOctahedralValues() in UpdateLighting()][:"debug visualisation" :lighting]
[50:28][Our light is still more square than we'd like][:lighting :run]
[50:38][Make SampleLighting() use a pure specular material][:lighting]
[50:45][Our small moving light is very hard edged in the specular map][:lighting :run]
[50:56][Make DebugDrawOctahedralValues() draw the SpecAtlas values, toggling it on in UpdateLighting()][:"debug visualisation" :lighting]
[51:23][Our light probes pick up a far more gradual fall-off than appears][:"debug visualisation" :lighting :run]
[53:37][Reacquaint ourselves with SumLight()][:lighting :research]
[1:01:10][Check out our current light][:"debug visualisation" :lighting :run]
[1:01:22][Prevent SumLight() from shrinking LIGHT_LOOKUP_VOXEL_DIM by 1 when computing VoxR][:lighting]
[1:01:30][Our :lighting shifts][:run]
[1:02:57][Revert SumLight() to shrink LIGHT_LOOKUP_VOXEL_DIM by 1 when computing VoxR][:lighting]
[1:03:36][Hunt for a corresponding minus 1 in FullCast()][:lighting :research]
[1:06:19][The light fall-off's hardness is influenced by the reflection angle][:lighting :run]
[1:08:20][Make SampleLighting() use a pure diffuse material][:lighting]
[1:08:26][Check out our pure diffuse light][:lighting :run]
[1:09:53][Consider changing the interpolation of the octahedral map][:lighting :run]
[1:11:38][Introduce Mestre() for SumLight() to use][:lighting]
[1:19:07][Our light is more circular][:lighting :run]
[1:20:00][Toggle off DebugDrawOctahedralValues() in UpdateLighting()][:"debug visualisation" :lighting]
[1:20:10][Our more circular light is nicer, but maybe still not quite right][:lighting :run]
[1:21:27][Toggle on room lights in StandardLightingPattern()][:lighting :"procedural generation"]
[1:21:44][Our more circular light is better than the alternative][:lighting :run]
[1:22:59][@frizi09][I still believe this might be just an artifact of too low voxel resolution, and what we see is actually expected given the current constraints][:lighting]
[1:24:22][Comment out the Mestre() calls in SumLight()][:lighting]
[1:24:41][Our light looks great barring the squareness][:lighting :run]
[1:24:55][Determine to place a known point of light in the system][:lighting :research]
[1:26:30][Determine to make ComputeLightPropagationWork() further slice up the work for better :threading][:lighting]
[1:28:07][Make FullCast() hard set the TransferPPS of all light probes in a radial pattern][:lighting]
[1:31:34][Our light fall-off does not look radial][:lighting :run]
[1:31:56][Multiply the distance between the origin and light probe by 0.1 to try and prevent more distant probes from zeroing out][:lighting]
[1:32:05][Our light fall-off looks radial][:lighting :run]
[1:32:07][Multiply the distance between the origin and light probe by 0.25][:lighting]
[1:32:16][Our light fall-off looks more blocky][:lighting :run]
[1:33:38][Make the fragment shader in CompileZBiasProgram() remove a guessed 0.1 from the SurfaceReflect][:lighting]
[1:34:11][Our light is blown out][:lighting :run]
[1:34:20][Make the fragment shader in CompileZBiasProgram() clamp SurfaceReflect to 0][:lighting]
[1:35:11][Our light fall-off is now circular][:lighting :run]
[1:35:29][Decrease the SurfaceReflect light floor removal from 0.1 to 0.01][:lighting]
[1:35:41][Our light fall-off is a little blocky again][:lighting :run]
[1:35:48][Increase the SurfaceReflect light floor removal from 0.01 to 0.05][:lighting]
[1:36:02][Our light fall-off is circular][:lighting :run]
[1:36:18][Comment out the hardcoded TransferPPS in FullCast()][:lighting]
[1:36:29][Our light falls to black][:lighting :run]
[1:37:26][Comment out the SurfaceReflect light floor removal in the fragment shader][:lighting]
[1:37:36][Our light is back][:lighting :run]
[1:37:49][Check Clamp0Inf() for bugs][:lighting :research]
[1:38:08][Decrease the SurfaceReflect light floor removal from 0.05 to 0][:lighting]
[1:38:21][Our light remains][:lighting :run]
[1:38:26][Increase the SurfaceReflect light floor removal from 0 to 0.01][:lighting]
[1:38:35][Our light darkens considerably][:lighting :run]
[1:38:41][Decrease the SurfaceReflect light floor removal from 0.01 to 0.001][:lighting]
[1:38:50][Our light brightens somewhat][:lighting :run]
[1:39:07][Increase the SurfaceReflect light floor removal from 0.001 to 0.01][:lighting]
[1:39:19][Our light fall-off is very circular][:lighting :run]
[1:39:44][@leemyy][Considering this is supposed to be specular, I find it odd that the region at full brightness is so large][:lighting]
[1:39:57][Make SampleLighting() use a pure specular material][:lighting]
[1:40:04][Our specular light fall-off remains circular][:lighting :run]
[1:40:25][Make SampleLighting() use a pure diffuse material][:lighting]
[1:40:28][Applying a natural floor enables our light to fall off radially][:lighting :research]
[1:43:00][Decrease the SurfaceReflect light floor removal from 0.01 to 0.0001][:lighting]
[1:43:14][Our light fall-off is square again][:lighting :run]
[1:43:23][Increase the SurfaceReflect light floor removal from 0.0001 to 0.01][:lighting]
[1:43:33][Our light fall-off is circular, but the solution is too dark][:lighting :run]
[1:43:58][Remove the SurfaceReflect light floor removal][:lighting]
[1:44:18][@pfizzyenator][Is the ACESFilm() function contributing to the badness?][:lighting]
[1:44:27][The light with ACESFilm()][:lighting :run]
[1:44:33][Remove the ACESFilm() call][:lighting]
[1:44:46][The light without ACESFilm()][:lighting :run]
[1:44:55][Reinsert the ACESFilm() call][:lighting]
[1:45:02][The light with ACESFilm()][:lighting :run]
[1:45:27][Consider the light pretty reasonable][:lighting :run]
[1:47:00][Without flooring, linear interpolation won't cut it][:lighting :research]
[1:47:39][@frizi09][Would it be practical to up the voxel resolution a bit? Just to see the comparison][:lighting]
[1:48:38][Double the LIGHT_LOOKUP_VOXEL_DIM_X and LIGHT_LOOKUP_VOXEL_DIM_Y][:lighting]
[1:49:01][Our :lighting region is larger][:"debug visualisation" :run]
[1:49:23][Make UpdateLighting() halve the VoxCellDim in all dimensions][:lighting]
[1:50:04][Hit an out-of-bounds assert in GridBuildSpatialPartition()][:lighting :run]
[1:50:28][Make UpdateLighting() retain the full VoxCellDim in Z][:lighting]
[1:51:03][Hit an out-of-bounds assert in GridBuildSpatialPartition()][:lighting :run]
[1:51:33][Scour UpdateLighting() for sources of our out-of-bounds lookup][:lighting :research]
[1:52:22][Run an -Od build until hitting our IsInBounds() assertion in FlatIndexFrom()][:lighting :run]
[1:55:10][Investigate our IsInBounds() assertion hit in FlatIndexFrom()][:lighting :run]
[1:56:57][Remove the Z loops from GridBuildSpatialPartition()][:lighting]
[1:58:40][Run an -O2 build without asserting][:lighting :run]
[1:59:06][The light looks better, but with shiny :sampling errors][:lighting :run]
[1:59:47][Quadruple the LIGHT_LOOKUP_VOXEL_DIM_X and LIGHT_LOOKUP_VOXEL_DIM_Y and make UpdateLighting() quarter the VoxCellDim in X and Y][:lighting]
[2:00:16][Hit an OpenGL error][:lighting :run]
[2:00:26][Revert LIGHT_LOOKUP_VOXEL_DIM_X, LIGHT_LOOKUP_VOXEL_DIM_Y and VoxCellDim to their original values][:lighting]
[2:00:41][Consider bigger light sources to be our only option][:lighting :run]
[2:01:32][@frizi09][Bigger and slightly weaker light source could work there, though][:lighting]
[2:01:51][Our light is pretty good][:lighting :run]
[2:02:08][Make AddPlayer() increase the lights' size to 0.7 and decrease the brightness to 0.1][:lighting :"procedural generation"]
[2:02:48][Our moving lights are less square][:lighting :run]
[2:03:14][Uncomment the Mestre() calls in SumLight()][:lighting]
[2:03:37][Our moving lights are more radial][:lighting :run]
[2:03:52][Make AddPlayer() increase the lights' size to 1][:lighting :"procedural generation"]
[2:04:17][@pfizzyenator][How trivial is it to move to GPU?][:lighting]
[2:04:44][This bigger light actually looks square as the main light source outdoors][:lighting :run]
[2:07:00][Make AddPlayer() increase the lights' brightness to 0.5][:lighting :"procedural generation"]
[2:07:30][Our lights are blown out][:lighting :run]
[2:07:42][Reinstate the SurfaceReflect light floor removal of 0.01][:lighting]
[2:08:27][Our light fall-off is radial][:lighting :run]
[2:10:27][Rewrite the SurfaceReflect floor removal and ACESFilm() application][:lighting]
[2:10:54][Our light fall-off is radial][:lighting :run]
[2:11:03][Make StandardLightingPattern() increase the room lights' brightness to 0.5][:lighting :"procedural generation"]
[2:12:12][Patches of the solution fall to full darkness][:lighting :run]
[2:13:15][Make StandardLightingPattern() increase the room lights' brightness to 1][:lighting :"procedural generation"]
[2:13:32][Patches of the solution still fall to full darkness][:lighting :run]
[2:14:20][Revert the room lights' brightness to 0.05 in StandardLightingPattern(), and that of the head and glove lights to 0.1 in AddPlayer()][:lighting :"procedural generation"]
[2:15:03][Our light is dim but circular][:lighting :run]
[2:15:06][Decrease the SurfaceReflect light floor removal from 1 to 0][:lighting]
[2:15:19][Our light fall-off is square][:lighting :run]
[2:15:37][Try squaring the SurfaceReflect][:lighting]
[2:15:59][Our light fall-off is way less blocky][:lighting :run]
[2:16:19][Increase the SurfaceReflect multiplier from 100 to 1000][:lighting]
[2:16:24][Our light brightens a touch][:lighting :run]
[2:17:06][Partially revert the SurfaceReflect light floor removal to 0][:lighting]
[2:17:13][Our light fall-off is square][:lighting :run]
[2:17:38][Try to flatten the ACES filmic tone mapping curve[ref
    site="Krzysztof Narkowicz"
    page="ACES Filmic Tone Mapping Curve"
    url=https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/][ref
    site=Desmos
    page="Graphic Calculator"
    url=https://www.desmos.com/calculator]][:lighting :research]
[2:19:31][Try setting B to 0 in ACESFilm()][:lighting]
[2:19:44][Our light fall-off doesn't differ much][:lighting :run]
[2:20:05][Play with the ACES filmic tone mapping curve[ref
    site=Desmos
    page="Graphic Calculator"
    url=https://www.desmos.com/calculator]][:lighting :research]
[2:21:02][Try setting Z to 0.05 \[typo\] in ACESFilm()][:lighting]
[2:21:10][Our light fall-off remains square][:lighting :run]
[2:21:44][Revert ACESFilm()][:lighting]
[2:21:56][@pfizzyenator][I think you typed 0.05?][:lighting]
[2:22:04][Fix typo of Z from 0.05 to 0.5 in ACESFilm()][:lighting]
[2:22:06][Our light fall-off remains square][:lighting :run]
[2:23:22][Revert ACESFilm()][:lighting]
[2:24:02][Consider adding self-illumination and bloom, maybe leaving the square fall-off, removing 3D from the collision and adding gameplay rooms][:lighting :run]
[2:26:56][Enable LIGHTS_ARE_SPHERES][:lighting]
[2:27:22][Our light fall-off isn't materially different][:lighting :run]
[2:27:35][Disable LIGHTS_ARE_SPHERES][:lighting]
[2:27:41][Our light fall-off isn't materially different][:lighting :run]
[2:27:52][Decrease RayCount from 16 to 8 in GridRayCast()][:lighting :"procedural generation"]
[2:27:56][The light looks great][:lighting :run]
[2:28:51][Call it a day, with the determination to add bloom next time][:speech]
[2:29:10][@pfizzyenator][Framerate too high! Go back to 1 fps!]
[2:29:20][Thank you, everyone][:speech]
[2:30:21][@frizi09][We need an RTX ON comparison][:lighting]
[2:30:24][Thanks, everyone][:speech]
[/video]
