[video output=day570 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Distinguishing Between Lights and Occluders" vod_platform=youtube id=_dVntlUp4eM annotator=Miblo]
[0:01][Demo the current state of our light probe-based ray cast :lighting][:run]
[1:59][:Lighting improvements: 1. Averaging across frames][:run]
[2:57][:Lighting improvements: 2. Real indirect bounce and convection][:run]
[3:34][:Lighting improvements: 3. How best to store and update our information][:run]
[8:22][Reacquaint ourselves with TestCastFromProbes()][:lighting :research]
[9:55][Reacquaint ourselves with ComputeLightPropagation()][:lighting :research :threading]
[10:49][Turn the lighting_work version of ComputeLightPropagation() into a ComputeLightPropagationWork() PLATFORM_WORK_QUEUE_CALLBACK][:lighting :threading]
[13:22][Prepare to update ComputeLightPropagationWork() to work with voxel-based :lighting][:research]
[17:51][Set up ComputeLightPropagationWork() to handle multiple light sources][:lighting]
[20:55][Continue to reacquaint ourselves with ComputeLightPropagationWork(), its stochastic spherical :sampling and ambient light][:lighting :research]
[23:53][Consider getting ambient light from the probes][:lighting]
[24:56][Continue to reacquaint ourselves with ComputeLightPropagationWork(), :sampling hits][:lighting :research]
[26:52][Set up ComputeLightPropagationWork() to sample from our voxel-based :lighting, removing light_probe_irradiance and introducing ComputeVoxelIrradianceAt()][:sampling]
[31:19][Make ComputeLightPropagationWork() call SpamVoxel() renaming the existing SpamVoxel() to SpamVoxelSlice()][:lighting]
[35:52][Clean up compile errors][:lighting]
[40:55][Set up ComputeLightPropagationWork() to compute falloff based on the light source position][:lighting]
[43:02][Make ComputeLightPropagationWork() weight the incoming light by its intensity and location][:lighting]
[46:11][Consider how to average higher fidelity :lighting with multiple light fields][:research]
[48:23][Make ComputeLightPropagationWork() initialise a consistent MoonP, and SpamVoxelSlice() and SpamVoxel() take a LightFalloff which may be 0.0f for the moon][:lighting]
[54:37][Introduce a stubbed out ComputeVoxelIrradianceAt()][:lighting]
[55:38][Traverse the world with the determination to put lights into the casting hierarchy][:lighting :run]
[56:29][Determine to distinguish between lights and occluders][:lighting :speech]
[57:59][Spatial Partitioning of Lights][:blackboard :geometry :lighting]
[1:03:17][Upgrade our lighting_box spatial hierarchy for gathering four lights and distinguish between lights and occluders, replacing its Emission and TextureIndex values with a LightBoxD array in lighting_solution][:"data structure" :geometry :lighting]
[1:11:41][Make PushOccluder() set IsLight to 0, and redo PushLight() based on that function instead setting IsLight to 1][:lighting]
[1:13:40][Fix compile errors in SplitBox() and UpdateAndRenderEntities()][:"entity system" :geometry :lighting]
[1:16:16][Make RayCast() conditionally set the HitEmission to 1.0 or 0.0f for lights and occluders respectively, with deep considerations on efficiency][:lighting]
[1:24:05][Find that all remains well][:lighting :run]
[1:24:23][Toggle on the PushLight() call in UpdateAndRenderWorld()][:lighting]
[1:25:12][Check out our pushed light, being occluded at the top of the hero's hop][:lighting :run]
[1:25:50][Set up TestCastFromProbes() to distinguish between lights and occluders][:lighting]
[1:27:10][Find that our light–occluder distinguishing does not work][:lighting :run]
[1:27:31][Enable IsTestCast in TestCastFromProbes() to highlight ray hits][:"debug visualisation" :lighting]
[1:30:06][Find that our light–occluder distinguishing now works][:lighting :run]
[1:31:17][Introduce GetSpatialLeafForP() to gather light from the spatial hierarchy][:geometry :lighting]
[1:38:29][Make TestCastFromProbes() call GetSpatialLeafForP(), and rename LightBoxP to LightBoxTargetP in lighting_solution][:"data structure" :geometry :lighting]
[1:41:04][Slightly rewrite GetSpatialLeafForP() to return a u32 rather than a lighting_box pointer][:geometry :lighting]
[1:42:39][Fix compile error in TestCastFromProbes()][:geometry :lighting]
[1:43:12][Determine to gather our light from the spatial hierarchy][:geometry :lighting :speech]
[1:43:47][Check out our uninitialised light][:geometry :lighting :run]
[1:43:59][Investigate why we saw the light move][:geometry :lighting :research]
[1:44:43][Consider our :lighting to be buggy][:geometry :run]
[1:45:02][Begin to enable BuildSpatialPartitionForLighting() to insert lights into the hierarchy, introducing InsertLight()][:geometry :lighting]
[1:52:21][Consider tabling our spatial hierarchy :lighting gather for tomorrow][:geometry :speech]
[1:53:55][Make BuildSpatialPartitionForLighting() fill LightBoxTargetP with the DebugLightP][:geometry :lighting]
[1:55:01][Verify that the LightBoxTargetP filling works][:geometry :lighting :run]
[1:55:09][Disable IsTestCast in TestCastFromProbes()][:"debug visualisation" :lighting]
[1:55:34][See our test :lighting, without the spatial hierarchy lookup][:geometry :run]
[1:55:56][Q&A][:speech]
[1:57:23][@0lpbm][Q: You're returning 0 instead of Result in the function you created to find the box][:geometry :lighting]
[1:57:45][Fix GetSpatialLeafForP() to return Result][:geometry :lighting]
[1:58:03][@ymm0][Q: Not sure how relevant, but the problem seems related to importance :sampling lights in Monte Carlo ray tracers][:lighting]
[1:59:43][@jessem3y3r][Q: What lessons did you learn from implementing [~hero Handmade Hero]'s debug inspection system?][:"debug system"]
[2:01:15][@jessem3y3r][Q: Yes! Follow up question incoming...]
[2:02:09][@devsigner][Q: Are there any :performance impacts to storing large arrays of data as static global constants?]
[2:04:10][@jessem3y3r][Q: Is a non-trivial part of the difficulty the inherent limitations of C (you originally had to implement various metaprogramming tooling) or is the ideal system you want just inherently complex?][:language]
[2:04:52][@panostrak][Q: Do you use OpenGL?]
[2:06:42][@0lpbm][Q: Will you add lights separately, or bundle it with other objects in the scene (like lamps, for example)?][:"entity system" :lighting]
[2:08:14][@berlin84][Q: Not a question, but just wanted to tell you. Lost two daughters (twins) due to a freak accident, and binging [~hero Handmade Hero] helped a lot with managing the loss during the hardest time. You help with more than you probably think]
[2:10:23][@jessef][Q: Do you think the current trend of dedicated ray tracing :hardware is the right way to go for GPUs solving the :lighting problem? Is there another route you would like to see?]
[2:14:36][@bulmanator][Q: I really like the platform and renderer setup you have. If your renderer needed to load files – for shaders or something, or had to allocate a lot of stuff – would you reimplement the platform specific functions in the renderer, or would you pass your platform :API struct to the renderer initialise and use the ones your main executable implemented?][:"file io" :library :memory]
[2:16:17][Wrap it up][:speech]
[/video]
