Graphics Techniques

[Ray Tracing] ray를 통해 구의 입체감 표현하기

doyyy_0 2024. 10. 11. 10:27

2D 화면에 원을 그리는 방법은 간단합니다. 스크린좌표계를 월드 좌표계(일반 좌표계)로 변환한 후, 해당 좌표에서 원의 중심까지의 거리가 반지름 이하인 경우만 색칠해 주면 됩니다. 하지만 구는 다릅니다. 입체감을 표현하기 위해, 바라보는 시점에서 구까지의 거리당 밝기를 조절해야 하기 때문입니다. 만약 모든 픽셀의 밝기가 같다면, 화면에 그려지는 것은 2D 원과 같게 보일 것입니다.

 

**본 글은 이해를 편하게 하기 위해, Orthographic projection (정투영)으로 이해합니다

1. 일반 좌표계로의 변환

먼저, 이미지 좌표계를 월드 좌표계로 변환하는 방법을 살펴보겠습니다.
화면의 픽셀은 다음과 같습니다:

  • width = 1280, height = 720
  • aspect = width / height

스크린 좌표계는 (0, 0)부터 (width - 1, height - 1)까지의 2D 좌표로, 픽셀 단위로 표현됩니다. 이는 추후에 다양한 계산을 할 때 일반적인 x,y좌표와 다르므로 사용하지 않습니다.

월드 좌표계는 일반적으로 화면 비율(aspect ratio)을 고려한 [-aspect, aspect] x [-1, 1] 범위로 정의됩니다. 이는 실제 물리적 공간에서의 위치를 나타내는 좌표계로, 더 직관적이고 물체 간의 관계를 더 명확하게 할 수 있습니다

 

픽셀 (i, j)를 1:1 비율로 변환하기 위해서는 다음과 같은 작업을 진행합니다:

  • xScale = 2.0f / (width - 1)
  • yScale = 2.0f / (height - 1)

그 후, 픽셀 좌표 (i, j)는 다음과 같이 변환됩니다:

  • i -> (i * xScale - 1.0f) * aspect
  • j -> -j * yScale + 1.0f

이 변환을 통해, (i, j)는 [-aspect, aspect] x [-1, 1] 범위의 좌표계를 형성하게 됩니다.

2. 구 그리기

구를 그릴 때는 각 픽셀의 위치와 구까지의 거리를 계산해야 합니다. 구의 기본 방정식은 다음과 같습니다:

다음 그림을 보며 이해해 봅시다.

 

  • x = o + d * u (이것이 ray입니다)
    여기서 o는 화면의 각 픽셀의 위치, u는 화면에 수직인 구를 바라보는 방향 벡터 (크기는 반드시 1), center는 구의 중심, r은 구의 반지름, d는 ray를 쏘았을때, o에서 구의 까지의 거리입니다.

구의 방정식 (x - r)^2 = r^2에 x = o + d * u를 대입해 일반화하면, 판별식 D는 다음과 같습니다:

  • D = (u · (o - c))^2 - ((o - c)^2 - r^2)

구와 화면이 교차하는 위치에서의 거리는 다음과 같이 구할 수 있습니다:

  • d = -(u · (o - c)) ± √D

자세한 내용은 https://en.wikipedia.org/wiki/Line%E2%80%93sphere_intersection에서 확인할 수 있습니다.

 

여기서 d1만 계산합니다. 화면에 그려질 구는 앞에 있기 때문에, 만약 D가 음수이거나 d1이 음수라면 구가 화면 뒤에 있다고 판단하고 해당 픽셀에 색을 입히지 않습니다. 이렇게 화면에서 구를 바라봤을 때 구의 색에 d값을 곱해주면 거리당 밝기를 다르게 하여 구의 입체감을 표현할 수 있습니다