Handmade Hero»Episode Guide
Inverting the Full 3D Transform
?
?

Keyboard Navigation

Global Keys

[, < / ], > Jump to previous / next episode
W, K, P / S, J, N Jump to previous / next marker
t / T Toggle theatre / SUPERtheatre mode
V Revert filter to original state Y Select link (requires manual Ctrl-c)

Menu toggling

q Quotes r References f Filter y Link c Credits

In-Menu Movement

a
w
s
d
h j k l


Quotes and References Menus

Enter Jump to timecode

Quotes, References and Credits Menus

o Open URL (in new tab)

Filter Menu

x, Space Toggle category and focus next
X, ShiftSpace Toggle category and focus previous
v Invert topics / media as per focus

Filter and Link Menus

z Toggle filter / linking mode

Credits Menu

Enter Open URL (in new tab)
0:09Recap and set the stage for the day
0:09Recap and set the stage for the day
0:09Recap and set the stage for the day
3:05"This will be a stream filled with mucus"α
3:05"This will be a stream filled with mucus"α
3:05"This will be a stream filled with mucus"α
4:14handmade_debug.cpp: Consider how to enable DEBUGStart() to correctly place the debug text
4:14handmade_debug.cpp: Consider how to enable DEBUGStart() to correctly place the debug text
4:14handmade_debug.cpp: Consider how to enable DEBUGStart() to correctly place the debug text
6:53handmade_math.h: Make OrthographicProjection() set the near clip plane to be behind the camera
6:53handmade_math.h: Make OrthographicProjection() set the near clip plane to be behind the camera
6:53handmade_math.h: Make OrthographicProjection() set the near clip plane to be behind the camera
9:12Run the game to see that it's drawing okay, but that we cannot perform a debug click
9:12Run the game to see that it's drawing okay, but that we cannot perform a debug click
9:12Run the game to see that it's drawing okay, but that we cannot perform a debug click
10:56handmade_debug.cpp: Temporarily make DEBUGStart() shrink the debug text
10:56handmade_debug.cpp: Temporarily make DEBUGStart() shrink the debug text
10:56handmade_debug.cpp: Temporarily make DEBUGStart() shrink the debug text
11:38Determine to get Unproject() working again
11:38Determine to get Unproject() working again
11:38Determine to get Unproject() working again
13:22Run the game to see those pixel coordinates
13:22Run the game to see those pixel coordinates
13:22Run the game to see those pixel coordinates
14:00handmade_render_group.cpp: Look at how Unproject() currently works
14:00handmade_render_group.cpp: Look at how Unproject() currently works
14:00handmade_render_group.cpp: Look at how Unproject() currently works
15:08Blackboard: The Projection, Clip-space, Screen-space pipeline
15:08Blackboard: The Projection, Clip-space, Screen-space pipeline
15:08Blackboard: The Projection, Clip-space, Screen-space pipeline
19:53handmade_render_group.cpp: Prevent Unproject() from baking in the aspect ratio
19:53handmade_render_group.cpp: Prevent Unproject() from baking in the aspect ratio
19:53handmade_render_group.cpp: Prevent Unproject() from baking in the aspect ratio
21:47Blackboard: Inverting a matrix
21:47Blackboard: Inverting a matrix
21:47Blackboard: Inverting a matrix
25:44Blackboard: Producing the inverse of our projection matrix
25:44Blackboard: Producing the inverse of our projection matrix
25:44Blackboard: Producing the inverse of our projection matrix
30:35Blackboard: Check our working
30:35Blackboard: Check our working
30:35Blackboard: Check our working
35:32Blackboard: Producing the bottom row of the identity projection matrix
35:32Blackboard: Producing the bottom row of the identity projection matrix
35:32Blackboard: Producing the bottom row of the identity projection matrix
44:46Blackboard: Plug in those terms and see if that checks out
44:46Blackboard: Plug in those terms and see if that checks out
44:46Blackboard: Plug in those terms and see if that checks out
46:51handmade_render_group.cpp: Note that our projection matrix is slightly different
46:51handmade_render_group.cpp: Note that our projection matrix is slightly different
46:51handmade_render_group.cpp: Note that our projection matrix is slightly different
47:33Blackboard: Computing the inverse projection matrix for our actual matrix
47:33Blackboard: Computing the inverse projection matrix for our actual matrix
47:33Blackboard: Computing the inverse projection matrix for our actual matrix
49:38handmade_math.h: Introduce m4x4_inv struct and augment PerspectiveProjection() to produce both the Forward and Inverse matrices
49:38handmade_math.h: Introduce m4x4_inv struct and augment PerspectiveProjection() to produce both the Forward and Inverse matrices
49:38handmade_math.h: Introduce m4x4_inv struct and augment PerspectiveProjection() to produce both the Forward and Inverse matrices
53:56Step in to PerspectiveProjection() and inspect the resulting matrix
53:56Step in to PerspectiveProjection() and inspect the resulting matrix
53:56Step in to PerspectiveProjection() and inspect the resulting matrix
55:35Blackboard: Producing the identity orthographic projection matrix
55:35Blackboard: Producing the identity orthographic projection matrix
55:35Blackboard: Producing the identity orthographic projection matrix
1:01:05handmade_math.h: Augment OrthographicProjection() to produce both the Forward and Inverse matrices
1:01:05handmade_math.h: Augment OrthographicProjection() to produce both the Forward and Inverse matrices
1:01:05handmade_math.h: Augment OrthographicProjection() to produce both the Forward and Inverse matrices
1:02:15Step in to OrthographicProjection() and inspect the resulting matrix
1:02:15Step in to OrthographicProjection() and inspect the resulting matrix
1:02:15Step in to OrthographicProjection() and inspect the resulting matrix
1:03:01handmade_render_group.cpp: Set up SetCameraTransform() to compute both the Forward and Inverse matrices
1:03:01handmade_render_group.cpp: Set up SetCameraTransform() to compute both the Forward and Inverse matrices
1:03:01handmade_render_group.cpp: Set up SetCameraTransform() to compute both the Forward and Inverse matrices
1:04:42handmade_math.h: Determine to augment CameraTransform() to produce both the Forward and Inverse matrices
1:04:42handmade_math.h: Determine to augment CameraTransform() to produce both the Forward and Inverse matrices
1:04:42handmade_math.h: Determine to augment CameraTransform() to produce both the Forward and Inverse matrices
1:05:34Blackboard: Beginning to produce the identity camera matrix
1:05:34Blackboard: Beginning to produce the identity camera matrix
1:05:34Blackboard: Beginning to produce the identity camera matrix
1:06:24Blackboard: Isolating pieces of the matrix
1:06:24Blackboard: Isolating pieces of the matrix
1:06:24Blackboard: Isolating pieces of the matrix
1:10:13Blackboard: Producing the identity camera matrix
1:10:13Blackboard: Producing the identity camera matrix
1:10:13Blackboard: Producing the identity camera matrix
1:12:45Blackboard: Handling different length, yet still orthogonal axes
1:12:45Blackboard: Handling different length, yet still orthogonal axes
1:12:45Blackboard: Handling different length, yet still orthogonal axes
1:14:44handmade_math.h: Augment CameraTransform() to produce both the Forward and Inverse matrices
1:14:44handmade_math.h: Augment CameraTransform() to produce both the Forward and Inverse matrices
1:14:44handmade_math.h: Augment CameraTransform() to produce both the Forward and Inverse matrices
1:16:41Blackboard: Getting the inverse of a vector's own length
1:16:41Blackboard: Getting the inverse of a vector's own length
1:16:41Blackboard: Getting the inverse of a vector's own length
1:17:22handmade_math.h: Continue to augment CameraTransform()
1:17:22handmade_math.h: Continue to augment CameraTransform()
1:17:22handmade_math.h: Continue to augment CameraTransform()
1:18:08handmade_math.h: Introduce an operator/() that operates on vectors
1:18:08handmade_math.h: Introduce an operator/() that operates on vectors
1:18:08handmade_math.h: Introduce an operator/() that operates on vectors
1:19:41Blackboard: Producing our rightmost and bottom vectors for the identity camera matrix
1:19:41Blackboard: Producing our rightmost and bottom vectors for the identity camera matrix
1:19:41Blackboard: Producing our rightmost and bottom vectors for the identity camera matrix
1:22:31handmade_math.h: Enable CameraTransform() to compute our inverse components
1:22:31handmade_math.h: Enable CameraTransform() to compute our inverse components
1:22:31handmade_math.h: Enable CameraTransform() to compute our inverse components
1:25:50Step in to CameraTransform() and inspect the resulting matrix
1:25:50Step in to CameraTransform() and inspect the resulting matrix
1:25:50Step in to CameraTransform() and inspect the resulting matrix
1:26:55handmade_math.h: Fix typos in CameraTransform()
1:26:55handmade_math.h: Fix typos in CameraTransform()
1:26:55handmade_math.h: Fix typos in CameraTransform()
1:27:12Step back in to CameraTransform() and inspect the resulting matrix
1:27:12Step back in to CameraTransform() and inspect the resulting matrix
1:27:12Step back in to CameraTransform() and inspect the resulting matrix
1:28:39Blackboard: Producing our inverse components
1:28:39Blackboard: Producing our inverse components
1:28:39Blackboard: Producing our inverse components
1:31:47Blackboard: Set up the matrixes in the correct orientation
1:31:47Blackboard: Set up the matrixes in the correct orientation
1:31:47Blackboard: Set up the matrixes in the correct orientation
1:33:04handmade_math.h: Make CameraTransform() correctly compute the iP
1:33:04handmade_math.h: Make CameraTransform() correctly compute the iP
1:33:04handmade_math.h: Make CameraTransform() correctly compute the iP
1:34:18Step in to CameraTransform() to see that we're now rock solid
1:34:18Step in to CameraTransform() to see that we're now rock solid
1:34:18Step in to CameraTransform() to see that we're now rock solid
1:35:03handmade_render_group.cpp: Enable SetCameraTransform() to compute both matrices, and PushSetup() to take a m4x4_inv
1:35:03handmade_render_group.cpp: Enable SetCameraTransform() to compute both matrices, and PushSetup() to take a m4x4_inv
1:35:03handmade_render_group.cpp: Enable SetCameraTransform() to compute both matrices, and PushSetup() to take a m4x4_inv
1:37:03Run the game and note that we can always access the inverse of our projection
1:37:03Run the game and note that we can always access the inverse of our projection
1:37:03Run the game and note that we can always access the inverse of our projection
1:37:23handmade_render_group.cpp: Determine to enable Unproject() to perform the reverse transform on the z
1:37:23handmade_render_group.cpp: Determine to enable Unproject() to perform the reverse transform on the z
1:37:23handmade_render_group.cpp: Determine to enable Unproject() to perform the reverse transform on the z
1:38:41Blackboard: Unprojecting the z
1:38:41Blackboard: Unprojecting the z
1:38:41Blackboard: Unprojecting the z
1:39:50handmade_render_group.cpp: Enable Unproject() to perform the reverse transform on the z
1:39:50handmade_render_group.cpp: Enable Unproject() to perform the reverse transform on the z
1:39:50handmade_render_group.cpp: Enable Unproject() to perform the reverse transform on the z
1:43:06Consider restoring the mouse picking of entities
1:43:06Consider restoring the mouse picking of entities
1:43:06Consider restoring the mouse picking of entities
1:45:15handmade_render_group.cpp: Make Unproject() take a WorldDistanceZ
1:45:15handmade_render_group.cpp: Make Unproject() take a WorldDistanceZ
1:45:15handmade_render_group.cpp: Make Unproject() take a WorldDistanceZ
1:47:28handmade_math.h: Extend Transform() to take a v4
1:47:28handmade_math.h: Extend Transform() to take a v4
1:47:28handmade_math.h: Extend Transform() to take a v4
1:48:20handmade_render_group.cpp: Make Unproject() compute the ClipZ from ProbeZ
1:48:20handmade_render_group.cpp: Make Unproject() compute the ClipZ from ProbeZ
1:48:20handmade_render_group.cpp: Make Unproject() compute the ClipZ from ProbeZ
1:49:20handmade_math.h: Introduce an operator*() that takes a v4
1:49:20handmade_math.h: Introduce an operator*() that takes a v4
1:49:20handmade_math.h: Introduce an operator*() that takes a v4
1:49:40handmade_render_group.cpp: Make GetCameraRectangleAtDistance() use WorldDistanceFromCameraZ directly
1:49:40handmade_render_group.cpp: Make GetCameraRectangleAtDistance() use WorldDistanceFromCameraZ directly
1:49:40handmade_render_group.cpp: Make GetCameraRectangleAtDistance() use WorldDistanceFromCameraZ directly
1:50:50Run the game to see how it currently works
1:50:50Run the game to see how it currently works
1:50:50Run the game to see how it currently works
1:51:39handmade_render_group.cpp: Enable SetCameraTransform() to check the inverse of the composite
1:51:39handmade_render_group.cpp: Enable SetCameraTransform() to check the inverse of the composite
1:51:39handmade_render_group.cpp: Enable SetCameraTransform() to check the inverse of the composite
1:52:20Step in to SetCameraTransform() and inspect that identity composite matrix
1:52:20Step in to SetCameraTransform() and inspect that identity composite matrix
1:52:20Step in to SetCameraTransform() and inspect that identity composite matrix
1:54:02Step in to Unproject() and inspect the Clip coordinates
1:54:02Step in to Unproject() and inspect the Clip coordinates
1:54:02Step in to Unproject() and inspect the Clip coordinates
1:55:30handmade_debug.cpp: Make DEBUGEnd() set the MouseX to 0 and MouseY to 1079
1:55:30handmade_debug.cpp: Make DEBUGEnd() set the MouseX to 0 and MouseY to 1079
1:55:30handmade_debug.cpp: Make DEBUGEnd() set the MouseX to 0 and MouseY to 1079
1:56:03Step in to Unproject() to see that the Clip coordinates are now wrong
1:56:03Step in to Unproject() to see that the Clip coordinates are now wrong
1:56:03Step in to Unproject() to see that the Clip coordinates are now wrong
1:56:57handmade_render_group.cpp: Make Unproject() correctly compute the ClipSpaceX and ClipSpaceY
1:56:57handmade_render_group.cpp: Make Unproject() correctly compute the ClipSpaceX and ClipSpaceY
1:56:57handmade_render_group.cpp: Make Unproject() correctly compute the ClipSpaceX and ClipSpaceY
1:58:06Blackboard: Dividing by half of the width
1:58:06Blackboard: Dividing by half of the width
1:58:06Blackboard: Dividing by half of the width
1:59:06Step through Unproject() and inspect the values
1:59:06Step through Unproject() and inspect the values
1:59:06Step through Unproject() and inspect the values
2:01:11Run the game to find that debug clicking works correctly again
2:01:11Run the game to find that debug clicking works correctly again
2:01:11Run the game to find that debug clicking works correctly again
2:02:14todo.txt: Update the TODO list
2:02:14todo.txt: Update the TODO list
2:02:14todo.txt: Update the TODO list
2:03:21Q&A
🗩
2:03:21Q&A
🗩
2:03:21Q&A
🗩
2:04:10Miblo Am I right in thinking that today's work has had the cool, and not immediately expected, side effect of beginning to level up the debug camera, in terms of mouse picking of entities? Or did the debug camera have that before anyway?
🗪
2:04:10Miblo Am I right in thinking that today's work has had the cool, and not immediately expected, side effect of beginning to level up the debug camera, in terms of mouse picking of entities? Or did the debug camera have that before anyway?
🗪
2:04:10Miblo Am I right in thinking that today's work has had the cool, and not immediately expected, side effect of beginning to level up the debug camera, in terms of mouse picking of entities? Or did the debug camera have that before anyway?
🗪
2:04:52Blackboard: 3D Picking of Entities
2:04:52Blackboard: 3D Picking of Entities
2:04:52Blackboard: 3D Picking of Entities
2:05:46kim_jorgensen Do you plan to keep the Assert in OpenGLDebugCallback? My driver is sending a lot of debug information that fires the assert
🗪
2:05:46kim_jorgensen Do you plan to keep the Assert in OpenGLDebugCallback? My driver is sending a lot of debug information that fires the assert
🗪
2:05:46kim_jorgensen Do you plan to keep the Assert in OpenGLDebugCallback? My driver is sending a lot of debug information that fires the assert
🗪
2:05:54handmade_opengl.cpp: Disable the OpenGLDebugCallback error message
2:05:54handmade_opengl.cpp: Disable the OpenGLDebugCallback error message
2:05:54handmade_opengl.cpp: Disable the OpenGLDebugCallback error message
2:08:18lucid_frost Why do you think it is not popular to do x-forward coordinate systems? Jon Blow was talking about it yesterday and it seems like a good idea, at least in terms of rotations
🗪
2:08:18lucid_frost Why do you think it is not popular to do x-forward coordinate systems? Jon Blow was talking about it yesterday and it seems like a good idea, at least in terms of rotations
🗪
2:08:18lucid_frost Why do you think it is not popular to do x-forward coordinate systems? Jon Blow was talking about it yesterday and it seems like a good idea, at least in terms of rotations
🗪
2:09:05macielda Why use Square(Length(..))? How does it compare to LengthSq(..)?
🗪
2:09:05macielda Why use Square(Length(..))? How does it compare to LengthSq(..)?
🗪
2:09:05macielda Why use Square(Length(..))? How does it compare to LengthSq(..)?
🗪
2:09:21handmade_math.h: Make CameraTransform() use LengthSq() directly
2:09:21handmade_math.h: Make CameraTransform() use LengthSq() directly
2:09:21handmade_math.h: Make CameraTransform() use LengthSq() directly
2:10:47unknown_20 Will you consider a faster matrix multiplication algorithm other than inner product?
🗪
2:10:47unknown_20 Will you consider a faster matrix multiplication algorithm other than inner product?
🗪
2:10:47unknown_20 Will you consider a faster matrix multiplication algorithm other than inner product?
🗪
2:11:33jeffgmelton Is there a roadmap for what you will be working on over the coming months?
🗪
2:11:33jeffgmelton Is there a roadmap for what you will be working on over the coming months?
🗪
2:11:33jeffgmelton Is there a roadmap for what you will be working on over the coming months?
🗪
2:11:50macielda The ProbeZ thing went a bit too quick for me. I didn't fully understand the role of WorldDistanceFromCameraZ and how you are going to generate it. Are you going to talk more about that next time?
🗪
2:11:50macielda The ProbeZ thing went a bit too quick for me. I didn't fully understand the role of WorldDistanceFromCameraZ and how you are going to generate it. Are you going to talk more about that next time?
🗪
2:11:50macielda The ProbeZ thing went a bit too quick for me. I didn't fully understand the role of WorldDistanceFromCameraZ and how you are going to generate it. Are you going to talk more about that next time?
🗪
2:12:04Blackboard: The 3D Picking Procedure
2:12:04Blackboard: The 3D Picking Procedure
2:12:04Blackboard: The 3D Picking Procedure
2:13:56pragmascrypt Since you are only doing quads, wouldn't it be possible to upload a constant index buffer once with the max number of vertices and then never touch it again?
🗪
2:13:56pragmascrypt Since you are only doing quads, wouldn't it be possible to upload a constant index buffer once with the max number of vertices and then never touch it again?
🗪
2:13:56pragmascrypt Since you are only doing quads, wouldn't it be possible to upload a constant index buffer once with the max number of vertices and then never touch it again?
🗪
2:14:59unknown_20 Is it possible that Square Length can result in a zero and blow up?
🗪
2:14:59unknown_20 Is it possible that Square Length can result in a zero and blow up?
🗪
2:14:59unknown_20 Is it possible that Square Length can result in a zero and blow up?
🗪
2:15:39kim_jorgensen I get OpenGL messages with severity DEBUG_SEVERITY_NOTIFICATION and DEBUG_SEVERITY_MEDIUM
🗪
2:15:39kim_jorgensen I get OpenGL messages with severity DEBUG_SEVERITY_NOTIFICATION and DEBUG_SEVERITY_MEDIUM
🗪
2:15:39kim_jorgensen I get OpenGL messages with severity DEBUG_SEVERITY_NOTIFICATION and DEBUG_SEVERITY_MEDIUM
🗪
2:15:59ratchetfreak Even a simple pass-through geometry shader is a decent perf hit
🗪
2:15:59ratchetfreak Even a simple pass-through geometry shader is a decent perf hit
🗪
2:15:59ratchetfreak Even a simple pass-through geometry shader is a decent perf hit
🗪
2:16:15rooctag Sorry, didn't see the whole stream, but why no 60fps with the move to core GL?
🗪
2:16:15rooctag Sorry, didn't see the whole stream, but why no 60fps with the move to core GL?
🗪
2:16:15rooctag Sorry, didn't see the whole stream, but why no 60fps with the move to core GL?
🗪
2:16:31build.bat: Temporarily switch to -O2 and disable the debug system
2:16:31build.bat: Temporarily switch to -O2 and disable the debug system
2:16:31build.bat: Temporarily switch to -O2 and disable the debug system
2:18:45Run the game in the belief that this is 60fps
2:18:45Run the game in the belief that this is 60fps
2:18:45Run the game in the belief that this is 60fps
2:20:01kim_jorgensen e.g. MEDIUM: "Recompiling fragment shader for program 3"
🗪
2:20:01kim_jorgensen e.g. MEDIUM: "Recompiling fragment shader for program 3"
🗪
2:20:01kim_jorgensen e.g. MEDIUM: "Recompiling fragment shader for program 3"
🗪
2:20:24handmade_opengl.cpp: Pull in the severities from corearb.h and only make the OpenGLDebugCallback occur on GL_DEBUG_SEVERITY_HIGH1
2:20:24handmade_opengl.cpp: Pull in the severities from corearb.h and only make the OpenGLDebugCallback occur on GL_DEBUG_SEVERITY_HIGH1
2:20:24handmade_opengl.cpp: Pull in the severities from corearb.h and only make the OpenGLDebugCallback occur on GL_DEBUG_SEVERITY_HIGH1
2:21:32Run the game to see that it still works
2:21:32Run the game to see that it still works
2:21:32Run the game to see that it still works
2:21:40We are about done for today
🗩
2:21:40We are about done for today
🗩
2:21:40We are about done for today
🗩