Introduction
3D 공간과 3D 공간에서 정점을 이동하는 방법.
장면에서 멀리 떨어져 있는 요소가 더 작게 표시되도록 원근감 있게 렌더링한다.
원근감 있는 모델을 렌더링할 수 있게 되면 모델에 조명을 비출 수 있으며 이것이 얼마나 큰 차이를 만드는지 알 수 있다.
Position your model
우리는 x, y, z 축이 있는 좌표 공간에서 작업한
다. 이 축의 중심에 원점이 있다.
모든 방향에서 위치가 0이고 위쪽 축은 y축이 된다.
(Blender와 같은 일부 앱은 위쪽 축에서 z을 사용한다)
모델의 각 정점은 일반적으로 -1과 1 사이의 위치를 가진다.
모델은 종종 이 범위 밖의 정점 위치를 갖지만 지금은 -1과 1 사이에서 작업할 것이다. (NDC)
행렬을 사용하면 이러한 정점을 쉽게 변환할 수 있다.
수학적으로 변환은 무언가를 이동, 이동, 회전 또는 크기 조정하는 기능을 말한다.
변형 행렬을 정점 위치에 적용하면 해당 정점 위치가 변환되고 원점을 기준으로 회전하며 크기가 조정된다.
4x4 행렬의 경우 4개의 열과 4개의 행이 있다.
이 위치에 1과 0이 있는 왼쪽의 행렬을 항등 행렬Identity matrix이라고 한다. 정점 위치에 이 행렬을 곱하면 위치는 그대로 유지된다.
예를 들어 5에 1을 곱하면 5가 나오므로, 기존 수와 똑같다. 즉, 숫자 1도 항등 행렬이다. (1x1)
왼쪽의 행렬이 회전 변환이라면 정점 위치와 곱하여 해당 정점 위치를 변경할 수 있다.
특정 변환, 회전 및 배율 값으로 행렬을 설정한다.
왼쪽에 있는 이 행렬은 x축에서 원점으로 이동하고 z축에서 45도 회전한다.
이 행렬에 꼭짓점 위치를 곱하면 해당 꼭짓점이 행렬에 따라 변환, 회전 및 크기 조정된다.
3차원 개체를 이동하려면 개체의 모든 정점에 4x4 변환 행렬을 적용해야 한다.
그리고 개체는 3차원 공간에서 이동, 회전 및 크기 조정된다.
Coordinate Spaces
좌표 공간의 개념을 살펴보자.
좌표 공간은 단순히 공간에서 점을 정의하는 방법이다.
원점을 설정한 다음 단위 배율을 정의하여 모든 좌표 공간을 정의할 수 있다.
Blender에서 모델을 만들 때 모델 공간이라고 하는 좌표 공간에 정점을 추가한다. 예를 들어, 이 열차의 모든 정점 위치는 열차의 원점(0, 0, 0)에서 일정 거리 떨어져 있다.
각 정점 위치는 모형 공간에서 측정된다.
이 기차의 모든 꼭지점 위치는 NDC 내에 있다. 즉, x축과 y축에서 (-1)에서 (+1)까지 가는 정규화된 장치 좌표이다.
그렇기 때문에 기차를 0 위치에서 Rendering할 때 화면의 맨 왼쪽에서 오른쪽으로 늘어난다.
Model Matrix : Model Space에서 Model의 모든 정점을 World Space로 변환하는 행렬
Model Matrix를 사용하면 정점 위치를 Model Space에서 World Space로 변환하여 모든 정점에 적용되는 단 한 번의 변환으로 기차와 트리의 위치를 지정할 수 있다.
장면 주위를 이동하려면 가상 카메라를 만든다.
이것은 개념적으로 실제 카메라를 통해 실제 장면을 보는 것과 유사하다. 여기 기차를 바라보는 카메라가 있다. 아래는 카메라가 보는 것이다.
카메라를 기차에 더 가까이 이동하면 더 커진다.
그러나 개념적으로 World Space에서 Camera Space로 이동해도 동일한 결과를 얻을 수 있다.
카메라는 원점에 있고 우리는 그 주변의 장면에 있는 다른 모든 것을 움직인다.
컴퓨터 그래픽에서 이를 수행하기 위해 우리는 세계 공간에서 카메라의 위치를 포함하는 뷰 매트릭스를 생성하고 그 역을 장면의 모든 모델의 정점 위치에 적용한다.
Model Matrix : 각 Model마다 장면의 위치를 설명하는 행렬
View Matrix : Scene에서 카메라가 있는 위치를 설명하는 행렬
Shader에서 정점 위치에 Model Matrix를 곱한 다음 Inverted-View Matrix를 곱하여 Scene에서 Model이 어디에 있는지 결정하고 카메라와 관련하여 결정한다.
Projection and Depth
지금까지 행렬을 사용하여 Model Space에서 World Space로 Model을 가져온 다음 World Space에서 카메라 또는 뷰 공간으로 Model을 가져왔다. 마지막으로 적용할 행렬 변환은 투영이다.
우리는 장면을 볼 때 실제로는 모두 같은 크기이지만 각각 우리에게서 멀리 떨어져 있는 이 나무들처럼 더 멀리 떨어져 있는 물체가 더 작을 것이라고 기대한다.
Projection은 다음과 같다. 카메라나 눈 위치가 있고 그 위치에서 먼 평면을 본다.
근거리 및 원거리 평면Near / Far Plane은 볼 수 있는 것을 설명한다.
Near Plane 앞에 있는 모든 것과 Far Plane 뒤에 있는 모든 것이 잘려서 표시되지 않는다.
시야각Field of View은 카메라를 사용하는 사람에게는 익숙할 것이다.
시야각으로 65도를 선택한다. 장면에 맞게 더 크거나 작게 만들 수 있다.
투영 변환Projection Transform은 다른 변환과 약간 다르다.
모델 및 뷰 변환은 평행선이 보존된다. 그러나 우리는 뒤쪽에 있는 물체를 더 작게 만들려고 노력하고 있으므로 투영 변환이 좋지 않다.
Projection Matrix를 적용하면 Scene에서 더 이상 NDC(Normalized Device Coordinates)를 사용하지 않지만 시야와 원거리 평면에 따라 자체 배율 단위가 있으므로 모든 것을 더 쉽게 배치할 수 있다. 단위를 사용하는 것과 동일하다.
최종 정점 변환은 Scene의 뒤쪽 평면을 이용하여 변환한다.
꼭짓점 함수는 x, y, z 및 w 구성 요소로 위치를 출력한다. (w로 x y z 를 나누는 Rasterizer에 입력)
Projection된 Scene을 가져와 모든 좌표를 정규화하고 2D 화면에 맞도록 평면화한다.
var viewTransform = Transform()
viewTransform.position.y = 1.0
viewTransform.position.z = -2.0
var viewMatrix = viewTransform.matrix.inverse
var viewMatrix = projectionMatrix * viewTransform.matrix.**inverse**
GPU가 Rendering 할 수 있는 Depth Buffer를 생성하여 깊이를 Rendering 하는 방법을 Pipeline에 알려야 한다. 그러면 GPU는 이 Buffer를 사용하여 정점의 깊이를 비교할 수 있다.
여기에는 두 단계가 포함된다.
let depthStencilState: MTLDepthStencilState
첫째, Render Command Encoder에 제공할 수 있는 상태 개체State Object를 만들어야 한다.
depthStencilState = Renderer.createDepthState()
static func createDepthState() -> MTLDepthStencilState {
let depthDescriptor = MTLDepthStencilDescriptor()
depthDescriptor.depthCompareFunction = .less
depthDescriptor.isDepthWriteEnabled = true
return Renderer.device.makeDepthStencilState(descriptor: depthDescriptor)!
}
둘째, GPU가 깊이 값을 쓸 수 있도록 Grey Scale, Depth Texture를 할당해야 한다.
pipelineStateDescriptor.depthAttachmentPixelFormat = .depth32Float
Texture를 명시적으로 생성하지는 않지만 Metal 뷰에서 깊이의 픽셀 형식을 설정하고 PipelineState에서 동일하게 변경한다. 그리고 Metal View의 Render Pass Descriptor가 Depth Texture를 생성한다.
Cameras
'IT > Graphics' 카테고리의 다른 글
Metal 스터디 5주차 (23.01.12) (0) | 2023.01.15 |
---|---|
Metal 스터디 4주차 (23.01.06) (0) | 2023.01.15 |
Metal 스터디 2주차 (22.12.15) (0) | 2022.12.28 |
Metal 스터디 1주차 (22.12.09) (0) | 2022.12.13 |
컴퓨터 비전 스터디 7주차 : 21.05.23 (0) | 2021.05.24 |
댓글