본문 바로가기

Graphics

[Graphics] 06. 3D 이미지 생성을 위한 작업

 

이미지라고 생각하면 사진을 생각하면 적절하다. 카메라를 두고 어떤 피사체로 가서 셔터를 내리면 사진이 찍히는 방식이다. 즉 3차원상의 물체는 다음과 같이 찍힐 것이다.

이 때 관측자가 수직으로 바라보고 있다고 가정하자. 그럼 우린 카메라의 좌표가 필요할 것이다. 이를 Eye(Ex, Ey, Ez)로 표기하도록 하겠다. 그럼 이미지는 저 스크린의 픽셀들의 단위라고 볼 수 있을 것이다.
이 안에는 다양한 정보가 있다. 카메라, 스크린, 물체, 그리고 그 물체의 색, 공간의 좌표계, etc...

이 때 위의 회색처럼 Eye는 사각뿔의 모양을 가지고 스크린을 투영을 하는데 이 공간을 전문 용어로 View Frustum 즉 시각 사각뿔이라고 부른다. 이 때 이미지를 어떠한 내용을 고정시켜줘야 이미지를 딱 하나로 고정되는가를 데이터로 제공해야한다. 이는 Parameter를 제공해야 한다.

 

1. parameter of an image : 일단 관측자의 위치와 바라보는 방향을 줘야한다. 그리고 관측자의 회전축을 주어야 한다. (고개를 숙이거나, 또는 좌우로 회전을 해야하기 때문에) 이 parameter를 어떻게 주냐에 따라서 어떻게 보여질 지 다르다. 이 때 OpenGL에서 사용하는 것이 바로 다음과 같은 함수이다.

// 1. Eye : 카메라가 어디있는가.
// 2. at : 어디를 바라보는가
// 3. up : 머리의 위는 어디인가(회전축이 어딜 향하는가.)
void gluLookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble atx, GLdouble aty, GLdouble atz,  
    GLdouble upx, GLdouble upy, GLdouble upz);
 

 

2. Coordinate : 위에서 말한 정보를 가지고 우리는 카메라 좌표계를 정의할 수 있었다. 즉 카메라를 기준으로 어떤 좌표를 가지고 있는가를 파악할 수 있는 것이다. 그럼 카메라 좌표계 말고 어떤 좌표계가 또 있을까? 바로 World coordinate 즉 기본 좌표계라고도 부르는 월드 좌표계이다. 이는 어떤 사물들의 위치를 표현할 때 기준으로 삼는 좌표계로 문제에 따라서 우리가 읨의로 잡아서 사용할 수 있는 좌표계이기도 하다. 이 두개는 어디서 사용되는가? 바로, 물건의 배치와 함께 다음에서 설명할 부분에서도 사용된다.

 

3. Color of the pixel P : 지금까지 카메라, 좌표계에 대해 정리를 했다. 그럼 이제 카메라에게 제일 중요한 부분 과연 이 스크린에 어떻게 색을 정해서 투영시킬 것인가이다. 이 색을 표현하기 위해서 크게 두 가지 방식을 소개하겠다. OpenGL에서 사용되는 Z-Buffer 알고리즘, 그리고 우리가 공부하느라 죽어나갈(^^;;;) Ray Tracing 알고리즘이다.

 

- Z-buffer : 간단하게 말하면 두 개의 Buffer를 둔다. 하나는 단지 각 픽셀의 Color의 정보를 저장할 Color-Buffer, 그리고 다른 하나는 스크린으로부터 물체가 얼마나 떨어져있나를 저장할 Depth-Buffer이며 이를 저장해두고 지속적으로 갱신을 해나가는 방식으로 사용된다. 그렇다면 이 방식은 어떤 방식으로 동작하는지 의사코드를 통해서 설명하도록 하겠다.

z-buffer = infinity // 일단 아무 값이나 넣어둔다. (INT_MAX같은 걸로)
c-buffer = background-color // 일단 지정되어 있는 배경식을 넣는다.

for(each color in the view-frustum) 
{
   1. project the object onto the screen
   2. for(each pixel of the object) 
   {
      if(z-buffer of the pixel < z-buffer) 
      {
         c-buffer = color of the object;
         z-buffer = z-value;
      }
   }
}
 

이 방식을 통하면 미리 기억해두고 이를 buffer에 끊임없이 전송하며 이를 하드웨어가 처리를 하기 때문에 Tracing 기법에 비해서는 빠르다는 장점이 있다. 하지만 반대로 shadow 표현은 어렵다는 단점이 있는데 이를 보완하기 위해 1982년도에 발표된 ray casting 알고리즘이다.

 

- Ray tracing(Ray Casting) : 이 알고리즘은 1982년도 스콧 로스(Scott roth)라는 사람이 발표한 알고리즘으로 여기서는 정~~말 간단하게만 소개하고 넘어가도록 하겠다.(뒷 장에서 다시 설명할 것이기 때문) 간단하게 카메라에서 어떤 한 빛을 투사에서 만약 어떤 물체를 맞았다면 이 object의 컬러를 스크린에 투과하며 만약 아니라면 지정된 배경색을 스크린에 투과하는 방식으로 한다. 이를 의사 코드로 정리하면 다음과 같다.

for(each pixel of the screen)
{
   1. send the ray E→P
   2. find the 1st-hit object
   if(some hit)
   {
      c-buffer = color of the hit position
   } 
   else
   {
      c-buffer = background of the color // pre-defined
   }
}
 

이 방식은 단지 하나의 버퍼 즉 컬러 버퍼만 가지게 되며, 단지 hit된 object나 background의 color 정보만 들어가게 된다. 또 보통 광원은 카메라에서 나오는 것만 있는 것이 아니라 어떠한 태양, 백열등, 형광등 같은 것들의 정보를 같이 추적한 뒤 이를 혼합하는 방식이기 때문에 굉장히 컴퓨터의 성능이 높아야 한다는 단점이 있다. 그렇기에 굉장히 최근에 와서 NVidia 사의 RTX 시리즈가 나오기 전까지는 이러한 알고리즘을 사용한 컨텐츠가 굉장히 적었었다.