[video output=day396 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Rendering Lighting Information from the Game" vod_platform=youtube id=erE0m3_7FbI annotator=Miblo]
[0:01][Recap and set the stage for the day]
[0:51][handmade_opengl.cpp and handmade_opengl.h: Rename UVStep to SourceUVStep everywhere CompileMultiLightDown()]
[3:06][Run the game and consider using different textures for the up and down sampling]
[3:54][handmade_opengl.cpp: Make TransferLight() in CompileMultiLightDown() use the reflection colour and enable ComputeLightTransport() to combine the colours with glBlendFunc()]
[8:33][Run the game to see that we're now seeing unlit dots, despite the scene being lit yellow by them]
[10:17][handmade_opengl.cpp: Reduce the colour intensity of the lights in CompileFakeSeedLighting() and run the game to see the scene's yellow light still not affecting the interior of the red and green light sources]
[12:04][handmade_opengl.cpp: Make TransferLight() in CompileMultiLightDown() reduce the amount of light transferred, running the game to see how that affects it]
[14:47][Run the game and describe exactly what we're expecting]
[15:32][handmade_opengl.cpp: Prevent TransferLight() in CompileMultiLightDown() from using the reflection colour]
[15:54][Run the game to see the red and green light sources being affected by each other]
[16:12][handmade_opengl.cpp: Make TransferLight() in CompileMultiLightDown() clamp the light transfer and run the game to see that]
[17:04][handmade_opengl.cpp: Make TransferLight() in CompileMultiLightDown() use the reflection colour again, and run the game]
[17:43][handmade_opengl.cpp: CompileFakeSeedLighting() increase the colour intensity of the lights, running the game to see how that affects it]
[19:10][Run the game and note the problem with the light bleeding]
[20:24][Consider creating a way to switch between game and test mode]
[23:03][handmade_opengl.cpp: Toggle off the lighting debug visualisation in OpenGLRenderCommands() and run the game]
[24:26][Prepare to enable lighting toggling]
[26:36][handmade_opengl.cpp: Make CompilePeelComposite() render the game at full brightness, preserving the directional lighting]
[29:02][Run the game to see the lit scene a lot more cleanly]
[29:40][handmade_opengl.cpp: Try to make CompileResolveMultisample() only blend with colours from above]
[31:19][Run the game to see that a lot of the blending has been eliminated]
[31:57][handmade_opengl.cpp: Flip the direction of the depth test in CompileResolveMultisample() and run]
[32:26][handmade_opengl.cpp: Back out those changes]
[32:58][Run the game and consider how to get everything into the lighting system]
[33:57][handmade_opengl.h: Describe the opengl_framebuffer struct, noting that we'll need some space to store the emitter]
[37:43][handmade_opengl.h: Extend opengl_framebuffer to contain multiple ColorHandle types]
[43:27][Blackboard: Emission Specification]
[46:11][handmade_opengl.h: Specify opengl_color_handle_type enum, noting the heavily increased write bandwidth required]
[51:13][handmade_opengl.cpp: Make CreateFramebuffer() and FreeFramebuffer() operate on multiple framebuffers]
[55:28][Run the game correctly]
[55:47][handmade_opengl.cpp: Make CreateFramebuffer() operate on OpenGLAllColorAttachments]
[59:06][Run the game to see it rendering just fine]
[59:58][handmade_opengl.cpp: Move the lighting code out of CompilePeelComposite()]
[1:02:52][Run the unlit version of the game]
[1:03:14][handmade_opengl.cpp: Replace deprecated gl_FragData in CompileFakeSeedLighting() and CompileMultiLightUp()[ref
    site="GitHub"
    page="HandmadeHero/cpp Issues"
    url="https://github.com/HandmadeHero/cpp/issues"]]
[1:08:07][Run the game to see that it looks fine, and close issue #9[ref
    site="GitHub"
    page="HandmadeHero/cpp Issues"
    url="https://github.com/HandmadeHero/cpp/issues"]]
[1:10:03][handmade_opengl.cpp: Propagate this gl_FragData replacement to all shaders]
[1:12:37][Rant on how things have to be named in GLSL]
[1:15:09][handmade_opengl.cpp: Rename colours]
[1:16:52][Run the game to see it working almost alright]
[1:17:19][handmade_opengl.cpp: Fix up the naming]
[1:19:56][Run the game to see it working correctly]
[1:20:16][handmade_opengl.cpp: Enable CompileZBiasProgram() to write light out to multiple textures]
[1:30:31][Run the game to see that we're good]
[1:30:34][handmade_opengl.cpp: Enable CompileResolveMultisample() and ResolveMultisample() to blend multiple light sources]
[1:39:45][Run the game to see that stuff going]
[1:39:51][handmade_opengl.cpp: Switch back to the game renderer, and run the game to see that's okay]
[1:40:21][handmade_opengl.cpp: Enable ComputeLightTransport() to override the ordinary texture with the surface emission buffer]
[1:42:56][Run the game and see nothing in the emission framebuffer]
[1:44:15][handmade_opengl.cpp: Hard set BlendUnitColor\[0\] in CompileResolveMultisample() to the surface emission buffer and run the game]
[1:46:41][handmade_opengl.cpp: Hard set BlendUnitColor\[0\] in CompileResolveMultisample() to factor in the CombinedNPL and run the game to see a Stephen's Sausage Roll-esque scene]
[1:47:39][handmade_opengl.cpp: Ensure that OpenGLInit() does not encode the lighting framebuffers as sRGB]
[1:50:15][Run the game and consider that the colours may be being decoded in sRGB space]
[1:50:48][handmade_opengl.cpp: Investigate why CompileResolveMultisample() is not writing out the emission buffer]
[1:54:10][handmade_opengl.cpp: Enable CompileResolveMultisample() to apply light from a wider radius]
[1:55:18][Run the game to see that it makes a difference]
[1:56:00][handmade_opengl.cpp: Toggle on the lighting debug visualisation in OpenGLRenderCommands() and the downward light transfer in ComputeLightTransport()]
[1:57:06][Run the game and see glowy hero]
[1:57:15][Q&A][:speech]
[1:59:25][@Miblo][We can set the spread of the emitter, but can we also set the direction of the spread?]
[1:59:44][Blackboard: Emitter vs sprite facing]
[2:01:32][@vaualbus][Why not doing a marathon stream in lighting? Maybe if doing so will be more productive as you remember what hack you have done, and maybe forget the next weekend]
[2:02:44][@napoleon89][Don't know if this is the right place, but with your assert macro, it could currently cause bugs if you place it inside and if / else that doesn't use curly braces. Adding an else to this macro could solve this]
[2:04:04][@psychomaniactv][I have been looking into compression schemes for skeletal animation data. Currently I have only implemented basic quantisation, but I would like to add curve fitting to the mix. Could you give me some pointers on this? If I were to use Catmull-Rom splines, what are some methods on estimating the error of a segment and finding a good split point? And how could I apply this stuff to quaternions?]
[2:04:38][@brruunnooo][Do you plan to allow sprites to use emit textures that could, for example, make eyes glow?]
[2:05:23][@chrysos42][Alternative if / else syntax?]
[2:06:50][@macielda][About the Nx Ny Lp0 Lp1 texture, is a 16-bit texture worse than a 32-bit in any way? I felt like you added Lp0 and Lp1 just because it wouldn't make much of a difference performance-wise? Is that true?]
[2:09:11][handmade_opengl.h: TODO(casey): Think about making only one opengl_color_handle_type store RGB]
[2:10:35][@alexkelbo][(Off-topic) I'm playing with the debug cycle counters. Is there a way to find out for how long Windows puts our process to sleep? I'm missing millions of cycles in my main loop[ref
    site="Casey's Blog"
    page="The Worst API Ever Made"
    url="https://mollyrocket.com/casey/stream_0029.html"]]
[2:12:54][@iwumbo_][How do you define a good API and a bad API, or do you have examples of very good APIs?[ref
    site="Casey's Blog"
    page="The Worst API Ever Made"
    url="https://mollyrocket.com/casey/stream_0029.html"]]
[2:21:03][A few words on compressing animation data]
[2:24:10][@fr0styninja][Speaking of, ever thought of releasing old talks you've done if you still have slides / notes and the like laying around?]
[2:24:48][Scan through archival slides for 'In-Depth 3D Exporter: Design and Implementation']
[2:26:36][Scan through archival slides for 'Character Animation Programming I']
[2:28:08][Scan through archival slides for 'Requirements for Real=time Geometry']
[2:28:25][Wrap it up][:speech]
[/video]
