레이블이 그래픽인 게시물을 표시합니다. 모든 게시물 표시
레이블이 그래픽인 게시물을 표시합니다. 모든 게시물 표시

2013년 12월 3일 화요일

복셀 에디팅 팁

다신 안볼줄 알았는데.... -_-  요즘들어 다시 복셀(voxel) 에디팅에 대해 잠시 본 바.... 이 기회에 제가 이짓하면서 배운 교훈들을 짧게(정말?) 공유해볼까 합니다. 저번에 썼던 "혼합가능한 RGBM" 글 과는 달리 여기에 나열한 모든 정보/fact 들은 이미 온라인에 다 널려있는 내용입니다. 그냥 그 모든 내용들을 모아 제 의견을 약간 곁들인게 전부입니다.

1. isosurface부터 이해하세요
복셀 데이터를 주무르는 가장 실용적인 방법은 각 복셀마다 iso 값을 대입하는 겁니다. 다른 방법도 시도해봤는데요(물론 제가 발명해낸 기괴한 방법도 한번 시도해봤죠 -_-) 대부분 별로더라구요. 단점들이 있어요. 결국엔 iso 값으로부터 메쉬를 다시 생성해내는게 가장 실용적이고 메모리 친화적인 방법인거 같습니다. iso surface extraction에 대해 설명하는 무수한 논문이 있으나 정작 isosurface가 뭔지를 쉽게 설명하는 자료는 흔치 않더라구요.

여기 저기 뒤진 끝이 이 튜토리얼을 찾았습니다. 설명도 잘해놨구요. isosurface의 개념을 익히는데는 최고인듯 싶습니다. (물론 영어입니다... 이 글도 영문 블로그에 썻다가 한글로 번역하는 놈이기 때문에.. 혹시라도 괜찮은 한글자료 가지고 계신분은 공유좀 부탁 -_-a)

또한 3D Coat의 개발자가 매우 친절하게도 3D Coat에서 사용하는 복셀 데이터의 포맷을 공개해놨습니다. 이 데이터 구조를 들여다보는 것만으로도 복셀 에디팅에 대해 상당히 많은걸 배울 수 있습니다.

복셀 편집에는 큰 관심이 없고 그대신 임시 복셀 데이터로부터 절차적(procedurally)으로 거대한 지형(terrain)을 만드는게 목적이시라면 VoxelFarm inc의 블로그를  읽어보세요. 이 분 정말 천재더라구요. (실제 한번 만나도 봤습니다. 몬트리올 살때 -_-)

2. 복셀데이터는 "간접적" 으로만 변경할 수 있습니다
볼륨 데이터를 표현하기 위해 iso 값을 사용하게 되면 복셀 데이터를 변경할 수 있는 유일한 방법은 iso 값을 변경하는 것입니다. 이 연산들은 간단한 수학인데요. 각 iso 값을 증감하거나 이웃간의 값을 평균내는 등입니다. 물론 distance 함수를 직접 계산해서 새로운 isosurface 모양을 꾸겨넣을 순 있지요. (이 distance 함수에 대해서는 위에 링크를 걸어둔 튜토리얼을 참고해 주세요.)

iso 값과 최종 메쉬의 모양과는 1:1 관계가 없습니다. 즉 "이 edge를 0.2미터 오른쪽으로 늘리고 싶어. 그러니 복셀 값을 0.752로 바꿔야지!"라는 말을 할수가 없어요. 다시 말하면 최종 모양을 세밀하게 조절할 방법이 없습니다. 복셀의 밀도(density)를 아주 높이 올려도 (예: 1센치당 복셀 하나) 역시 마찬가지입니다. 이게 바로 제가 간접적으로만 복셀을 편집할 수 있다고 한 이유죠.

매우 뾰쪽한 edge를 가진 메쉬를 생성하는 새로운 알고리듬들도 있긴 합니다. 하지만 이 방법들은 복셀 편집을 위해 만들어진게 아닙니다. (자세한건 다음 섹션에서....)

3. 전통적인 마칭 큐브(marching cube)면 충분합니다
방금 말씀드렸듯이 iso데이터에서 메쉬를 생성하는 새로운 리서치들이 있습니다. 특히 Cubical Marching Square와 Efficient Voxel Octree가 꽤 주목할만한 리서치들인데요.

CMS는 매우 날카로운 edge를 생성할 수 있습니다. 단, 한가지 조건이 있습니다. 폴리곤 데이터로부터 iso값을 capture해야만 하지요. 이 방법은 큐브 표면에서 각 폴리곤 edge가 만나는 거리를 인코딩하는 방법으로 작동하거든요. 근데 실시간으로 이 데이터를 편집하려면(예: C4 engine이나 3D Coat에서 하는 것처럼) 꽤 힘들겠죠?  저도 edge의 교차점을 제대로 보존하면서 이 데이터를 편집할 실용적인 방법을 찾는데 실패했습니다.. ㅠ_ㅠ

EVO는 폴리곤 생성을 하는 기법이 아닙니다. 이건 CUDA에서 레이트레이싱을 하면서 실시간으로 복셀을 화면에 그려주는 기법입니다. 실시간으로 돌리만큼 꽤 빨라요. (보고 꽤 감동받았습니다. 데모한번 실행해보세요 ^_^) 그리고 복셀 데이터를 볼륨이 아닌 표면(2D 비슷한) 데이터로 저장했다는게 꽤 주목할만 합니다. 하지만 똑같은 문제점이 있지요. 이 데이터를 편집할 수 있는 쉬운 방법이 없어요 -_-

즉, 이 새로운 기법들은 모두 폴리곤 데이터를 복셀데이터로 캡춰한 뒤 아무런 수정없이 다시 보여주는데 유용한 방법이란 겁니다.

물론 전통적인 MC와 CMS를 사용해서 메쉬를 생성해내면 결과가 조금 달라집니다. 하지만 폴리곤 데이터를 완벽하게 재현해내는게 목적이 아니라 복셀 데이터 편집이 목적이라면 그 차이점은 무시해도 될 수준입니다. 편집툴에서 고치는 즉시 결과가 보이기만 하면(WYSIWYG) 어떤 방법을 써도 별 차인 없거든요. 하지만 MC가 CMS보다 최소 30% 이상은 빠릅니다. (둘다 최적화를 하지 않은 C# 프로그램에서 테스트해봤습니다. 물론 당연히 멀티쓰레딩은 했구요)

4. 정점버퍼를 최적화하세요
10 x 10 x 10 복셀에서 메쉬를 생성하면 삼각형이 1~2천개 정도 나오는건 예사입니다. 복셀 밀도가 높고 월드가 넓으면, 1500만개 삼각형도 금방 씁니다. 이 엄청난 정점 데이터를 GPU로 보내려면 느리더라구요. 고사양 그래픽 카드와 저사양 그래픽 카드에서 모두 테스트 해봤는데 둘 다 엄청 느렸습니다... -_-

그러니 간단한 정점버퍼 최적화라도 해주세요. 삼각형들 끼리 정점을 공유하고 인접 표면들끼리의 법선을 평균내는 것 등이요. 이러면 정점버퍼의 크기를 30~50% 정도 줄일 수 있습니다.

5. level-of-details을 쓰세요
정점들을 공유하는것 만으론 충분치 않습니다. 1500만개에서 30~50% 세이브해도 여전히 삼각형 수가 800~1000만 정도거든요. LOD 메쉬도 생성해주세요. 복셀 공간에서 메쉬를 생성하려면(아마 그러셔야 할껄요?) 매 n번째 복셀을 샘플링 하는 방법으로 LOD 메쉬를 만들면 됩니다. (LOD1은 매 2번째, LOD2는 매 4번째 등으로요..)

CMS를 사용하면 LOD를 만드는 게 그리 어렵지 않습니다. 이 알고리듬은 교차점 정보를 가지고 있으므로 LOD사이에서 끊김 현상이 없거든요. 하지만 제가 권해드린 것처럼 MC를 사용하신다면 틈이 벌어집니다. 이 틈을 메꾸는걸 아직 시도해보진 않았습니다만.. 만약 그런다면 TransVoxel 알고리즘을 먼저 시도해볼거 같습니다. Don Williams 아저씨도 이 방법을 써서 성공했다더군요.

높은 LOD 폴리곤으로부터 낮은 LOD들을 생성하는 방법도 있습니다. 이러면 복셀 데이터를 직접 사용하지 않아도 되지요. Voxel Farm이 이 방법을 씁니다. 이 방법의 장점이 하나 있는데요. 높은 LOD 메쉬를 재투영(reproject)해서 낮은 LOD 메쉬에 사용할 노말맵을 만들수 있습니다. 하지만 메쉬 단순화(simplification)는 제 입맛에 안맞더군요. 자세한 이유는 역시 다음 섹션에서... -_-

6. 메쉬 단순화(simplication)이 입맛에 안맞을 수도 있습니다
정점 데이터를 최적화 하는 다른 방법으로 메쉬 단순화 기법이 있습니다. Voxel Farm이 이 방법을 사용하고 결과도 그닥 나쁘지 않습니다. 하지만 전 별로 맘에 안들었습니다. 합쳐질 삼각형과 그러지 않을 삼각형들을 제 맘대로 선택할 수 있는 방법이 매우 제약적이기 때문입니다. 이 삼각형들 선택은 어떤 오차계산(error calculation) 알고리듬을 선택하느냐에 따라 다른데요. 모든 경우에 제대로 작동하는 함수를 도무지 찾을 수가 없더라구요.

이 방법이 다른 분들의 용도에 안맞는다는 말은 아닙니다. 그냥 저에겐 안맞았습니다.


자.. 그럼 이정도면 된듯 하니... 즐겁게 복셀을 주무르세요~ 하악x2~

포프

2013년 11월 26일 화요일

알파혼합 가능한 RGBM

RGBM이란?
fat 버퍼(채널당 16비트)를 써서 HDR 렌더타겟을 저장하는게 가장 직관적인 방법입니다. 하지만 이러기엔 속도가 너무 느렸고 메모리도 많이 잡아먹었죠. 그래서 보통 HDR을 8비트/채널 버퍼에 인코딩(패킹)하곤 했었습니다. 다양한 패킹 방법들이 존재하는데 아마 그중에서 가장 널리 사용했던건 RGBM 이었을겁니다. (이 링크에는 LogLUV 패킹 방법에 대해서도 잘 나와있으니 잘 모르시는 분은 읽어보세요...무.. 물론 영어 -_-)

패킹이라... 음.. 좋은 놈이지요... bandwidth하고 메모리 둘다 절약해 줬거든요...

RGBM의 단점
근데 문제가 있었습니다.. 아티스트분들이 엄청 좋아하는거 하나를 할 수 없거든요.. 넵. .알파 블렌딩 입니다.. -_-

RGBM버퍼를 사용하면 알파블렌딩을 할 수 없는게 현실입니다. 달리 말하면 투명한 물체들을 못쓴다는거지요... 왜냐구요? RGBM을 사용할때 블렌딩을 하려면 다음과 같은 공식을 돌려야 합니다.

    ( DestColor * DestMultiplier * InvSrcAlpha + SrcColor * SrcAlpha ) / SrcMultiplier

여기서 몇몇 매개변수들을 좀 살펴보지요.
  • DestMultiplier: DestAlpha 채널에 저장되어있습니다. 블렌딩 유닛이 쉽게 사용할수 있지요
  • SrcMultiplier: 셰이더에서 알파채널로 출력(output)합니다
  • SrcAlpha: 투명값입니다. 근데.. 이걸 어디다 저장하죠? 보통 같으면 알파채널이죠.. 근데 RGBM을 사용하면 .... 이미 multiplier를 알파채널에 출력하니... 바.. 방법이..... 아.. 맞다.. "premultiplied alpha." 라는게 있었죠? 셰이더 안에서 SrcColor에 알파값을 미리 곱해주면 됩니다. 대충 해결했군요.
  • InvSrcAlpha: 하지만 바로 여기가 모든게 개판나는 곳입니다. 투명값을 더 이상 출력하지 않으니 InvSrcAlpha를 블렌딩 유닛에서도 쓸수 없고, 이걸 셰이더안에서 DestColor에 미리 곱해줄 방법도 없지요. 넵.. 망했습니다 -_-;

기존의 해결방법
그래서 이 문제를 해결하기 위해 먼 짓을 했냐구요?.... 아무짓도 안했습니다... -_- 그냥 렌더타겟을 하나 더 만들어서 문제를 피해갔지요. 모든 투명한 물체들을 HDR 인코딩 없이 이 새로운 버퍼에 그렸습니다. 그리고 나중에 그 결과를 신(scene) 버퍼에 합쳤지요.

간단히 말해 불투명(opaque)한 물체들은 HDR에 그리고 투명한 물체들은 LDR에 그리는 겁니다. 하지만 이러면 전체화면(fullscreen) 패스를 한 번 더 돌려서 버퍼들을 합쳐줘야 하므로 속도저하의 문제가 있었습니다. 그래서 속도저하를 좀 줄여보고자 투명버퍼의 크기를 절반 또는 1/4로 줄여주는 꼼수를 쓰기도 했지요.

뭐, 이래저래 여전히 RGBM 버퍼만 하나 쓰는것보단 메모리를 더 먹었습니다.

혼합가능한(Blendable) RGBM
자, 그럼 제가 최근에 고안해낸 꼼수를 알려드리겠습니다. 혼합가능한(Blendable) RGBM이라 이름을 붙였구요. 일단 간단히 요약부터 해보죠.
  • 투명한 물체들을 수학적으로 올바른 방법으로 혼합합니다
    • 따라서 별도의 메모리를 필요로 하지 않습니다.
  • 투명한 픽셀들은 이전에 HDR 버퍼에 그려졌던 불투명 픽셀의 multiplier를 그대로 사용합니다.
  • 하지만 정밀도(precision)의 문제가 생길수 있는데요. 특히 불투명 픽셀과 투명 픽셀의 값이 크게 차이가 날 경우 그렇습니다.
    • 투명 물체가 픽셀값을 어둡게 만들경우 벤딩(bending) 효과가 나타날 수 있습니다.
    • 또, 투명 물체가 픽셀을 어느정도 이상으로 밝게 만들수도 없습니다. (불투명 픽셀의 multiplier가 허용하는 것 이상으로 밝게 만드는게 불가능합니다)
자..그럼 이제 좀 차근차근 대충대충 설명해보죠..

일단 수학공식에 맞추기
RGBM 혼합공식을 다시 봅시다:

    ( DestColor * DestMultiplier * InvSrcAlpha + SrcColor * SrcAlpha ) / SrcMultiplier

InvSrcAlpha 때문에 망했다고 전에 말씀드렸죠? 이건 셰이더에서 알파채널 값에 SrcMultiplier를 넣기 때문이었습니다. 그럼 이걸 어떻게 해결할까요? 간단 합니다.. 그냥 SrcMultiplier를 버리면 됩니다.. -_-;;;;; 농담이 아닙니다.. -_-;;;; SrcMultiplier와 DestMultiplier를 같게 만들면 됩니다. 즉 DestMultiplier만 쓰면 되죠. 이따위 짓을 하고 나면 공식이 이렇게 변합니다:

    ( DestColor * DestMultiplier * InvSrcAlpha + SrcColor * SrcAlpha ) / DestMultiplier

이걸 풀면 이렇게 간단히 되죠.

    DestColor * InvSrcAlpha + SrcColor * SrcAlpha  / DestMultiplier

자, 이제 알파채널을 사용하지 않으니 SrcAlpha를 그냥 알파채널에 써주면 됩니다. 끝~


올바른 블렌딩 렌더스테이트 설정
전 하드웨어 블렌딩 연산을 가지고 노는걸 좋아합니다. 가끔 기발한 짓을 할수 있거든요. 예전에 스크린 스페이스 데칼 만들 때도 그런짓을 했지요. 이번에도 또 사고쳤답니다 -_- ㅋㅋ

위에서 보여드렸던 블렌딩 공식에 껴 맞추려면 다음과 같이 렌더스테이트를 바꿔주면 됩니다:
  • SrcBlend: DestAlpha
  • DestBlend: InvSrcAlpha
이렇게 하고나면 위의 혼합공식에 매우 가까워졌지요. 하지만 아직 한가지가 빠져있군요. SrcAlpha를 곱해주는 부분입니다. 이미 SrcBlend를 DestAlpha로 해줬으니 SrcAlpha를 블렌딩 하드웨어에 설정해줄 방법은 없군요. 해법이 뭐냐구요? 전에 했던것처럼 그냥 premultiplied alpha를 다시 쓰면 됩니다. ^_^  셰이더에서 SrcColor에 SrcAlpha를 미리 곱해주세요.

자, 그럼 모두 다 해결된건가요?.... 불행히도 아닙니다.. ( -_-)  위 블렌딩 스테이트 까지 설정해준 다음엔 공식이 이렇게 되거든요.

    DestColour * InvSrcAlpha + SrcColor * SrcAlpha * DestMultiplier

퉤.. -_- DestMultiplier를 나눠줘야 하는데 곱해주고 있군요.... 이걸 고치려면 RGBM 인코딩/디코딩 하는 법을 좀 바꿔주면 됩니다.

RGBM 인코딩/디코딩 방법 바꾸기
RGBM 인코딩/디코딩을 하는 오리지날 방법은 다음과 같습니다.
  • M: max(RGB)
  • encoding: RGB / M
  • decoding: RGB * M
  • alpha encoding: M / 6
이걸 제대로 돌게 만드려면 M을 역으로 뒤집어주면 됩니다. 그러면 인코딩시엔 곱하고 디코딩시엔 나눠줄 수 있습니다. M을 뒤집어주면 대충 이렇게 됩니다.

  • M: 1 / clamp( length(RGB), 1, 6 )
  • encoding: RGB * M
  • decoding: RGB / M
  • alpha encoding: M
max(RGB)대신에 length(RGB)를 사용한 이유는 나중에 투명한 물체가 픽셀을 더 밝게 만들 수 있도록 좀 마진(margin)을 준것입니다. 여기서 M을 계산하는 방법은 좀 핵(hack)이라 생각하는데요. 저 공식에 있는 1(두번 나옴)을 0.125같이 작은 수로 바꾸면 LDR에서 정밀도(precision)가 좀 더 나을겁니다. 그런데 이걸 1으로 두면 나중에 투명패스에서 사용할 수 있는 색상값의 범위가 최소한 0~1은 되니.. 그걸 보장하기 위해 저렇게 뒀습니다.. 뭐든간에... 이것보다 훨씬 괜찮은 M 계산법을 다른 분들이 찾아낼거라 믿습니다... :)

드디어 새로운 블렌딩 공식!
이제 이리저리 다 뜯어 고쳤으니 드디어 공식이 완성되었습니다:

    ( DestColor / DestMultiplier * InvSrcAlpha + SrcColor * SrcAlpha ) * DestMultiplier

이걸 전개하면 다음과 같이 됩니다.

    DestColour * InvSrcAlpha + SrcColor * SrcAlpha * DestMultiplier

무하하하하 -_- 블렌딩 렌더스테이트에서 나온 계산하고 똑같죠? 드디어 완성되었습니다.. -_-v

Alpha 쓰기 끄기
잠만요.. 근데 투명값을 알파채널로 출력(output)해주면 HDR 버퍼에 이미 적혀있던 multiplier를 덮어 쓰겠네요? 그럼 안되지요. 알파값은 블렌딩 유닛에서만 필요한거니, 이게 렌더타겟에 적히는 걸 막아야합니다.

이것도 역시 렌더스테이트에서 alpha 쓰기를 마스킹해주는 것만으로 간단히 해결됩니다.

가산혼합(Additive Blending)
제 방법은 가산혼합과도 잘 동작합니다. 블렌딩 스테이트를 다음과 같이 바꿔주세요
  • SrcBlend: DestAlpha
  • DestBlend: One
주의점
앞서 밝혔다 싶이, 이 방법에는 두가지 단점이 있습니다.
  • 투명한 물체가 픽셀을 너무 어둡게 만들면 벤딩효과가 보일겁니다. 정밀도가 모잘라서 인데요. 이건 이미 버퍼에 있던 픽셀들이 HDR 영역에 있었을때만 보이는 현상입니다.
  • 투명한 물체가 픽셀값을 어느정도 이상으로 밝게 만들지 못합니다. 여기서 어느정도라 하면 불투명 픽셀들이 내뱉어낸 multiplier에서 허용하는 한도입니다.

혼합가능한 RGBM을 어느상황에나 사용할 수 있는건 아닙니다. 특별한 상황에서만 사용가능한데요. 실제 게임 만들면서 그런 상황을 본적이 있습니다. 뭐든간에 성능 또는 메모리상의 이유로 버퍼를 따로 하나 만들수 없고 비주얼 퀄리티를 약간 희생시킬 수 있다면 사용하세요. 결국 비주얼 퀄리티와 메모리간의 밸런스 문제니까요.


p.s.
새로운 콘솔용 게임을 만드시는 분들에게 HDR 패킹은 더이상 필요없을지도 모르겠습니다. 하지만 아직도 후진(?) 하드웨어 용으로 게임을 만드시는 분들이 계실테니, 그분들께 도움이 되었으면 하는 맘에서 오랜만에 동영상이 아닌 블로그 글을 썼습니다.. ^_^


포프였습니다.


2013년 10월 16일 수요일

[KGC 2013] 컴오히의2의 겨울 렌더링 기법

제 전 동료 다니엘이 KGC 2013에서 강연했던 컴오히2의 겨울 렌더링 테크 발표입니다. 다니엘의 부탁으로 제 블로그에 따로 올립니다..



2013년 6월 10일 월요일

밉맵 디테일 높이기

벌써 5년넘게 써오고 있는 방법인데 생각보다 모르시는 분들이 많은 것 같아 이방법을 공유합니다.

밉맵?

일단 밉맵이 뭔지는 다 아시리라 생각하고 굳이 밉맵에 대해서는 설명하지 않겠습니다.  모르시는 분들은 여길 참고하세요.

문제점 및 일반적인 해결책

밉맵을 사용하다보면 정말 카메라를 가까이 들이밀지 않는한 텍스처의 디테일이 흐릿해 보이는 경우가 흔히 발생합니다.  보통 다음과 같은 방법들로 해결합니다.

흔히 쓰는 해결법 1 - 텍스처 크기 늘리기

밉레벨이 낮아질수록 텍스처 크기가 절반씩 줄어드는 거니 젤 높은 디테일의 밉멥 텍스처크기를 크게 키워주면 그만큼 흐려지는 현상이 덜합니다. 하지만 메모리를 많이 잡아먹는다는 단점이 있어서 정 필요한 때만 제한적으로 사용하곤 합니다. (왜 흔히 라고 한거지 그럼 -_-)

흔히 쓰는 해결법 2 - 밉맵 바이어스 쓰기

이걸 고치기 위해 흔히 쓰는 해결법은 밉맵 bias를 조절하는 방법입니다. 샘플러스테이트에서 정해주는 방법도 있고 셰이더에서 해주는 법도 있습니다. 뭐든 나쁜 방법은 아니고 가장 널리 쓰는 방법인데 여러가지 단점이 있습니다


  1. 고디테일의 텍스처(크기가 큼)를 더 많이 쓰도록 bias를 주므로 텍스처 캐쉬의 성능저하 (그만큼 넣어야할 데이터가 많으니)
  2. 밉맵이 원래 해결하려고 하는 거리에 따른 애일리어싱 문제가 쉽게 더 생긴다.
  3. 모든 경우에 적당히 잘 동작하는 bias 값을 찾기가 쉽지 않다.

흔히 쓰는 해결법 3 - 밉맵 생성시 사용하는 필터 다르게 사용하기

보통 bilinear 필터를 사용해서 밉맵을 만드는게 일반적입니다. 그럼 그냥 주변에 있는 이웃 픽셀들 2x2개 모아다가 균등하게 혼합하는게 전부입니다. 이 외에 kaiser 필터 등을 사용하면 좀더 낫다고 해서 그렇게 하는 사람들을 봤지만... 개인적으로는 별 효과가 없다고 생각합니다.


제 해결법 - sharpening filter

생각보다 매우 간단합니다. 그냥 밉맵 텍스처에 sharpening 필터 한번 더 먹여주면 됩니다. -_- 사실 밉맵들이 흐릿해 보이는 이유가 bilinear 필터링만 쓰면 그냥 경계를 뭉게버린다는건데 여기다 sharpening 필터 한번 먹여주면 경계부분은 다시 적당히 또렷하게 살아나거든요... 

오프라인 프로세스라 게임성능에 지장도 없고... 흔히 쓰는 해결법 2에서 말씀드렸던 단점들도 없습니다.. 그냥 밉맵만드실때 이런순서로 만들어 주시면 됩니다.
  1. 밉맵 0으로부터 밉맵 1 생성 (bilinear filter)
  2. 밉맵 1에 sharpening filter 적용
  3. 2번 결과물로부터 밉맵 2 생성(bilinear filter)
  4. 밉맵 2에 sharpening filter 적용
  5. 밉맵 끝까지 만들때까지 반복...

이 방법을 대충 포토샵으로 흉내낸걸 보여드리면 대충 이렇습니다. 오른쪽이 제 방법입니다.










2013년 5월 20일 월요일

1080P 이상의 디스플레이...


오늘 공원벤치에서 비맞으며 앉아있다가 한 생각...


드디어 제임스 카메론 아저씨의 아바타 영화를 봤다. (DVD로..)... 꽤 괜찮은 영화였는데... DVD화질을 1080P 디스플레이에서 보니 별로더라.. DVD는 480P지 아마..? 이제 사람들이 1080P 영상을 하도봐버릇 해서 DVD 품질이 구려보이는 현상.. 흑 -_-;; 심지어는 유튜브 비디오가 DVD보다 품질이 좋아보인다...

그럼 이젠 무슨 일이 일어날까? 1080P이상의 디스플레이가 필요할까?... 한동안 사람의 눈은 수백만개 픽셀 이상을 보지 못하므로 1080P 을 넘는 디스플레이는 쓸모없다고 믿는게 통설이었던거 같다..(1080P는 대략 2백만 픽셀이 나온다)... 하지만 사람의 눈의 그보다 많은 픽셀을 볼수 있단다.. 대략 6억화소... -_-; 그럼 당연히 1080P 이상이 필요하겠지...




그렇다면 어느날 TV가 이정도 이상의 픽셀을 지원하겠지..? 그럼 여기서 TV의 해상도를 더이상 높이지 않아도 될까...?  음.. 그건 아니라고 생각한다..인간의 눈이 한계가 아니라... 제조비용이 높아지는게 한계일듯 하다. 계산의 편의를 위해 인간의 눈이 대략 10억개의 픽셀을 볼수 있다고 해보자.. 그러면 40억개 픽셀이 달린 TV가 있다면... 인간의 눈의 4개의 픽셀을 하나로 인지할 것이다. 즉 4개의 픽셀을 혼합해서 하나로 만든것과 마찬가지 결과... 어... 그럼 이건 말그대로 4x 슈퍼샘플링 안티앨리어싱(SSAA)이 아닌가...? 160억개 화소면 16x 슈퍼샘플링 SSAA고... 이.. 이거 신나는걸? -_-;

하지만 앞에서도 말했듯이 픽셀을 더 추가하는게 너무 비싸질 지도 모른다... 하지만 LED가격이 계속 떨어지고 있고 LED의 소비전력도 매년 낮아지는 추세니.. 이건 문제가 아닐지도 모른다... 오히려 물리법칙의 한계상 더이상 픽셀을 추가하지 못하는 현상이 생기진 않을까? 싱글코어 CPU를 더이상 빠르게 만들지 못하게 된것 처럼....? 그럴지도.. 하지만 일단 6억픽셀부터 따라잡으려면 시간이 좀 걸릴거 같다 -_-;

2013년 1월 3일 목요일

쓸모없는 회의

정확히 기억은 안나는데 아마도 애플사의 일 진행법을 소개하는 프리젠테이션이었던거 같다. 거기서 한 말중에 기억에 남는 게...

  • 모든 회의의 끝에는 결정(액션 플랜)을 내릴 것
  • 결정을 내리지 않을 회의는 하지도 말 것
  • 결정을 내릴 권한이 없는 직원은 회의에 포함시키지 말 것

원래부터 쓸모없는 회의에 들어가서 시간낭비하는 걸 싫어했던 나에게 참 괜찮게 들리는 이야기였다. 

그 후, 어떤 회의에 초대되어 들어갔다. 한두시간에 끝나는 회의가 아니라 한 3일간에 걸쳐서 하는 회의였고 참여자만도 20명정도 되었는데  회의의 주제는 '차세대 그래픽'이었다.

정확히 회의가 어떻게 진행는지 아무도 내게 말해준 적이 없어서... 

'대체 무슨 회의지?'

하는 생각에 들어갔는데... 이런 저런 새로운 그래픽 기법들이 있는데 자기 팀에서는 어떤 시도를 해봤는지 그리고 앞으로 어떻게 사용할건지 등을 공유하는 거였다. 뭐 결과적으론 시그래프 등에서 볼 수 있는 내용들을 그냥 반복하는 정도랄까... 차이점이라면 

"우린 이거 시도해봤는데 너무 느려서 실제 게임에선 못쓰겠어요."

라고 (주로) 실패한 경험을 공유하는 정도... 이쯤 이야기하면

"아, 대단히 값진 회의였군요."

라고 말할 사람들이 있을지도 모르겠다. 솔직히 말하면 시간낭비였다. 게임쪽에서 차세대 그래픽이 그리 엄청난 도약을 하지 않을 것이라는 건 이제 누구나 아는 이야기이다. 전세대에서 현세대로 넘어올 때 처럼의 엄청난 도약은 없을거란 말...

근데 회의를 마치는 날에 회의 진행자가 갑자기 말하더라. 이 회의의 끝에는 액션 플랜을 만들어야 한다고... 

'아, 이 사람도 그 프리젠테이션을 봤구나.'

라는 생각이 들었는데 사실 유쾌하기 보다는 좀 실망스러웠다고 할까? 왜냐면 그 프리젠테이션에서 전하고자 하는 의미를 제대로 이해 못한 채, 어설프게 흉내내며 시간만 더 낭비하는 느낌이었다.

우리가 만든 액션플랜은 한 대 여섯개 되었는데 이건 사실 다음과 같이 한 줄로 요약이 가능했다. 

"이런 이런 기법이 있다. 하지만 게임에서 사용하기엔 너무 느림. 도구와 파이프라인의 효율성을 높이는데 더 주력해야 할 것"

이건 회의를 들어가기 전에 회의 세부일정을 보고 이미 생각한 거였다. 나 뿐 아니라 회의 참가자들 모두가 같은 생각을 했을 거라 생각한다. (아니라면 그놈들 실력을 심각히 의심해봐야할 듯...).어차피 뻔히 알고 있는 내용으로 결론을 내릴 것을 20명이나 되는 시니어 그래픽 프로그래머들의 시간을 3일이나 낭비시킬 이유가 있는건지....

위의 프리젠테이션에 다음 내용을 추가해야만 이런 쓸모없는 시간낭비를 막을 수 있을 거 같다.
  • 이미 알고 있는 결정을 내릴 회의는 하지도 말 것