Trace:

tutorial_205_20-_203d_20transformation

This shows you the differences between two versions of the page.

tutorial_205_20-_203d_20transformation [2018/03/31 13:19] 127.0.0.1 external edit |
tutorial_205_20-_203d_20transformation [2018/04/13 22:39] (current) richardrussell Added syntax highlighting |
||
---|---|---|---|

Line 17: | Line 17: | ||

\\ To apply multiple transformations to a vector, we can simply multiply the vector by the first transformation matrix, then multiply the resulting vector by the second transformation matrix, and so on. Because vector and matrix multiplication is associative, we can also multiply all of the matrices first, then multiply the vector by the product matrix and obtain an identical result.\\ \\ | \\ To apply multiple transformations to a vector, we can simply multiply the vector by the first transformation matrix, then multiply the resulting vector by the second transformation matrix, and so on. Because vector and matrix multiplication is associative, we can also multiply all of the matrices first, then multiply the vector by the product matrix and obtain an identical result.\\ \\ | ||

===== Creating the Orbit ===== | ===== Creating the Orbit ===== | ||

- | \\ In this tutorial, we will be transforming two cubes. The first one will rotate in place, while the second one will rotate around the first, while spinning on its own axis. Each cube will have its own world transformation matrix associated with it, and this matrix will be reapplied to it in every frame rendered.\\ \\ The first cube will be spinning in place and act as the center for the orbit. The cube has a rotation along the Y axis applied to the associated world matrix. This is done by calling the MatrixRotation procedure shown in the following code. The cube is rotated by a set amount each frame. Since the cubes are suppose to continuously rotate, the value which the rotation matrix is based on gets incremented with every frame:\\ \\ | + | \\ In this tutorial, we will be transforming two cubes. The first one will rotate in place, while the second one will rotate around the first, while spinning on its own axis. Each cube will have its own world transformation matrix associated with it, and this matrix will be reapplied to it in every frame rendered.\\ \\ The first cube will be spinning in place and act as the center for the orbit. The cube has a rotation along the Y axis applied to the associated world matrix. This is done by calling the MatrixRotation procedure shown in the following code. The cube is rotated by a set amount each frame. Since the cubes are suppose to continuously rotate, the value which the rotation matrix is based on gets incremented with every frame: |

+ | | ||

+ | <code bb4w> | ||

PROC_MatrixRotation(mWorld1(), 0, t, 0) | PROC_MatrixRotation(mWorld1(), 0, t, 0) | ||

- | \\ The second cube will be orbiting around the first one. To demonstrate multiple transformations, a scaling factor, and its own axis spin will be added. First the cube will be scaled down to 30% size, and then it will be rotated along its spin axis (the Z axis in this case). To simulate the orbit, it will get translated away from the origin, and then rotated along the Y axis. The desired effect can be achieved by using four separate matrices (mScale, mSpin, mTranslate, mOrbit), then multiplied together:\\ \\ | + | </code> |

+ | | ||

+ | The second cube will be orbiting around the first one. To demonstrate multiple transformations, a scaling factor, and its own axis spin will be added. First the cube will be scaled down to 30% size, and then it will be rotated along its spin axis (the Z axis in this case). To simulate the orbit, it will get translated away from the origin, and then rotated along the Y axis. The desired effect can be achieved by using four separate matrices (mScale, mSpin, mTranslate, mOrbit), then multiplied together: | ||

+ | | ||

+ | <code bb4w> | ||

PROC_MatrixRotation(mSpin(), 0, 0, -t) | PROC_MatrixRotation(mSpin(), 0, 0, -t) | ||

PROC_MatrixRotation(mOrbit(), 0, -2*t, 0) | PROC_MatrixRotation(mOrbit(), 0, -2*t, 0) | ||

Line 27: | Line 33: | ||

mWorld2() = mWorld2() . mTranslate() | mWorld2() = mWorld2() . mTranslate() | ||

mWorld2() = mWorld2() . mOrbit() | mWorld2() = mWorld2() . mOrbit() | ||

- | \\ An important point to note is that these operations are not commutative. The order in which the transformations are applied matter. Experiment with the order of transformation and observe the results.\\ \\ Since all the transformation functions will create a new matrix from the parameters, the amount at which they rotate has to be incremented:\\ \\ | + | </code> |

+ | | ||

+ | An important point to note is that these operations are not commutative. The order in which the transformations are applied matter. Experiment with the order of transformation and observe the results.\\ \\ Since all the transformation functions will create a new matrix from the parameters, the amount at which they rotate has to be incremented: | ||

+ | | ||

+ | <code bb4w> | ||

t = TIME / 100 | t = TIME / 100 | ||

- | \\ Before the rendering calls are made, the constant buffer must be updated for the shaders. Note that the world matrix is unique to each cube, and thus, changes for every object that gets passed into it:\\ \\ | + | </code> |

+ | | ||

+ | Before the rendering calls are made, the constant buffer must be updated for the shaders. Note that the world matrix is unique to each cube, and thus, changes for every object that gets passed into it: | ||

+ | | ||

+ | <code bb4w> | ||

REM Update variables for first cube: | REM Update variables for first cube: | ||

PROC_MatrixTranspose(ConstantBuffer{}, ConstantBuffer.mWorld{}, mWorld1()) | PROC_MatrixTranspose(ConstantBuffer{}, ConstantBuffer.mWorld{}, mWorld1()) | ||

Line 51: | Line 65: | ||

\ ^pConstantBuffer% | \ ^pConstantBuffer% | ||

SYS ID3D11DeviceContext.DrawIndexed%, pImmediateContext%, 36, 0, 0 | SYS ID3D11DeviceContext.DrawIndexed%, pImmediateContext%, 36, 0, 0 | ||

- | \\ | + | </code> |

===== The Depth Buffer ===== | ===== The Depth Buffer ===== | ||

- | \\ There is one other important addition to this tutorial, and that is the depth buffer. Without it, the smaller orbiting cube would still be drawn on top of the larger centre cube when it went around the back of the latter. The depth buffer allows Direct3D to keep track of the depth of every pixel drawn to the screen. The following code in the sample creates a depth buffer (a DepthStencil texture). It also creates a DepthStencilView of the depth buffer so that Direct3D 11 knows to use it as a Depth Stencil texture:\\ \\ | + | \\ There is one other important addition to this tutorial, and that is the depth buffer. Without it, the smaller orbiting cube would still be drawn on top of the larger centre cube when it went around the back of the latter. The depth buffer allows Direct3D to keep track of the depth of every pixel drawn to the screen. The following code in the sample creates a depth buffer (a DepthStencil texture). It also creates a DepthStencilView of the depth buffer so that Direct3D 11 knows to use it as a Depth Stencil texture: |

+ | | ||

+ | <code bb4w> | ||

REM Create depth stencil texture: | REM Create depth stencil texture: | ||

DIM descDepth{} = D3D11_TEXTURE2D_DESC{} | DIM descDepth{} = D3D11_TEXTURE2D_DESC{} | ||

Line 82: | Line 99: | ||

ERROR "ID3D11Device::CreateDepthStencilView failed: "+STR$~hr% | ERROR "ID3D11Device::CreateDepthStencilView failed: "+STR$~hr% | ||

ENDIF | ENDIF | ||

- | \\ In order to use this newly created depth stencil buffer, it must be bound to the device. This is done by passing the depth stencil view to the third parameter of the OMSetRenderTargets function:\\ \\ | + | </code> |

+ | | ||

+ | In order to use this newly created depth stencil buffer, it must be bound to the device. This is done by passing the depth stencil view to the third parameter of the OMSetRenderTargets function: | ||

+ | | ||

+ | <code bb4w> | ||

SYS ID3D11DeviceContext.OMSetRenderTargets%, pImmediateContext%, \ | SYS ID3D11DeviceContext.OMSetRenderTargets%, pImmediateContext%, \ | ||

\ 1, ^pRenderTargetView%, pDepthStencilView% | \ 1, ^pRenderTargetView%, pDepthStencilView% | ||

- | \\ As with the render target, we must also clear the depth buffer before rendering. This ensures that depth values from previous frames do not incorrectly discard pixels in the current frame. In the code below the tutorial is actually setting the depth buffer to be the maximum amount (1.0):\\ \\ | + | </code> |

+ | | ||

+ | As with the render target, we must also clear the depth buffer before rendering. This ensures that depth values from previous frames do not incorrectly discard pixels in the current frame. In the code below the tutorial is actually setting the depth buffer to be the maximum amount (1.0): | ||

+ | | ||

+ | <code bb4w> | ||

REM Clear the depth buffer to 1.0 (max depth): | REM Clear the depth buffer to 1.0 (max depth): | ||

SYS ID3D11DeviceContext.ClearDepthStencilView%, pImmediateContext%, \ | SYS ID3D11DeviceContext.ClearDepthStencilView%, pImmediateContext%, \ | ||

\ pDepthStencilView%, D3D11_CLEAR_DEPTH, FN_f4(1), 0 | \ pDepthStencilView%, D3D11_CLEAR_DEPTH, FN_f4(1), 0 | ||

+ | </code> |

tutorial_205_20-_203d_20transformation.txt · Last modified: 2018/04/13 22:39 by richardrussell

Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 4.0 International