|
미국에서는 자동차가 신발 같은 것이라서, 1인당 한대씩 개나 소나 다 가지고 있습니다.
심지어는 고등학생들도 차가 있고, 대학생이라면 왠만해서는 다 한대씩 몰고 다닙니다. 미국은 대중 교통이 없기 때문에 (버스 한대가 한시간에 한번 올까 말까) 자기 차가 없으면 학교를 못 다녀요... ㅡ.ㅡ 그런데 유학 온 학생들중에는 이런 미국 사정을 모르고 오는 사람들 (저처럼) 많기 때문에, 차가 없이도 어떻게 될꺼라고 생각하는 사람이 많습니다. 이런 사람들은 대부분 주변 사람들에게 교통편을 부탁하는 방법으로 문제를 해결하지요. 그런데 제가 하고 싶은 말은, 제가 심성이 못되고 인정이 박하기 때문이 아니라, 교통편을 부탁해 올때마다 상당히 불편한 느낌을 받습니다. ![]() 두번째로는 운전을 할줄 모르는 사람들은 운전하는 걸 매우 간단한 걸로 생각하기 때문에, 어디 데려다 달라는 거를 아무것도 아닌것 처럼 부탁합니다. 고맙다는 말을 듣는 경우도 거의 드물지요. 세번째는, 운전에 집중해야하는 상황에서, 옆에 앉아 있는 (운전 할줄 모르는) 사람들이 끊임 없이 말을 겁니다. 차 내가 조용하면 뭔가 썰렁하다고 느껴서 자꾸 얘기를 하고 싶어하는것 같습니다. 그래서 저는 항상 이런 불만이 있으면서도 말은 안하고 이렇게 얘기 합니다. "너도 어서 운전 배워야지~~" 라고요. 그렇게 말하는 것의 실제 속마음은 "너가 운전을 배워봐야 이게 어려운줄 알지..." 라는 의미입니다. 되돌아보면, 제가 한국에 있을때 차 얻어 탈때마다 이 얘기를 들어왔던것 같은데, 아마 그때 그런 의미였던가 봅니다. ㅡ.ㅡ
요즘 ShaderX7 을 읽고 있는데 2009년 가장 최신판인 만큼 난이도가 아주 높고, 내용도 매우 충격적으로 훌륭합니다. 거의 최신 기술들을 전부 망라해 놓은 듯한 느낌이 들어서 상당히 재미있게 읽고 있습니다.
이번 7판에서 가장 흥미로운 점은 deferred shading 의 문제점을 개선한 pre-light rendering 이라는 방법이 제안되었다는 점입니다. ![]() 책의 핵심 편집자이자 RockStar 에서 연구하고 계시는 Engel 아저씨의 말에 따르면 GTA4 에서 이 pre-light rendering 이라는것이 이미 사용되고 있다고 합니다. 우선 deferred shading 의 문제점을 살펴보면, G-Buffer 라는 (geometric buffer) 것을 생성하는 과정에서 MRT (Multiple Render Target) 라는 기능이 하드웨어적으로 지원이 안되면 deferred shading 을 사용할수 없다는 제약이 있고, 사용할수 있게 된다고 하더라도 MRT 로 사용할수 있는 텍스쳐의 량을 무한으로 증가 시킬수 없기 떄문에 (보통 최대 4장) 나중에 lighting 할때 사용할수 있는 material 에 대한 정보가 제한될수 밖에 없습니다. 그리고 MSAA (Multisampling Anti-Aliasing) 기능을 사용할수 없다는 큰 문제점도 있습니다. 결정적으로 deferred shading 의 가장 치명적인 문제점은 투명한 물체 표현이 매우 매우 어렵다는 점입니다. ShaderX7 에 있는 글들을 읽어보면 위에서 언급한 대부분의 문제점들은 DirectX 10 이상에서 해결이 가능하다고 합니다만, 여전히 투명한 물체 표현은 depth peeling 같은 느린 연산을 사용해야 한다고 하고, 그리고 근본적으로 deferred shading 은 G-Buffer 의 사이즈가 너무 커서 shader programming 에서 가장 중요한 bandwidth 를 너무 많이 잡아 먹는다는 문제가 여전히 남게 되겠습니다. 여기에 pre-light rendering 을 사용하면 위에 언급된 문제점들이 모두 해결됩니다. 기본 아이디어는 deferred shading 의 기본 아이디어를 반대로 하는 것입니다. 즉, deferred shading 에서는 geometry 정보를 먼저 사용해서 G-Buffer 를 작성하지만 pre-light rendering 방식에서는 lighting 을 먼저 계산하고 뒤이어서 geometry 한개 한개씩을 그려줄때에는 이미 계산된 빛의 강도값을 사용해서 그려주는 방식입니다. pre-light rendering 은 우선 MRT 를 필수로 요구하지 않습니다. (성능 향상을 위해 MRT 를 활용할수는 있습니다) 그리고 기본적으로 MSAA 의 지원을 받을수 있습니다. 그리고 G-Buffer 같은 무거운 버퍼를 가지는 것이 아니기 때문에 material 사용을 훨씬더 자유롭게 할수 있습니다. 그리고 light buffer 를 구성하는 방법에 따라 투명한 물체 표현도 상당히 간단하게 해결될수 있고, 그림자 문제도 deferred shading 에서 하는 방식을 그대로 사용해서 간단히 해결할수 있습니다. 이렇게 보면 pre-light rendering 은 deferred shading 을 완전히 대체 할수 있는 새로운 방법으로 보입니다. 확실히 저는 그런 느낌이 듭니다. 그런데 pre-light rendering 도 문제점은 있는데, 제가 볼때는 두가지가 대표적인 문제점입니다. 첫번째는 deferred shading 이 geometry 정보를 한번만 그리는 것에 반해서 pre-light rendering 을 사용하면 처음에 depth buffer 를 체워주기 위해서 한번 그리고 나중에 material 사용해서 빛량을 계산할때 또 한번 그려줘야 합니다. 사실 depth buffer 만 체우는거는 상대적으로 빠르고, depth buffer 체우기의 특성상 카메라에 가까운것부터 먼것 순서로 그리게 되면 하드웨어 occlusion culling 효과가 있어서 비용이 그리 많이 들지 않습니다. 두번째 문제는 사용할수 있는 빛의 종류를 다양하게 늘리는데 한계가 있어 보입니다. 이 문제는 조만간 개선 방법이 나올걸로 확신됩니다만, 당분간은 누군가가 해결할때 까지 기다려야 할것 같습니다. 쉽게 말해서 pre-light rendering 에서는 빛의 종류를 directional 이나 point light 나 spot light 중의 한가지만 사용할수 있습니다. 두개 이상 동시에 사용하려고 하는 경우, 가능은 한데 pixel shader 코드가 복잡해집니다. 그리고 아직 두가지 이상의 빛 종류를 동시에 사용하는 걸 구현한 pixel shader 가 없습니다. ![]() http://code.google.com/p/lightindexed-deferredrender/ 위의 주소에 보면 한번에 255개의 빛이 동시에 사용된 것을 볼수 있습니다. 그러면서도 사용된 텍스쳐의 량은 기존의 표준 deferred shading 의 절반정도 밖에 되지 않고 훨씬 빠릅니다. Engel 의 글에 따르면 deferred shading 이 3.5ms 걸릴때 pre-light rendering 은 0.7ms 걸린다고 하는군요. 아무튼 책을 계속 읽고 있는데, 최신 기술들이 마구 마구 쏟아져 나와서 머릿속으로 소화하느라 고생중입니다. 책은 정말 좋아서 벌써 레벨 1 업하고도 남는 기분입니다.
Texture sampling 과 관련해서 주의해야할 사항을 한번 적어보려고 합니다.
Pixel shader 프로그래밍을 하다보면 너무나 자연스럽게 texture sampler 를 사용하게 됩니다. 간단한 예를 보면 다음과 같습니다. sampler color_map;여기에서 tex2D 라는 것이 텍스쳐 color_map 이라는 것에 접근해서 값을 꺼내주는 함수입니다. 우선 기억을 되살려야 할것은, 우리가 텍스쳐 그림 파일을 저장하는 방법입니다. 예를 들어, 텍스쳐를 A8R8G8B8 의 32bit 형태로 저장한 그림 파일을 사용한다고 했을때, red 가 8bit 를 사용하고, green 과 blue 도 8bit 를 사용해서 각각 256가지 색깔을 표현할수 있습니다. 구체적으로 이 값들은 8bit integer 형으로 저장되는데 signed 가 아니라 unsigned 형태라는 점도 기억해두어야 합니다. 그런데 우리가 텍스쳐 샘플링을 할때, 다시 말해서 pixel shader 에서 tex2D 라는 함수를 사용해서 텍스쳐로부터 색을 얻어오면, 값의 범위는 0 부터 1 사이입니다. 그리고 이 값은 signed 값입니다. 그리고 float 형태로 값을 넘겨주기 때문에 32bit 형태입니다. 정리하면 이렇게 됩니다. unsigned 8 bit int 가 signed 32bit float 형태로 샘플링 된다는 것입니다. 이렇게만 되면 사실 문제는 없는데, 이 과정이 반대로 되면 문제가 발생합니다. 우리가 render target 을 지정해서 이미지를 텍스쳐에 임시로 그려 넣는다고 했을때, 생상 정보는 각 채널당 8bit 이기 때문에 무심결레 float 값을 한 색상 채널에 저장해서 그려두면 32bit 값이 8bit로 쪼그라 들어버립니다. 그런데 나중에 샘플링 해서 사용할때는 tex2D 가 다시 32bit float 을 넘겨주기 때문에, 마치 계속 32bit 값이 유지되고 있는것 같은 착각을 일으킵니다. 이런 이유로 floating-point texture 혹은 fat pixel 이라는 개념이 등장하는 것입니다. fat pixel 은 한 픽셀안에 색상 채널당 32bit 로 구성되어있기 때문에 A32R32G32B32 가 되어서 총 128bit 로 구성됩니다. 일반 색상의 4배가 되는것이죠. 가볍게 생각해버리면, 색상 정보는 24bit 만 있으면 되는데 왜 fat pixel 같은 128bit 픽셀이 필요하지?? 하고 생각할수 있습니다. 하지만, 실제 pixel shader 프로그래밍을 하면 텍스터에다가 색상만 담는게 아니라, 색상 이외의 다른 정보들을 (일종의 꽁수형태로) 저장하는게 일반화 되어있기 때문에 fat pixel 이 필요하게 되는 것입니다. 하지만 fat pixel 은 pixel shader 2.0 표준에서 표함되어있는것이 아니기 때문에 지원되는 하드웨어가 있고 안되는 하드웨어가 있습니다. 이렇게 지원이 안되는 하드웨어에서 32bit 값을 텍스쳐에 저장하는 꽁수로는 32bit float 값을 integer 형태로 인코딩해서 저장하는 방법입니다. 구체적으로는 이런식이 되겠습니다. float4 ps_main( float4 inDepth: TEXCOORD0 ) : COLOR0 그러면 나중에 이 택스쳐로 부터 값을 꺼내서 사용할때는 다시 디코딩을 해야하는데 다음과 같이 하면 되겠습니다. float4 DepthValue = tex2D(Texture2,texCoord); 여기에 더해서 texture sampler 가 하는 또하나의 기능은 anti-aliasing filter 를 적용해주는 일입니다. 사실 저도 구체적으로 어떻게 aliasing filter 를 정용하는지 잘 모르기 때문에 이부분은 다음 기회로 미루겠습니다.
Introduction to 3D game programming with DirectX 9.0 을 읽었습니다. 이름이 길어서 그런지 흔히 "용책"으로 불리는 책입니다. DirectX 의 입문서로 유명한 책인데, 도서관에 없었던 관계로 구입했습니다. 구입하고 나서 보니까 9.0c 용으로 책이 또 있더군요. 두가지가 접근법이 다른 것이라 또 보고 싶기는 한데 시간이 없군요...
![]() 그래도 가장 마지막 chapter 에서 effect framework 를 설명하는 부분은 상당히 재미있게 읽었습니다. 모르던 부분이라서 그랬을수도 있지만, 프로그래밍 스타일을 상당히 크게 바꿔 놓을만큼 중요한 내용이더군요. 예전에 Ogre 책 읽을때도 거기서 같은 내용을 다루었는데, 그때는 Ogre 고유 기능인줄 알았더니만, 지금보니 DirectX 에 원래 있던 거였군요... 쩝 ㅡ.ㅡ ![]() 4일정도 걸린것 같은데 중간에 딴지가 없었으면 3일도 가능했을것 같습니다.
아.. 내가 왜 진작에 그런 생각을 하지 못했을까...
책도 다운 받을수가 있는 세상이 되었구나.... ![]() | ||||