4주차

Normals

Untitled

Untitled

Scene이 원근감과 깊이를 갖고 있지만, 약간의 음영Shading이 있을 때까지는 완전한 3D가 아니다.

우리는 빛의 방향을 설정할 수 있으며 빛에서 멀어지는 Vertex는 빛을 바라보는 Vertex보다 어둡다.

그래서 꼭짓점들이 어느 방향을 바라보고 있는지를 알아야 한다. 표면 법선Surface Normal을 사용하여 이를 알아낸다.

Untitled

Surface Normal은 직각으로 가리키는 Vector로, 표면에 직각이다.

Blender가 OBG 파일을 내보낼 때 파일에 Surface Normal이 포함된다. Surface Normal을 사용하여 표면의 기울기와 방향을 알 수 있다. Normal의 방향을 빛과 음영의 방향과 적절하게 비교할 수 있다.

OBG 파일에서 Normal을 읽도록 코드를 변경해보자.

import Foundation
import MetalKit
extension MTLVertexDescriptor {
    static func defaultVertexDescriptor() -> MTLVertexDescriptor {
        let vertexDescriptor = MTLVertexDescriptor()
        vertexDescriptor.attributes[0].format = .float3
        vertexDescriptor.attributes[0].offset = 0
        vertexDescriptor.attributes[0].bufferIndex = 0
        vertexDescriptor.layouts[0].stride = MemoryLayout<SIMD3<Float>>.stride

				// vertexDescriptor에 Normal을 위한 atrribute 할당.
        vertexDescriptor.attributes[1].format = .float3
        vertexDescriptor.attributes[1].offset = MemoryLayout<SIMD3<Float>>.stride
        vertexDescriptor.attributes[1].bufferIndex = 0

				// 각 vertex가 buffer에서 두 개의 Float3를 가지는 것을 표시.
        vertexDescriptor.layouts[0].stride = MemoryLayout<SIMD3<Float>>.stride * 2

        return vertexDescriptor
    }
}
extension MDLVertexDescriptor {
    static func defaultVertexDescriptor() -> MDLVertexDescriptor {
        let vertexDescriptor = MTKModelIOVertexDescriptorFromMetal(.defaultVertexDescriptor())

        let attributePosition = vertexDescriptor.attributes[0] as! MDLVertexAttribute
        attributePosition.name = MDLVertexAttributePosition
				// Normal은 Model IO에 미리 정의되어 있는 속성 중 하나이다.
        let attributeNormal = vertexDescriptor.attributes[1] as! MDLVertexAttribute
        attributeNormal.name = MDLVertexAttributeNormal

        return vertexDescriptor
    }

Ambient and Diffuse Lighting

Untitled