[video output=day573 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Wiring Up Light Transport" vod_platform=youtube id=nTN1hqyp9JM annotator=Miblo]
[0:00][Welcome to the stream][:speech]
[0:40][Demo the current state of our blended and stably positioned light][:lighting :run]
[2:52][Set up to sample the voxel :lighting like in the pixel shader][:research]
[4:10][Begin to make ComputeVoxelIrradianceAt() sample the voxel :lighting, and introduce GetIrradiance(), both based on the CompileZBiasProgram() pixel shader][:sampling]
[6:23][Make ComputeVoxelIrradianceAt() take an Incidence query parameter, considering angular specularity][:lighting]
[8:50][Set up ComputeVoxelIrradianceAt() to sample vector 3s][:lighting :sampling]
[9:25][Change GetIrradiance() to take a LightColor directly][:lighting]
[10:11][Fix compile errors][:lighting :sampling]
[11:17][Embark on reimplementing OpenGL's texture() function in ComputeVoxelIrradianceAt()][:lighting :sampling]
[16:43][Voxel Sample][:blackboard :lighting :sampling]
[19:04][Make ComputeVoxelIrradianceAt() pick the correct voxels to sample from, introducing LookUpVoxelClamped()][:lighting :sampling]
[22:55][Make ComputeVoxelIrradianceAt() sample four light normals and colours from our light field, introducing TriLerp()][:lighting :sampling]
[26:23][Trilinear blending][:blackboard :lighting :sampling]
[27:00][Implement TriLerp()][:lighting :sampling]
[29:13][Implement LookUpVoxelClamped()][:lighting :sampling]
[31:36][Fix compile errors][:lighting :sampling]
[32:18][Make ComputeLightPropagationWork() pass the SampleD to ComputeVoxelIrradianceAt(), and consider doing the latter in SIMD][:lighting :sampling]
[34:28][Switch EndLightingComputation() to call our real ComputeLightPropagation()][:lighting :sampling]
[36:16][Hit an access violation error in ComputeLightPropagation()][:lighting :run :sampling]
[36:26][Switch ComputeLightPropagation() to operate single-threaded][:lighting :sampling]
[37:57][Hit an access violation error in ComputeLightPropagation()][:lighting :run :sampling]
[38:21][Restrict ComputeLightPropagationWork() to sample the one closest light, using GetLightLeafForP()][:lighting :sampling]
[39:21][See black][:lighting :run :sampling]
[39:47][See black in release mode][:lighting :run :sampling]
[40:00][Begin to investigate our blackness][:lighting :research :sampling]
[41:44][Step in to ComputeLightPropagationWork() and inspect the LightC][:lighting :run :sampling]
[42:51][Make EndLightingComputation() accumulate the :lighting always][:sampling]
[43:22][See our crazily lit scene][:lighting :run :sampling]
[44:00][See our crazily and briefly lit scene in release mode][:lighting :run :sampling]
[44:10][Make ComputeLightPropagationWork() only perform moonlight transfer][:lighting :sampling]
[45:11][See bright ambient light][:lighting :run :sampling]
[45:59][Fix ComputeLightPropagationWork() to correctly weight the :lighting][:sampling]
[48:38][See our ambient light darken][:lighting :run :sampling]
[48:51][Shift our MoonColor into the visible range in ComputeLightPropagationWork()][:lighting :sampling]
[50:16][Find that our location influences the ambient light][:lighting :run :sampling]
[51:42][Make ComputeLightPropagationWork() normalise the light direction][:lighting :sampling]
[52:56][Find that the ambient light looks more moonlight-y][:lighting :run :sampling]
[54:06][Let ComputeLightPropagationWork() perform the full light transfer][:lighting :sampling]
[54:17][Watch our :lighting blow up, possibly due to NaN][:run :sampling]
[55:04][Scrutinise ComputeLightPropagationWork()][:lighting :research :sampling]
[56:54][Debug our TransferPPS and LightP, introducing LooksFishy()][:lighting :sampling]
[59:05][Break in to ComputeLightPropagationWork() on a supposedly fishy LightP][:lighting :run :sampling]
[1:00:13][Debug our ProbeSampleP, not LightP][:lighting :sampling]
[1:00:23][Break in to ComputeLightPropagationWork() on a fishy TransferPPS][:lighting :run :sampling]
[1:04:42][Make SpamVoxelSlice() use the LightDF directly as the LightA, without boosting the intensity][:lighting :sampling]
[1:05:20][See black][:lighting :run :sampling]
[1:06:03][See black and then craziness, in release mode][:lighting :run :sampling]
[1:06:58][Make EndLightingComputation() normalise our light normals][:lighting :sampling]
[1:08:02][See crazy :lighting][:run :sampling]
[1:08:27][Consider clamping our light irradiance][:lighting :sampling :research]
[1:10:24][Try making EndLightingComputation() use a known stable normal][:lighting :sampling]
[1:11:07][See crazy :lighting with stable normals][:run :sampling]
[1:11:19][Try instead making EndLightingComputation() use a known stable colour][:lighting :sampling]
[1:12:59][See bizarre, but flicker-free :lighting][:run :sampling]
[1:13:11][Try also making EndLightingComputation() use a known stable normal][:lighting :sampling]
[1:13:27][See ordinary :lighting][:run :sampling]
[1:13:35][Let EndLightingComputation() pack the actual normals][:lighting :sampling]
[1:13:42][Traverse the world, trying to make sense of our normals][:lighting :run :sampling]
[1:15:02][Begin to investigate our weird colours and normals][:lighting :research :sampling]
[1:16:38][Prevent SpamVoxel() from spamming out to all the slices][:lighting :sampling]
[1:17:32][Consider our :lighting to be close to being good][:run :sampling]
[1:18:43][Switch EndLightingComputation() to call TestCastFromProbes()][:lighting :sampling]
[1:18:58][See our test cast :lighting, without flood-filling][:run :sampling]
[1:20:21][Add a switch in EndLightingComputation() for the known stable colour test][:lighting :sampling]
[1:21:38][See black][:lighting :run :sampling]
[1:21:55][Increase the LightC intensity eight-fold in TestCastFromProbes()][:lighting :sampling]
[1:22:04][See gapped :lighting][:run :sampling]
[1:22:32][Increase the LightC intensity in TestCastFromProbes() from 8 to 10][:lighting :sampling]
[1:22:48][See questionably gapped :lighting][:run :sampling]
[1:23:08][Restrict ComputeLightPropagationWork() to sample the one closest light, using GetLightLeafForP()][:lighting :sampling]
[1:23:24][See potentially sensible light][:lighting :run :sampling]
[1:24:02][Decrease the tIrradiancePreservation delay in EndLightingComputation()][:lighting :sampling]
[1:24:16][Check out our light][:lighting :run :sampling]
[1:24:30][Increase the tIrradiancePreservation delay in EndLightingComputation()][:lighting :sampling]
[1:24:52][Check out our light, with the determination to clean up our light encoding and perform flood filling to room edges][:lighting :run :sampling]
[1:27:33][Make IrradiancePack() encode our light to allow for "tailroom"][:lighting :sampling]
[1:32:51][Enable CompileZBiasProgram() to handle our light's new tailroom][:lighting :sampling]
[1:35:51][See more sane, but unfortunately shifting :lighting][:run :sampling]
[1:37:01][Encode our light in 16 bits, changing IrradiancePack() to return a 64-bit value][:lighting :sampling]
[1:41:33][See striped :lighting][:run :sampling]
[1:42:01][Fix OpenGLEndFrame() to submit a 16-bit texture for the :lighting][:sampling]
[1:42:29][Still see shifting :lighting][:run :sampling]
[1:42:59][Determine to figure out the light encoding later, and now submit it all as floats][:lighting :sampling]
[1:48:18][See non-shifting, but slower :lighting][:performance :run :sampling]
[1:49:03][Make CompileZBiasProgram() only sample one of the lights][:lighting :performance :sampling]
[1:49:24][See that our :lighting has sped back up][:performance :run :sampling]
[1:52:04][Plan our next steps for the :lighting: 1) Encoding; 2) Flood filling; 3) Voxel centering][:admin]
[1:54:12][Q&A][:speech]
[1:55:06][@letambourinroyal][Q: Remind us why you #define internal static][:language]
[1:58:48][@zrizi][Q: Hey master [@cmuratori Casey]. Is there a way to suggest / home \[hint\] the processor that a branch is likely / not likely taken? Goal is to help with branch prediction]
[2:01:05][@jelly_toast_][Q: I was watching an early stream where you said something along the lines of "I've never worked on a commercial compiler". So, have you ever worked on a non-commercial compiler or something of the sort?][:language]
[2:02:35][@overhaulhead][Q: Not relevant to today's episode but what C / C++ books do you recommend for a beginner?]
[2:02:53][@math_daemon_][Q: What's your guess on how much faster GPU trilinear :sampling is compared to CPU side? Also, could you not bounce the light on GPU side and be faster even on non RTX cards? What are the reasons against doing that? Is it just to keep complexity at [~hero Handmade Hero] scope?][:lighting :performance]
[2:05:24][@tbodt_][Q: It seems unlikely that Intel / AMD would change the default behavior of branch prediction, considering things like PGO and gcc __builtin_expect assume that behavior]
[2:06:00][@aidsjorb][Q: Have you considered the fact that if you just said [~hero Handmade Hero] had an :AI based :lighting solution you could say it was now done?]
[2:06:13][@x1bzzr][Q: I understand you're doing a unity build in [~hero Handmade Hero]. What is the meaning of internal in this scenario?][:language]
[2:06:46][@centhusiast][Q: Hi! I got contacted by two companies to work as a C programmer. One job on numerical computing and data visualization, and the other one on cryptography. They also wrote to me that they have a hard time in finding people who are interested in the low level-ish programming. Do you think it is because the majority of people use python, java script or high level languages? I guess there is always a job if someone can do C and a bit assembly]
[2:07:40][@x1bzzr][Q: When running Visual Studio with my executable as an argument I can't find the project properties window in which you would set #defines. Do you know why that happens?]
[2:08:08][@zrizi][Q: Just catching up on the show again. What do we have left, other than :lighting and actual gameplay?]
[2:10:12][@x1bzzr][Q: Which features of C++ do you think are conducive to performance oriented programming and which do you think are detrimental and should be avoided? I noticed that you use default arguments sometimes, for example][:language]
[2:11:02][@horrowind][Q: When adding the normals together, doesn't immediately normalizing after each add make the result dependent on the order of the vectors? I guess NOZ(NOZ(NOZ(a) + b) + c) != NOZ(NOZ(NOZ(c) + b) + a) is what I am saying. (I don't remember the exact routine where you did this.)]
[2:13:13][@centhusiast][Q: As you remember we talked about Valve's ACO shader compiler that is replacing LLVM. I heard that it reduces the shader compile time significantly compared to LLVM. They said that it is great for the open source graphic's driver on Linux]
[2:13:38][@morglod][Q: Do you track light energy?][:lighting]
[2:14:39][@tbodt_][Q: How is irradiance different from radiance?][:lighting]
[2:16:26][@ymm0][Radiance is per surface area per solid angle][:lighting]
[2:17:04][@psychomaniactv][No, different units][:lighting]
[2:18:12][@centhusiast][Q: Have you read [@nothings Sean Barrett]'s post on anti-aliasing?[ref
    author="Sean Barrett"
    title="How the stb_truetype Anti-Aliased Software Rasterizer v2 Works"
    url=http://nothings.org/gamedev/rasterize/]]
[2:19:11][Close it down][:speech]
[/video]
