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 |
댓글