본문 바로가기
Metal

Perspective Projection & Phong Shading

by ARpple 2024. 4. 22.

Perspective Projection

필요 데이터 구조

  • 눈 위치 벡터 (원근 투영을 구현하기 위함)

  • 화면을 바라보는 시점의 좌표(World)를 설정한다.
  • 화면을 바라보는 시점에 각 화면의 픽셀을 보는 방향 벡터를 구한다.
  • Ray의 방향 벡터를 위의 벡터로 설정해 투영한다.
final class Raytracer{
...
    let eye: vector_float3 = .init(0, 0, -1)
    func render()->[Vertex]{
        var vertices:[Vertex] = Array(repeating: .init(position: .zero, color: .zero), count: height * width)
        for j in (0..<height){
            for i in (0..<width){
                let pixelPosWorld = self.transformScreenToWorld(posScreen: .init(x: Float(i), y: Float(j)))
                let rayDir = pixelPosWorld - eye
                var ray = Ray(start: pixelPosWorld, dir: rayDir)
                let positionColor = vector_float4(traceRay(ray:&ray),1.0)
                vertices[j * width + i] = Vertex(position: .init(x: pixelPosWorld.x, y: pixelPosWorld.y), color: positionColor)
            }
        }
        return vertices
    }
...
}

Phong Shading

 

Phong shading - Wikipedia

From Wikipedia, the free encyclopedia Interpolation technique for surface shading This article is about Phong's normal-vector interpolation technique for surface shading. For Phong's illumination model, see Phong reflection model. Flat shading (left) versu

en.wikipedia.org

 

 

The Phong Model

The glossy reflection of a light source is dimmer than the reflection of that same light source by a mirror-like surface (we assume here that the viewer looks at the reflection of a light source along the light rays' reflection direction as shown in figure

scratchapixel.com

필요 데이터 구조

  • 퐁 머터리얼 - 모두 색상 (R,G,B)를 나타내는 3차원 Vector
    ⇒ Object 프로토콜에 에 모두 이 머터리얼을 저장 프로퍼티로 갖고 있게 선언
    • ambient - 주변광
    • diff - 분산
    • specular - 정반사
  • Light
    • 빛의 위치 - 3차원 Vector
  • Object Protocol의 확장
    • phongMaterial: 입력받게 수정
    • alpha: Specular를 더 크게 만든다 (Specular를 제곱함)
    • ks: 반사 강도
protocol Obj{
    var phongMat: PhongMaterial { get set }
    var color: vector_float3 {get set}
    var alpha: Float32 { get set }
    var ks:Float32 {get set}
    func checkRayCollision(ray: inout Ray) -> Hit
}

PhongColor 반환 메서드

Ray의 인스턴스와 Hit 인스턴스로 구현

⇒ Hit 인스턴스 내부에 Obj 프로토콜 정보가 담겨있어서 구현 가능

func phongColor(ray:Ray,hit: Hit) -> vector_float3 {
        /// Diffuse 설정
        guard let obj = hit.obj else {return .zero}
        let dirToLight = normalize(light.pos - hit.point)
        let diff = max(dot(hit.normal, dirToLight), 0)
        /// Specular 설정
        let reflectDir = 2 * dot(hit.normal, dirToLight) * hit.normal - dirToLight
        let specular = max(dot(-ray.dir, reflectDir),0)
        // 물체 특성에 따라 반짝이는 정도를 다르게 한다.
        let specularMat = pow(specular, obj.alpha)
        return obj.phongMat.amb + obj.phongMat.diff * diff + obj.phongMat.spec * specularMat * obj.ks
    }

'Metal' 카테고리의 다른 글

무게 중심 좌표계, Barycentric coordinates  (0) 2024.04.30
RayTracing으로 삼각형 그리기  (0) 2024.04.08
Raytracing으로 구 그리기  (0) 2024.03.31
블룸 효과 만들기 with Metal  (0) 2024.03.11

댓글