[1:44][Recap and set the stage for the day with praise for RenderDoc][:speech]
[3:15][Note that lots of our time is spent doing the multisample resolve][:performance :rendering :speech]
[7:32][Configure our project in RenderDoc][:admin]
[8:42][Capture a frame in RenderDoc and consult the event timings to see that the multisample buffer took 10 times longer to resolve than to draw][:performance :rendering :run]
[10:54][The possible bandwidth cost of resolving our multisample buffer][:performance :rendering :run]
[14:16][Our best case solution: Resolve the multisample buffer independently of the depth peel][:performance :rendering :run]
[16:29][Demo ~Milton's new grid feature, but its smoothing bug][:blackboard]
[17:32][:Rendering requirements of Sprites vs Geometry][:blackboard]
[20:16][Demo some undesirable alpha blending when traversing stairs][:rendering :run]
[22:15][Consider two multisample resolves to may be necessary][:performance :rendering :run]
[24:00][Plan to render the sprites with depth peel in a separate pass, then composite in the geometry with two multisample resolves][:blackboard :performance :rendering]
[30:17][Segregating our sprites and geometry into separate buffers][:blackboard :performance :memory]
[33:28][Hesitate to impose this separation requirement on the renderer][:blackboard :library]
[35:31][Producing a separate multisample buffer of the edge information][:blackboard :performance :rendering]
[36:52][The edge information in question][:performance :rendering :run]
[38:53][Using conservative rasterization to enable recovery of our edge blend from a single high- / low-coverage multisample resolve][:performance :rendering :run]
[43:48][Using conservative rasterization just to tell us how much a pixel is covered by a primitive][:performance :rendering :run]
[1:17:53][NVIDIA request: When enabling conservative rasterization, let us set the SampleMask to the number of samples we want][:rendering :speech]
[1:19:08][Lament the tremendous amount of bandwidth required to smooth out our edges][:memory :rendering :speech]
[1:20:36][Reflect on the need for the multisample buffer to tell if primitives are coplanar][:rendering :run]
[1:21:40][Consider augmenting our Colour Pass shader to skip pixels whose prior pass produced a fully opaque pixel][:rendering :run]
[1:28:10][Make CompileResolveMultisample() set the gl_FragDepth of opaque pixels to 1.0f, enabling CompileZBiasProgram() to discard obscured pixels][:rendering]
[1:36:24][Capture a frame to see that depth sorting is still working, and our Colour Passes are now more efficient][:rendering :run]
[1:38:28][Switch to the non-multisampling fast path in CompileResolveMultisample()][:rendering]
[1:39:50][Capture a frame to see that our glDrawArrays() calls have sped up][:rendering :run]
[1:41:01][Options for creating our fast path in CompileResolveMultisample(): 1. Read from the previous depth peel and do not resolve opaque pixels; 2. Resolve into a separate "blend" buffer][:rendering :speech]
[1:43:30][Make CompileResolveMultisample() only blend non-opaque pixels][:rendering]
[1:44:42][Reacquaint ourselves with the final CompilePeelComposite() with a view to instead accumulating the colour as we go][:rendering :research]
[1:46:39][Introduce a MaskSampler in CompileResolveMultisample() to contain the opacity][:rendering]
[1:48:49][Crash the game under RenderDoc][:run]
[1:49:11][Hit a shader error "unable to find overloaded function texelFetch()"][:rendering :run]
[1:49:45][Fix CompileResolveMultisample() to fetch the Mask's texel from the 0th texture][:rendering]
[1:50:24][See that the multisampling is a little busted][:rendering :run]
[1:51:01][Just let CompileResolveMultisample() always blend, including some shader parser mayhem][:rendering]
[1:53:16][See that the multisampled artefacts are gone][:rendering :run]
[1:53:42][Make CompileResolveMultisample() initialise the samplers in the order in which they are passed to OpenGLLinkSamplers()][:rendering]
[1:56:56][Make OpenGLEndFrame() set the Mask for CompileResolveMultisample() to acquire pixel opacity, introducing a SinglePixelAllZeroesTexture][:rendering]
[2:07:05][See a few multisampling artefacts in there][:rendering :run]
[2:08:08][Quickly scrutinise our new Mask code][:rendering :research]
[2:09:18][Capture a frame to see that our second and fourth Colour Passes are not as expected][:rendering :run]
[2:10:01][Check the Mask test in CompileResolveMultisample()][:rendering :research]
[2:11:00][Take a close look at our first glDrawArrays() call, to see that our MaskSampler is 0×0 pixels][:rendering :run]
[2:12:57][Fix OpenGLInit() to correctly bind our SinglePixelAllZeroesTexture][:rendering]
[2:13:19][Capture a frame to see that our third Colour Pass drew much more than expected][:rendering :run]
[2:15:29][Make CompileResolveMultisample() set gl_FragDepth of opaque pixels][:rendering]
[2:16:46][Crash in RenderDoc][:run]
[2:17:11][Make CompileResolveMultisample() set BlendUnitColor of opaque pixels][:rendering]
[2:17:36][Battle with the shader parser][:rendering :programming :run]
[2:21:16][Prevent CompileResolveMultisample() from setting the BlendUnitColor of opaque pixels][:rendering]
[2:21:39][Capture a frame to see that we are still busted][:rendering :run]
[2:33:05][See that everything looks nice and smooth][:rendering :run]
[2:33:53][Reinsert our fast path in CompileResolveMultisample()][:rendering]
[2:34:06][See new MIP map anisotropic filtering artefacts][:rendering :run]
[2:34:44][Capture a frame to see that our third and fourth Colour Passes are not as free as expected][:rendering :run]
[2:35:11][Fix CompileResolveMultisample() to black out the BlendUnitColor of opaque pixels][:rendering]
[2:36:16][Capture a frame to see that our Colour Passes are way more efficient][:rendering :run]
[2:38:31][Q&A][:speech]
[2:38:38][@dithinas][Q: Are you exceeding the size of your buffer for the shader code text? The EOF error seems kind of suspicious]
[2:38:50][Make CompileResolveMultisample() record the shader string BufferSize][:language]
[2:39:42][See that the shader string is 3877 characters][:language :run]
[2:39:59][Increase the FragmentCode buffer size from 4096 to 16000][:language]
[2:41:04][Find that the shader parser is happy, with a few words on tooling][:language :run]
[2:43:33][@sagian2005][Q: Couldn't you just not define the dimension and let the compiler figure out the size?][:language]
[2:44:10][@letambourinroyal][Q: Why can’t you just run the preprocessor on the shaders, though?][:language]
[2:46:53][@dithinas][Q: Do you have any concept of like a string builder that you could use with your format string function to have it pass you back a string allocated from temp memory? It's a small thing, but you won't need to think / worry about that anymore][:"string manipulation"]
[2:48:06][@enyo_enev][Q: I think that Dual Depth Peeling.[ref
title="Order Independent Transparency with Dual Depth Peeling"
publisher="NVIDIA Corporation"
url=http://developer.download.nvidia.com/SDK/10/opengl/src/dual_depth_peeling/doc/DualDepthPeeling.pdf] This paper may be able to help you out, because I looked at their OpenGL code and it seems possible to resolve only once when you render to the screen. You can download the code and see. I am not sure. It is pure OpenGL. They have not enabled multisampling, however I think it is possible to work][:rendering]
[2:53:20][@samyuutsu][Q: Have you considered using RenderDoc directly to recompile the shaders at runtime during rapid development?]
[2:54:40][@eddiesutrecht][Q: Hi [@cmuratori Casey], some episodes ago you said you didn't understand why [@naysayer88 Jon] credited you on Braid, since you didn't do any work on it. But you wrote the collision detector, right? Maybe I misunderstood and it was about the rewind only]
[2:59:08][@vaualbus][Q: How you would implement in debug systems the way of changing also v3 / v4, values?][:"debug system"]
[2:59:56][@zrizi][Q: I just watched the video about sub-pixel :sampling for pixel art assets. Thank you for explaining it, was really good. I have two related questions, though: 1) When you viewed the sprite sheet you noticed that it’s not alpha pre-multiplied and kind of mentioned that it might be a problem. I was wondering why. 2) You mentioned that they don’t use MIP maps and that got me thinking… How should we produce MIPs for pixel art assets? Box-filtering would not work since that’s made for bilinear]
[3:02:44][@zrizi][Q: 1) You're right. But I think Unity's shaders were set up for point :sampling]
[3:03:47][@zrizi][Q: And thank you very much for the skin mesh video. I still have to watch it]
[3:04:00][Time for bed, with a plug of Molly Rocket's Discord channel[ref