기술 이름이 길다. 이 SVOGI는 참고문헌 1번인 Epic Reveals Stunning Elemental Demo, & Tim Sweeney On Unreal Engine 4에서 언급되었는데, 참고문헌 2번인 Interactive Indirect Illumination Using Voxel Cone Tracing의 논문을 토대로 했다고 알려져 있다(정확한 구현 방법에 대해서는 안알려진걸로 아는데.. 기법은 같아 보인다). 여기서는 SVOGI 라는 이름을 쓰되 참고문헌 2번 논문 방법을 따라가는 것으로 하겠다.

SVOGI의 기본 흐름은 간단(?)할 수 있으나, 심도 깊은 이해와 구현은 다소 복잡했다. 그래서 이 SVOGI에 대한 설명은 4~5개의 글로 나누어질 예정이다.

기본적인 흐름을 이렇다. GI 를 위해 간접 조명을 계산해야하는데,

  1. 장면(Scene)을 복셀로 만들고
  2. 그 복셀로 만들어진 구조에서 레이가 아닌 원뿔 모양의 콘 트레이싱(cone-tracing)[1]을 해서 간접 조명을 계산한다.
  3. 이때 원뿔의 모양에 따라 간접 조명의 세밀함을 조절할 수 있다.

이것들이 실시간으로 이루어진다.

아무튼 저자가 보여준 Interactive Indirect Illumination Using Voxel Cone Tracing의 기술 시연을 보면 입이 벌어진다.

언리얼 엔진 4의 기술 시연 데모는 여기서 다시한번 입이 벌어진다.

다음과 같은 순서로 설명하도록 하겠다.

  1. Thin Surface Voxelization - 메쉬 표면을 복셀화 하는 것이다. 이때 결과는 3D 텍스쳐가 된다.
  2. Voxel Octree Construction - 복셀화 한 데이터를 3D 텍스쳐가 아닌 옥트리(Octree) 구조로 출력한다.
  3. 콘 트레이싱을 수행한다. (아마 글이 2개로 나뉘어질듯.)

이 기술은 비교적 최신 그래픽 카드에만 사용할 수 있다. OpenGL 을 기준으로 설명할 것이며, OpenGL 4.2를 지원하는 그래픽카드가 필요하다. 참고로 OpenGL 의 최신 버전은 4.3이다(2012 년 8월). 그런데 사실 지원 여부를 떠나서 굉장한 성능을 필요로 하기 때문에 구형 그래픽 카드에서는 성능상 못돌리기도 할 꺼 같다.

소스 코드는 모든 글이 다 올라갈 때쯤 같이 올라갈 예정이다. 그때 쯤 소스도 다시한번 정리하면서 github에 업로드할 예정. (OpenGL로 구현되며, 쉐이더 또한 GLSL(OpenGL Shading Language)로 구현되었다)

또 한가지. 좀 더 엄밀하게 확인한 후 한꺼번에 올리기보다는 일단 글을 작성하는대로 올리면서 점차 재차 다듬고 수정하고 덧붙일 예정이다. (내용이 틀린 점이 있을 수 있거나, 글이 나중에 수정이 될 수 있다는 말)

픽셀을 복셀로 (Pixel to Voxel)

사실 알고보면 이 과정은 매우 간단하다. 어떤 화면을 직교 투영(orthogonal projection) 렌더링 할 경우 각 픽셀을 얻을 수 있는데 이 픽셀 하나하나가 복셀이 된다.

화면의 정보를 알고 깊이 값을 알고 있을 때 3D 좌표를 얻는건 어렵지 않다.


ivec3 voxelPosition = ivec3( int(gl_FragCoord[0]), int(gl_FragCoord[1]), int(linearDepth * boxLength) )
 

이때 출력 될 데이터는 3D 텍스쳐인데, 실제 SVOGI 구현에서는 3D 텍스쳐를 사용하지 않지만, 여기서는 중간 과정을 위해서 3D 텍스쳐로 출력해보는 것이다.


glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_3D, g_VoxelBox.NormalTexture );
glBindImageTexture( 1, g_VoxelBox.NormalTexture, 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_RGBA32F );
 

g_VoxelBox.NormalTexture 는 3D 텍스쳐다. 이걸 이미지 텍스쳐(ImageTexture)라는 것과 연결 시키는 것이다. 테스트용이니까 텍스쳐는 금지막하게 GL_RGBA32F 같은걸로 잡아도 된다.

GLSL 코드 안에서는 다음과 같이 선언한다.


layout(rgba32f, binding = 0) uniform coherent volatile writeonly image3D normalVoxels;
 

coherent volatile 에 대한 설명은 여기선 중요하지 않아서 (실은 설명했다가 틀릴까봐) 생략. 이러면 쉐이더 코드의 normalVoxels 은 g_VoxelBox.NormalTexture 3D 텍스쳐와 연결된다.

이 다음엔


imageStore( normalVoxels, voxelPosition, vec4( normal.x, normal.y, normal.z, 1.0 ) );
 

요렇게 저장해주면 된다. 참 쉽죠~

Stanford Bunny Voxel

물론 imageStore를 했다고 위와 같은 화면이 나오는건 아니다. 이렇게 저장한 후 픽셀쉐이더에서는 픽셀을 스크린 버퍼나 텍스쳐에 그릴 필요가 없다. 픽셀 자체는 버려도 된다. 앞으로 이런식의 계산을 종종 하게 될 것이다. 어쨌건 여기서는 imageStore로 3D 텍스쳐를 만드는 것이고, 이 이미지는 이것을 확인해보는 것이다. 구멍이 뽕뽕 보이는 이유는 저 복셀을 정육면체로 그린게 아니라 그냥 픽셀로 그렸기 때문이다. 색깔은 위에 저장한대로 노말이다.

사실 이 과정에서 사실 정말 많은 것들을 생략했다. 가령 쉐이더 코드에서


#version 420
#extension GL_EXT_shader_image_load_store : enable
 

이런걸 붙여줘야 하는 것도 있고, Geometry Shader(GS)사용에 대해서도 설명이 빠졌다. 카메라를 하나를 두고 렌더링을 하게 되면 위나 아래 혹은 옆면에서 볼 때 복셀이 제대로 생성 안되는 것을 알 수 있다. 따라서 GS를 이용해서 major 축을 골라 각각에 맞게 처리해줘야 한다. (이 부분에 대한 설명은 나중에 글을 다듬을 때 추가할지, 아니면 그냥 넘어갈지 모르겠다)

위에 언급을 했듯이 실제로 SVOGI에서 3D 텍스쳐 출력은 사용하지 않는다. 3D 텍스쳐를 쓴다면 normal, color 두가지만 저장해도 각 데이터 (4바이트+4바이트)*512*512*512 = 1GB 가 되서 지나치게 많은 비디오 램을 사용하게 된다. 게다가 이렇게 구현해봤자 실제로 채워진 복셀 보다는 빈 복셀이 훨씬 더 많은 경우(sparse voxel)가 많아 메모리 낭비가 심하게 된다.

따라서 SVOGI에서 복셀 데이터는 3D 텍스쳐가 아닌 아토믹(atomic) 연산을 이용해서 데이터 버퍼로 출력하는데, 그것이 다음 글에서 설명할 내용이다.

참고 문헌

  1. Andrew Burnes, Epic Reveals Stunning Elemental Demo, & Tim Sweeney On Unreal Engine 4
  2. Cyril Crassin, et al, Interactive Indirect Illumination Using Voxel Cone Tracing, Pacific Graphics, 2011
  3. Cyril Crassin and Simon Green, Octree-Based Sparse Voxelization Using The GPU Hardware Rasterizer, OpenGL Insights, CRC Press, 2012

이 외에도 참고 문헌은 많은데, 가급적 핵심적인 것들만 소개하고 나중에 한꺼번에 정리할 새각이다. 2번의 논문이 본래 이 기술의 논문인데 설명이 굉장히 부족하다. 특히 트리 생성에 대한 설명이 너무너무 부족한데, 몇달전 3번의 문서[2]가 나오면서 자세한 설명을 얻을 수 있었다. 아마 이 책이 없었으면 난 아직도 2번 논문을 보면서 이해력 딸리는 내 머리만 자책하고 있었을듯.



  1. 콘이라는 단어 대신 원뿔로 말하는게 올바르겠지만, 트레이싱(tracing)이라는 단어와 함께 말할 때는 편의상 콘 트레이싱이라 부르도록 하겠다. [본문으로]
  2. OpenGL Insights라는 책의 한 챕터인데 샘플로 챕터 전문이 공개 되어있다. [본문으로]
크리에이티브 커먼즈 라이센스
Creative Commons License
2012/12/12 20:44 2012/12/12 20:44

트랙백 주소 :: 이 글에는 트랙백을 보낼 수 없습니다

  1. Subject: GS test demo

    Tracked from GS test demo 2013/04/02 14:55  삭제

    Hybrid :: SVOGI – 1. Sparse Voxel Octree Global Illumination

댓글을 달아 주세요