[video output=day415 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Per-primitive Lighting Samples" vod_platform=youtube id=oCpUs_ALvz0 annotator=Miblo]
[0:08][Recap and set the stage for the day][:speech]
[3:42][Decrease the voxel resolution][:lighting :rendering]
[4:29][:Run the game to see our :lighting solution][:rendering]
[5:38][Increase the voxel resolution][:lighting :rendering]
[6:15][:Run the game to see our ruined :lighting][:rendering]
[7:17][Further increase the voxel resolution][:lighting :rendering]
[8:45][:Run the game to see that the :lighting is way too sparse][:rendering]
[10:04][Voxel Interpolation of :Lighting][:blackboard :rendering]
[13:29][Using a spatial query to reconstruct the :lighting sample locations][:blackboard :rendering]
[17:27][Reflect on the efficacy of this approach][:blackboard :lighting :rendering]
[20:43][Boundary problem][:blackboard :geometry]
[24:22][Specifying our ideal :lighting solution][:blackboard :rendering]
[27:03][Consider using :lighting samples directly][:blackboard :rendering]
[30:36][:Run the game to show how the reconstruction problem may go away][:lighting :rendering]
[31:41][Specifying :lighting sample locations per primitive][:blackboard :rendering]
[35:42][Begin to switch to specifying :lighting sample locations per primitive][:lighting :rendering]
[40:26][Add LightOffset and LightCount to textured_vertex and enable CompileZBiasProgram() to use these values, passing them right through using GLSL's "flat" interpolation qualifier[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"]][:hardware :lighting :rendering]
[50:22][Introduce SumLight() based on SumVoxelLight()][:hardware :lighting :rendering]
[54:35][:Run the game and note that we're still fine][:lighting :rendering]
[54:50][Describe structured :art, as introduced to [@cmuratori Casey] by Mike Biddlecombe][:"debug visualisation" :rendering :speech]
[57:03][Set up the :rendering pipeline to enable CompileZBiasProgram() to display Red, Green, Blue and White on the corners of each quad][:"debug visualisation" :rendering]
[1:06:48][:Run the game and note that we may have a bug][:lighting :rendering]
[1:08:25][Make CompileZBiasProgram() set the FragLightIndex and FragLightCount][:hardware :lighting :rendering]
[1:08:52][:Run the game and get slower and slower][:lighting :rendering]
[1:09:21][Investigate this slowdown][:lighting :rendering]
[1:13:16][Prevent CompileZBiasProgram() from setting any of the light][:lighting :rendering]
[1:13:36][:Run the game to determine that this loop was the problem][:lighting :rendering]
[1:13:53][Prevent CompileZBiasProgram() from fetching the next light index][:lighting :rendering]
[1:14:23][:Run the game to see that we're still wrong][:lighting :rendering]
[1:14:47][Try to hardcode LightCount to 4 in CompileZBiasProgram()][:lighting :rendering]
[1:14:58][:Run the game to determine that LightCount is not properly getting set to 4 always][:lighting :rendering]
[1:15:39][Read through the code looking for the potential culprit][:lighting :rendering]
[1:17:48][Determine to do some graphics debugging][:run]
[1:19:05][Make CompileZBiasProgram() clamp the LightCount to 4][:hardware :lighting :rendering]
[1:19:32][Capture a frame and find that we are still binding only one GL_UNSIGNED_SHORT array][:lighting :rendering :run]
[1:20:12][Fix CompileZBiasProgram() to correctly set the FragLightCount][:hardware :lighting :rendering]
[1:20:56][:Run the game and still see no data][:lighting :rendering]
[1:21:12][Trim down OutputLightingTextures() in preparation to excise voxels, augment lighting_element to contain PackIndex, and enable ExtractReflectorsFromQuads() to use that PackIndex][:lighting :rendering]
[1:28:16][:Run the game to see that this indeed doesn't work][:lighting :rendering]
[1:29:03][Temporarily make SumLight() in CompileZBiasProgram() output red][:"debug visualisation" :hardware :lighting :rendering]
[1:30:12][:Run the game to see red][:"debug visualisation" :lighting :rendering]
[1:31:19][Note that shader debugging isn't supported on newer Nvidia GPUs, as explained by @JamesWidman][:hardware :speech]
[1:32:26][Capture a frame to inspect our :lighting arrays, and note that ExtractLightingQuads() cannot do the remap][:rendering :run]
[1:39:23][Make ExtractLightingQuads() set the PackIndex from Vert0][:lighting :rendering]
[1:40:50][:Run the game][:lighting :rendering]
[1:41:03][Capture a frame and inspect the buffers from which the fragment shader is sampling][:hardware :lighting :rendering :run]
[1:44:44][Change FragLightIndex and FragLightCount from unsigned short to unsigned int][:hardware :lighting :rendering]
[1:45:27][:Run and freeze][:lighting :rendering]
[1:46:59][Make SumLight() clamp LightCount to 4][:hardware :lighting :rendering]
[1:48:46][Q&A][:speech]
[1:49:25][@artemidoras][Q: What texture file type will you use?]
[1:50:18][@AsafGartner][Q: Can you increase the font size in the calculator?][:admin]
[1:52:27][@artemidoras][Q: In what structure do you organize world objects?][:"entity system"]
[1:53:18][@0lpbm][Q: I think you missed an equals sign in one of the shaders when defining Inv<something> {1, 1, 1}]
[1:53:35][Make OutputLightingTextures() correctly set InvCelDim][:lighting :rendering]
[1:53:53][@desuused][Q: Any comments on using SQLite as a file format for a game?][:database]
[1:54:36][@Zilarrezko][Q: Man, isn't it weird how OpenGL is with how you have to interface with it to do things, like you send it a string and then you put two shaders together to make a program. It's like esoteric and stuff][:hardware]
[1:56:21][@merkelbe][Q: What percentage of the way through the game do you think you are?]
[1:56:35][@blind_br][Q: Curious question: Why f32 has a lower case F while F32Max has a upper case F?]
[1:56:46][@hholst80][Q: In what video index did you start with the discussion about using a 3-dimensional voxel for :lighting?]
[1:57:17][@vaualbus][Q: Could we just normalize the light count / index to 1 and use them to build a color? Maybe this allows us to see what value we see]
[1:57:39][Make CompileZBiasProgram() normalize the FragLightCount and FragLightIndex to 1][:hardware :lighting :rendering]
[1:59:57][:Run the game and see all yellow][:lighting :rendering]
[2:00:19][Change FragLightCount and FragLightIndex back to shorts][:hardware :lighting :rendering]
[2:00:43][:Run the game and still see bogus :lighting results][:rendering]
[2:02:11][@macielda][Q: Have you considered Cascaded Voxels (as in Cascaded Voxel Cone Tracing) as a data structure for [~hero Handmade Hero] :lighting samples?][:rendering]
[2:02:32][@davechat][Q: Have you ever seen the source code of a GPU :driver?]
[2:03:13][@vaualbus][Q: You have not run the light calculation][:lighting :rendering]
[2:04:21][@alexkelbo][Q: What kind of work did you do on the Intel :driver?]
[2:05:28][@blackpawnsc][Q: What kinds of things do you most enjoy coding and what things the least?]
[2:07:04][@vaualbus][Q: If you were coding for a console would you be able to debug the graphics part of it? Do they give GPU hardware info down to implementation details?][:hardware]
[2:08:12][@groggeh][Q: Do you normally comment more than you do for this stream? Your code is clean to look at, but it feels like at big companies they would eat you up for not documenting a lot more]
[2:12:03][@wofiel][Q: I work for a large company, but in a very research-y area. Honestly I feel like I have the best of both worlds]
[2:12:58][@hholst80][Q: I worked at Frostbite and I think you would fit right in]
[2:17:42][@everybitcounts][Q: Having worked in a few large companies, I've found the need for commenting code arises from disproportionate skill levels among the developers. Less skilled or less interested engineers tend to complain about uncommented code...]
[2:20:59][Wind it down][:speech]
[/video]
