118 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			118 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
| [video member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Adding an Ambient Occlusion Pass" vod_platform=youtube id=-BNki3w_HEE annotator=Miblo]
 | |
| [0:01][Recap and set the stage for the day]
 | |
| [1:29][Run the game to see the lighting diamonds]
 | |
| [5:31][handmade_render_group.cpp: Make LightingTest() correctly sum the Dest->FrontEmitC]
 | |
| [5:55][Run the game to see the correctly summed colours]
 | |
| [6:08][handmade_render_group.cpp: Make LightingTest() account for the DistanceFalloff]
 | |
| [7:16][Run the game with DistanceFalloff and summation, and consider our way forward]
 | |
| [8:17][handmade_render_group.cpp: Make LightingTest() set DiffuseInner to 1.0f]
 | |
| [8:35][Run the game to see the flickering]
 | |
| [9:02][Determine to introduce the ability to add light sources]
 | |
| [12:27][handmade_platform.h: Add Emission to the textured_vertex struct]
 | |
| [14:11][Run the game to see that nothing bad happens]
 | |
| [14:30][handmade_render_group.cpp: Make PushQuad() and LightingTest() set the emission]
 | |
| [16:40][Run the game to see everything unlit]
 | |
| [16:47][handmade_render_group.cpp: Introduce PushLight()]
 | |
| [19:23][handmade_world_mode.cpp: Make UpdateAndRenderWorld() call PushLight()]
 | |
| [20:59][Run the game and see a cube light that is not emitting any light]
 | |
| [21:28][handmade_render_group.cpp: Make PushQuad() take Emission]
 | |
| [22:27][Run the game to see our emitting light, with less flickering, but that the light itself is not lit up]
 | |
| [24:55][handmade_render_group.cpp: Add a BreakHere in LightingTest() for the light]
 | |
| [25:58][Step in to LightingTest() and inspect the values for the light]
 | |
| [27:59][handmade_render_group.cpp: Make LightingTest() correctly set the FrontEmit]
 | |
| [28:35][Run the game to see our lit light]
 | |
| [29:18][handmade_render_group.cpp: Make LightingTest() iterate three times]
 | |
| [29:29][Run the game to see our much brighter scene, now with flutter]
 | |
| [30:03][handmade_render_group.cpp: Revert LightingTest() to perform one iteration]
 | |
| [30:10][Run the game and consider building a wall]
 | |
| [30:45][handmade_world_mode.cpp: Make AddStandardRoom() add a wall]
 | |
| [33:35][Run the game to see our wall]
 | |
| [35:56][handmade_render_group.cpp: Enable LightingTest() to compute the colours differently in the debug and game view]
 | |
| [39:24][Run the game to see the beautiful game view]
 | |
| [41:19][handmade_render_group.cpp: Consider gathering the light from the cubes' corners rather than their faces]
 | |
| [42:53][handmade_config.h: Add Global_Renderer_Lighting_ShowReflectors and Global_Renderer_Lighting_IterationCount]
 | |
| [45:08][win32_handmade.cpp: Try to add keys in Win32ProcessPendingMessages() to control the reflectors and lighting iteration count]
 | |
| [46:47][handmade_opengl.cpp: Prevent OpenGLRenderCommands() from calling ComputeLightTransport()]
 | |
| [47:12][win32_handmade.cpp: Increase the resolution in WinMain()]
 | |
| [47:34][Run the game to see that it's totally usable for lighting]
 | |
| [47:45][handmade.cpp: Add lighting controls to the debug system]
 | |
| [48:43][Run the game and try out those lighting controls]
 | |
| [49:53][Determine to compute the lighting hierarchically]
 | |
| [52:12][Consult the multipass shadowing algorithm[ref
 | |
|     site="NVIDIA Developer"
 | |
|     page="Chapter 14. Dynamic Ambient Occlusion and Indirect Lighting"
 | |
|     url="https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter14.html"]]
 | |
| [55:07][Run the game and consider the problem of shadowing]
 | |
| [57:10][Blackboard: Comparing reflectors, being an O(n³) problem]
 | |
| [58:51][Read 14.3 Indirect Lighting and Area Lights[ref
 | |
|     site="NVIDIA Developer"
 | |
|     page="Chapter 14. Dynamic Ambient Occlusion and Indirect Lighting"
 | |
|     url="https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter14.html"]]
 | |
| [1:00:26][Run the game and consider an iterative solution across multiple frames]
 | |
| [1:01:56][handmade_render_group.cpp: Start to enable LightingTest() to compute some shadowing]
 | |
| [1:03:57][Consult the disk-to-disk occlusion algorithm[ref
 | |
|     site="NVIDIA Developer"
 | |
|     page="Chapter 14. Dynamic Ambient Occlusion and Indirect Lighting"
 | |
|     url="https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter14.html"]]
 | |
| [1:05:32][handmade_render_group.cpp: Enable LightingTest() to compute the disk-to-disk occlusion[ref
 | |
|     site="NVIDIA Developer"
 | |
|     page="Chapter 14. Dynamic Ambient Occlusion and Indirect Lighting"
 | |
|     url="https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter14.html"]]
 | |
| [1:08:24][Blackboard: Shadow Approx.[ref
 | |
|     site="NVIDIA Developer"
 | |
|     page="Chapter 14. Dynamic Ambient Occlusion and Indirect Lighting"
 | |
|     url="https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter14.html"]]
 | |
| [1:19:58][A mini rant on papers giving partial solutions]
 | |
| [1:22:06][Consider what their saturate function is meant to be doing[ref
 | |
|     site="NVIDIA Developer"
 | |
|     page="Chapter 14. Dynamic Ambient Occlusion and Indirect Lighting"
 | |
|     url="https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter14.html"]]
 | |
| [1:26:31][Blackboard: Understanding their shadow approximation equation[ref
 | |
|     site="NVIDIA Developer"
 | |
|     page="Chapter 14. Dynamic Ambient Occlusion and Indirect Lighting"
 | |
|     url="https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter14.html"]]
 | |
| [1:29:25][handmade_render_group.cpp: Enable LightingTest() to compute this shadow approximation equation[ref
 | |
|     site="NVIDIA Developer"
 | |
|     page="Chapter 14. Dynamic Ambient Occlusion and Indirect Lighting"
 | |
|     url="https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter14.html"]]
 | |
| [1:32:08][handmade_intrinsics.h: Introduce ReciprocalSquareRoot()]
 | |
| [1:32:47][handmade_render_group.cpp: Continue to implement the shadow equation in LightingTest()[ref
 | |
|     site="NVIDIA Developer"
 | |
|     page="Chapter 14. Dynamic Ambient Occlusion and Indirect Lighting"
 | |
|     url="https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter14.html"]]
 | |
| [1:41:28][Blackboard: Occlusion from in front and behind]
 | |
| [1:41:46][handmade_render_group.cpp: Break out the shadow equation values in LightingTest()]
 | |
| [1:45:22][Correcting for occlusion by overlapping objects[ref
 | |
|     site="NVIDIA Developer"
 | |
|     page="Chapter 14. Dynamic Ambient Occlusion and Indirect Lighting"
 | |
|     url="https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter14.html"]]
 | |
| [1:46:43][handmade_render_group.cpp: Enable LightingTest() to iteratively occlude]
 | |
| [1:50:07][Run the game to see the shadowing looking kind of reasonable]
 | |
| [1:51:21][handmade_render_group.cpp: Make LightingTest() perform one shadowing iteration, and run the game to see that the wall's front face is not all black]
 | |
| [1:52:20][handmade_render_group.cpp: Move the Dest->Visibility setting one scope out in LightingTest()]
 | |
| [1:52:39][Run the game to see that the wall's front face is still black here]
 | |
| [1:53:51][handmade_render_group.cpp: Read carefully though the shadowing code in LightingTest()]
 | |
| [1:56:01][handmade_render_group.cpp: Add assertions in LightingTest() and compile in debug mode]
 | |
| [1:56:43][Run the game and fail to hit those assertions]
 | |
| [1:58:44][handmade_render_group.cpp: Assert in LightingTest() that the Visibility >= Dest->Visibility on the first iteration]
 | |
| [1:59:33][Run the game, hit that assertion and consider why]
 | |
| [2:00:37][handmade_render_group.cpp: Add a Shadow in LightingTest() to accumulate based on the Visibility]
 | |
| [2:04:42][Run the game to see our ambient occlusion solution]
 | |
| [2:05:20][Q&A][:speech]
 | |
| [2:06:43][@vkar2][square root (A/pi + r²) = square root (r² * ( A/(pi * r²) + 1) = r * square root (A/(pi * r²) + 1)]
 | |
| [2:07:31][Blackboard: Pulling the r out of square root (A/π + r²)]
 | |
| [2:10:36][@alexkelbo][Thank you very much for 400 days of programming. Had I remembered I would've sent you a golden crown to wear today. You're awesome!]
 | |
| [2:10:43][@mtsmox][What do extra iterations do for ambient occlusion? I understand it for bouncing light, but shadows?]
 | |
| [2:10:59][Blackboard: Calculating ambient occlusion over multiple iterations]
 | |
| [2:16:12][@mtsmox][Should the accumulator for the light passes be reset to zero at the start of the next pass?]
 | |
| [2:16:40][handmade_render_group.cpp: Make LightingTest() reset the accumulator]
 | |
| [2:17:50][Run the game to see the current lighting]
 | |
| [2:18:14][handmade_render_group.cpp: Make LightingTest() perform ambient occlusion]
 | |
| [2:18:55][Run the game to see how that looks with ambient occlusion]
 | |
| [2:20:50][handmade_config.h: Increase the Global_Renderer_Lighting_IterationCount and run the game to see how that looks]
 | |
| [2:22:22][@thesizik][It seems like the ground colors are off. Looks like it goes light green > gray > dark green]
 | |
| [2:24:24][handmade_render_group.cpp: Make LightingTest() cast the Element->Visibility calculation to a V4 in the setting of FrontEmit]
 | |
| [2:25:25][Run the game to see how that looks]
 | |
| [2:26:40][Wind it down][:speech]
 | |
| [/video]
 |