꽃미남 프로그래머 김포프가 창립한 탑 프로그래머 양성 교육 기관 POCU 아카데미 오픈!
절찬리에 수강생 모집 중!
프로그래밍 언어 입문서가 아닌 프로그래밍 기초 개념 입문서
문과생, 비전공자를 위한 프로그래밍 입문책입니다.
jobGuid 꽃미남 프로그래머 "Pope Kim"님의 이론이나 수학에 치우치지 않고 실무에 곧바로 쓸 수 있는 실용적인 셰이더 프로그래밍 입문서 #겁나친절 jobGuid "1판의내용"에 "새로바뀐북미게임업계분위기"와 "비자관련정보", "1판을 기반으로 북미취업에 성공하신 분들의 생생한 경험담"을 담았습니다.
Posted by 알 수 없는 사용자


< 밸브님들이 이런거 하기는 쫌... >


1) 밸브 선생님들이 만들 새로운 하드웨어에 대해서 감히 제가 썰 좀 풀어보자면.. 일단 혁신을 추구한다니 마이크로소프트랑 소니와 같이 스펙 싸움을 할 콘솔기기를 만들지는 않을 것 같습니다. 그렇다고 OUYA 처럼 저가, 저사양 콘솔은 혁신이라고 하기엔 좀 그렇고...



< Oculus Rift >


< 4분 40초부터 잘 봐주세요 >


2) VR헤드셋 Oculus Rift, 여러 구루들이 어썸어썸 그러는거 보면 Oculus Rift의 가능성은 매우 높은 것으로 기대됩니다. 실제 체험 동영상을 자세히 살펴보면 사용자들이 앞으로 움직이려고 순간적으로 상체를 숙이는 동작들이 나옵니다. 그만큼 Rift의 체험성이 강하다는 뜻이겠죠.


3) Oculus Rift 체험 동영상을 보시면 체험성을 떨어트리는 요인은 컨트롤러 부분인데요. Kinect를 활용하자니 앞이 보이지 않는 상태에서 전신 운동은 너무 위험해 보이고, 앉아서 해야 하는데 그러기에 기존 컨트롤러는 체험성을 떨어트립니다.


4) 제 생각에 밸브님들은 Oculus Rift와 같은 VR헤드셋과 손가락 모션캡쳐에 쓰이는 데이터 글러브를 결합한 게임 컨트롤러를 만들 것 같습니다. 의자에 앉아서 상체를 전부 활용하는 가상체험(VR)을 제공하는 것이죠.





5) 데이터 글러브는 위 영상처럼 손가락의 관절 움직임을 캡쳐하는 장갑입니다. 밸브님들은 여기에 더해서 헤드셋과 장갑의 상대적 위치값도 뽑아낼 것 입니다. 장갑에 자이로 센서를 달아서 방향도 알아낼 것 입니다.



< 이 팔과 손가락은 내가 움직이는데로 움직이게 됩니다 >


6) Oculus Rift + 데이터 글러브(손의 위치, 방향, 관절 각도), 이 조합이 어떤 체험을 주냐면, 의자에 앉아 있는 상태에서 내 눈 앞에 3D 환경이 펼쳐져 있는데 캐릭터의 양 팔이 보이고 내 팔과 손가락이 움직이는대로 캐릭터의 팔과 손가락이 움직이게 됩니다.




7) 게임의 UI는 데드스페이스 처럼 구성될 것 입니다. 허공에 검지로 클릭하듯이 손가락질을 하게 되면 3D 환경에서 캐릭터의 손가락이 그 지점을 클릭하게 될 것 입니다.



< VR헤드셋을 머리에 쓰고 장갑끼고 이 자세로 게이밍;;;; >


8) 게임플레이는 사용자가 마치 소총을 어깨 견착하듯이 대충 그런 자세를 잡고 왼손 검지를 앞으로 피면 캐릭터가 이동하고 방향이동은 고개를 돌려서 합니다. 오른손 검지를 방아쇠 당기듯이 접으면 총이 발사되고 엄지를 들면 탄창교환을 합니다. 근접전에서는 사용자가 주먹질 하는대로 캐릭터가 주먹을 뻗게 됩니다. 문을 열 때는 손바닥으로 앞을 탁 칩니다.



 

< 5DT사 제품들 >


9) VR헤드셋과 데이터 글러브는 새로운 개념이 아닌 기존에 VR분야에서 제품화된 것들이 있습니다. 하지만 5DT사의 홈페이지를 보면 데이터 글러브만 하더라도 양 손 + 무선키트가 합쳐서 3백만원이 넘고 VR헤드셋은 400만원이 넘습니다. 강력한 가상체험을 제공해준다해도 가격이 30~40만원대가 넘어가면 대중화되기 어려울 것 같습니다.


10) 여기까지 그냥 개인적으로 짐작해본 썰입니다ㅋㅋ 썰은 썰일뿐 신뢰하지 말자~





반응형
,
Posted by 친절한티스

요즘 파이썬을 만지작 거리며 재미를 붙이고 있는 친절한티스입니다. 요게 쓰면 쓸수록 매력적인 언어네요. 최근에는 파이썬을 이용해 Unity Build Maker를 만들어 유용하게 사용 중입니다.


그런데 이 파이썬 스크립트가 기본적으로는 파이썬이 설치 되어있는 환경에서만 작동이 됩니다. 만약 제가 파이썬으로 유용한 툴을 만들었는데 이것을 다른 컴퓨터에서 쓰기 위해서는 그 컴퓨터에도 파이썬을 설치 해주어야 합니다. 조금 껄쩍찌근 해지죠. 하지만 작성한 파이썬 스크립트를 실행 파일로 만들수 있다면 단지 그 실행 파일만 복사해서 실행만 해주면 됩니다. 참으로 편리 해지겠죠?



파이썬 스크립트를 실행 파일 형태로 변환 하는것은 의외로 간단합니다. 이미 py2exe 라는 유용한 변환 라이브러리가 존재합니다. 일단, py2exe 홈페이지에 가서 자신의 파이썬 버전에 맞는 라이브러리 버전을 다운로드 하여 설치합니다.


py2exe 바로 가기


그 다음 setup.py 파일을 하나 만들어서 아래와 같이 코드를 추가해줍니다.

from distutils.core import setup
import py2exe

setup(console=['hello.py'])

hello.py 부분에는 실행 파일로 변환 시키고픈 자신의 파이썬 스크립트 파일명을 적어주시면 됩니다. 그 다음 명령창에 아래와 같이 입력을 하시면...


> python setup.py py2exe


무언가가 마구마구 실행되는 듯 하더니 dist 폴더 안에 짠~ 하고 실행 파일로 변환된 자신의 파이썬 스크립트 파일이 나타납니다.



그런데 dist 폴더안에 실행 파일만 있는 것이 아니라 기타 잡스러운 파일들도 많이 보입니다. 막상 실행 파일만 떼어다가 다른 곳에서 실행 시켜보면 정상 작동을 안하고, 같이 있던 잡스러운 파일들을 같이 넣어주어야만 작동을 하는 것을 확인 할 수 있습니다.


잡스러운 파일들의 용도


실행 파일로 변환 된것은 좋은데 꼭 잡스러운 파일들까지 같이 딸려보낼려니까 왠지 찝찝한 기분을 떨쳐낼수가 없습니다. 파일 하나로 깔끔하게 변환할 수 있는 방법은 없는지 좀더 찾아 보니 방법이 존재하더군요.


아까 생성한 setup.py의 코드를 아래와 같이 변경 시켜줍니다.

from distutils.core import setup
import py2exe, sys, os

sys.argv.append('py2exe')

setup(
    options = {'py2exe': {'bundle_files': 1}},
    windows = [{'script': "hello.py"}],
    zipfile = None,
)

아까와 같이 hello.py 에는 자신의 파이썬 스크립트 명을 적어줍니다. 그 다음 명령창에 다시 명령어를 입력해주면... 짜잔!! 아까와 다르게 dist 폴더에 잡다한 파일은 없어지고, 실행 파일 하나만 생성된 것을 확인 할 수 있습니다.



반응형
,
Posted by 알 수 없는 사용자

제가 연재하는 날은 아니지만, 최근 플밍 관련 글도 자주 올라오지 않고, 겸사 겸사 정리하고 있던 내용도 있던 찰나에 불쑥 제가 한번 난입했습니다. ㅎㅎㅎ.

 

다들 DirectX11 공부를 하고 계신지 모르겠군요. DirectX11이 언제 대중화 될지는 모르겠지만, 언리얼4 등의 테크 데모를 보니, 이젠 DirectX9로는 표현력과 성능 상의 한계가 온 것 같다는 생각이 들기도 하고, 향후에는 확실히 더 높은 퀄리티의 그래픽을 만들어내기 위해서는 DirectX11으로 옮겨 갈 것같다는 생각에 저도 DirectX11 공부를 시작했습니다.

하지만, 공부를 시작하면서 뭘 어떻게 시작해야 할지 몰라서, 꽤 헤맸는데요. 그 이유는 일단 관련 서적이 부족해서 기반 지식을 무엇으로 익혀야 할지 턱 막히는 기분이었고, MSDN과 같은 경우에도 DirectX11의 경우에는 DirectX10을 기반으로 DirectX11에 대한 내용이 쓰여져 있기 때문에, DirectX11로만 찾아보면 별로 내용이 없더라구요. 거기에 DirectX11이 DirectX9과 비교해서는 굉장히 많은 부분이 바뀌어서, 머리 속에는 DirectX9에 대한 지식이 들어있는데, 이게 되려 발목을 잡아서, 뭐가 어떻게 바뀌었는지를 일일이 찾아서 확인해야만 하니 학습 속도가 어느 정도까지는 엄청 늦더란말이죠... (물론, 제가 머리가 나빠서 그런거에요.. ㅎㅎ)

암튼 그렇게 그렇게 틈틈히 공부를 한 달 정도 했더니, 아주 약간은 익숙해 졌고, 이제는 아키텍쳐를 조금 이해가 되기도 하고, DirectX9와 비교해서 "아~ 그래서 이렇게 바꿨겠구나~" 라는 것도 조금씩 느끼게 되면서 나름 재밌어지기 시작했습니다. ㅎㅎ

제가 한 달 정도 보면서 DirectX9와 비교해서 헷갈린 부분들이 참 많은데요. 그 중에, Buffer 관련한 것들을 공부하다가 가장 헷갈렸던 것이 바로 이 Lock 관련한 내용인데요! 오늘은 이것을 정리해보려고 합니다.


[DirectX9에서의 Buffer(or Texture)의 Lock 처리]

DirectX9에서는 Lock에 대해서는 뭐 저보다 다들 잘 아실테니 특별히 설명을 할 필요가 없겠죠?! ㅎㅎ. 기억을 되살리기 위해서, DX9의 Lock 에 대해서 간단히 볼까요?

뭐, 간단하게 정리하자면, Static Buffer(or Texture) 이냐 Dynamic Buffer(or Texture)이냐에 따라서 어떻게 Lock을 설정하느냐? 라는 문제가 되겠습니다. 일반적으로 Static Buffer의 경우에는 D3DPOOL_MANAGED / D3DUSAGE_WRITEONLY로 버퍼를 생성하고, D3DLOCK_DISCARD를 사용해서 Lock을 수행합니다. Dynamic Buffer에 대해서는 D3DPOOL_DEFAULT / D3DUAGE_DYNAMIC(+D3DUSAGE_WRITEONLY) 로 버퍼를 생성하고 D3DLOCK_DISCARD(or D3DLOCK_NOOVERWRITE)를 사용하여 Lock을  처리하고요.


[DirectX11에서의 Buffer의 Lock 처리]

먼저, DirectX11에서 Buffer를 만드는 방법부터 보도록 하겠습니다. 이 부분은 아주 크게 다르지는 않습니다. Buffer를 생성할 때 중요한 것은 DirectX9와 동일하고, "Static Buffer를 만들 것인가? Dynamic Buffer를 만들 것인가?"의 문제입니다.

DirectX11에서는 Buffer를 생성할 때, D3D11_BUFFER_DESC 구조체의 Usage와 CPUAccessFlags 항목을 통해서 Static / Dynamic 여부를 결정하게 됩니다. 그럼 Static / Dynamic Buffer에 대해서 어떻게 설정하게 되는지 알아보도록 하겠습니다.

if (dynamic == true)
{
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
}
else
{
desc.Usage = D3D11_USAGE_DEFAULT;
desc.CPUAccessFlags = 0;
}

Buffer의 성격은 사실 Usage를 어떻게 설정하느냐? 에 따라서 결정이 되구요. 그 성격에 따라서, Lock 이나 다른 옵션들은 거기에 맞추어 주어야 합니다. Usage의 설정은 다음과 같습니다. 

D3D11_USAGE_DEFAULT
  - GPU에 의해 read/write 가능
        D3D11_USAGE_IMMUTABLE
- GPU에 의해 오직 read 할 수 있다. 모든 CPU에서 접근 불가! 반드시 생성할 때 초기화되어야 한다. 생성 후 변경 불가 D3D11_USAGE_DYNAMIC
- GPU에서 read 가능 CPU에서 쓰기 가능, 매 프레임마다 cpu에서 업데이트 할 때 사용. Map을 통해서 업데이트 한다.
D3D11_USAGE_STAGING
- GPU에서 CPU로 데이터 이동(복사)를 지원한다. 즉, 읽기만 가능

이제 위의 코드가 조금 이해가 되시겠지요? Immutable의 경우에는 생성할 때 한번 데이터가 설정되면, 이 버퍼는 변경이 될 수 없습니다. 따라서, Lock을 한다거나 하는 것 자체가 되지 않습니다. 그렇다고 Default로 설정했을 때보다 특별하게 더 나은 성능을 주는 것은 아니라고 합니다. 그래서 일반적으로 Static Buffer의 경우에는 Default로 생성합니다.  여기까지는 약간 다르긴 해도 특별히 DirectX9와 비교해서 쉽게 이해할만 합니다. 

자, 이렇게 Buffer를 생성했다면, 데이터를 채우기 위해서는 DirectX9에서는 Lock을 사용했습니다. 그런데, DirectX11에서는 Lock이라는 함수는 존재하지 않습니다. 대신, Map ~ Unmap 이라는 것과 UpdateSubResource 라는 함수를 이용해야 한다고 하네요. 음... 이제부터가 문제입니다. 과연 언제, Map ~ Unmap을 사용하고, UpdateSubResource를 사용해야 하는 것일까요? 아마도, DirectX9의 경험으로 봤을 때, "Static / Dynamic Buffer에 따라서, 설정하는 방식이 다르지 않을까?" 라는 정도를 유추해볼 수 있겠네요.

* Map ~ Unmap과 UpdateSubResource에 대해서는 설명하기에는 내용이 너무 길어지기 때문에, msdn이나 강좌를 참고하도록 하겠습니다.
- UpdateSubResource : http://msdn.microsoft.com/en-us/library/windows/desktop/ff476486(v=vs.85).aspx
- Map : http://msdn.microsoft.com/en-us/library/windows/desktop/ff476457(v=vs.85).aspx

"How to: Create Vertex Buffer" 페이지를 참고하면 다음과 같이 나와있습니다.

Here are some ways to initialize a vertex buffer that changes over time.

  1. Create a 2nd buffer with D3D11_USAGE_STAGING; fill the second buffer using ID3D11DeviceContext::Map,ID3D11DeviceContext::Unmap; use ID3D11DeviceContext::CopyResource to copy from the staging buffer to the default buffer.
  2. Use ID3D11DeviceContext::UpdateSubresource to copy data from memory.
  3. Create a buffer with D3D11_USAGE_DYNAMIC, and fill it with ID3D11DeviceContext::MapID3D11DeviceContext::Unmap (using the Discard and NoOverwrite flags appropriately).

#1 and #2 are useful for content that changes less than once per frame. In general, GPU reads will be fast and CPU updates will be slower.

#3 is useful for content that changes more than once per frame. In general, GPU reads will be slower, but CPU updates will be faster.

정리가 참 잘 되어있네요. 하지만, 이 정도로는 정보가 조금 부족해서 좀 더 자료를 찾아보았습니다. 

제가 찾던 정보가 여기 다 있네요. 간단하게 정리하면 이렇군요.

  • Default Buffer의 경우, UpdateSubResource를 사용해서만 업데이트 할 수 있다.
    • RenderTarget에서 사용할 때 좋다. 
    • 자주 업데이트 되지 않는 (프레임 당 한번 이하) 텍스쳐에도 괜찮다.
    • Vertex / Index Buffer에서 Dynamic이 아닐 경우, 사용.
  • Immutable Buffer의 경우, 초기에 한번 설정되면 끝난다.
    • Default 보다 좋은 성능을 주는 것은 아니다.
  • Dynamic Buffer의 경우, Map ~ Unmap을 사용한다.
    • Discard, NoOverwrite 사용가능
    • 프레임당 한번 이상 자주 업데이트 되는 Dynamic Texture나 Dynamic Vertex/Index Buffer에 적합하다.
  • Staging Buffer의 경우, Map ~ Unmap만 사용가능
    • 읽기만 가능!
    • Double Buffering 으로 사용한다.
  • Constant Buffer는 UpdateSubResource로 업데이트 한다.
    • Constant Buffer는 예외적으로 매우 자주 업데이트 된다.
    • GPU가 아니라 시스템 메모리에서 시스템 메모리로 카피해서 최소한으로 GPU에 전달하도록 하는 것이 좋다.

여기에 추가적으로 몇 가지 이슈가 더 있습니다. DirectX11에서 지원하는 Multithread Rendering의 경우에는 어떻게 처리할 것인가? 부분 갱신을 할 때에는 어떤 함수를 사용하는가? 같은 문제들을 어떻게 처리해야 하는지도 같이 봐야 합니다. (사실 저는 아직 여기까지 정리를 하지 못했네요.. ㅎㅎ)

[마무리]
지금까지 (제 생각에는) DirectX9 -> DirectX11로 넘어가면서 많이 혼란스러웠던 부분 중에 하나인 Buffer 생성 및 Lock 에 대해서 정리해보았습니다. 아직 저도 공부를 계속 하는 중이라서 많이 알지는 못하지만, 저도 공부하면서 관련 자료(특히, 국내 자료)가 부족해서 시간이 꽤 걸렸던 부분들에 대해서는 가능하면 정리를 해볼 생각입니다.

DirectX11을 공부하면서 느낀 점은 DirectX9에 비해서 API가 참 정리가 잘 되었다는 점과, 자료 검색을 하면서 해외 포럼들을 보니까, 꾸준히 DX10을 보다가 DX11을 넘어와서 크게 어려움이 없어하는 반면에, 국내에는 DX10을 거의 관심을 많이 가지지 않았기 때문에 DX11을 바로 넘어가면서 더 많은 어려움을 느끼는 듯 합니다.   

그래픽스 API를 꾸준히 공부하시는 분들도 많을텐데, 이런 부분들도 좀 더 활발하게 공유가 되었으면 하는 바램입니다. 

참 공부할 게 많은 요즘이군요... ㅎㅎㅎ. 




반응형
,
Posted by 대마왕J

예압. 잘 계셨었었었나요???!?

15강의 시간이 돌아왔습니다! 힘세고 강한 15강!

원래 날짜는 1일인데 먼저 썼길래 걍 올립니다 ...

 

만약 내게 물어보면 나는 대마왕.

 

요새 계속 좀 어려운 얘기를 하고 있는 것 같습니다.

제가 얘기했잖아요 ㅋ 초반 10강 까지가 커피면, 10강 이후부터는 T.O.P입니다 ㅋ
확실히 슬슬 중반까지는 온 것 같은데... 나름 길게 천천히 설명했다고 생각했으면서도 사실은 너무 급하게 들어간게 아닐까 라는 생각이 듭니다.

중간에 흑백 이미지 만들기라던가 그런거 한 두 번 더 들어가서 좀 더 익숙해 지게 만들었어야 하는 게 아니었나..? 싶었다는.

일단 dot 나오면서부터 좀 수준이 달라져서 말이죠. 으흠. 뭐 그렇지만 이왕 시작한거 일단가고...

일단 생각해 둔건 이제 노말맵에 대한 설명... 그리고 스페큘러에 대한 설명... 정도까지 생각하고 있습니다.
렌더타겟이 안되니 더 깊은 수준도 애매하고... 반사벡터를 이용한 큐브맵? 아... 이건 1부에 했었어야 했구나....
1부에 큐브맵과 흑백/세피아 만들기를 했어야 했던 것 같아요. (아닌데 큐브맵 반사벡터 제대로 설명하려면 1부에 안되는데 아이씨... OTL 뭐야 몰라 무서워)

여기에 감마 코렉션이나 HDR 같은, 중요하지만 실습하기는 엄청나게 곤란한 그런 것들까지 할 수 있으면 얼마나 좋을까.. 라는 욕심이 들지만 뾰족한 방법이 생각나지 않는다는게 문제입니다. 뭐 저도 HDR을 사용할 줄만 알지 구현해 본적은 없기도 하고 ㅋㅋㅋ 에이 몰라 일단 노말맵과 스페큘러까지만 해도 거의 책 한권에 달할 분량이므로 거기까지 하고 나서 생각해 보렵니다.

자, 오래간만에 말씀드리지만, 이 강의는 '그래픽 아티스트를 위한 ' 강의입니다. 그래서 설명이 지나치게 자세하고, 다소 뛰어넘는게 있더라도 어떻게 하면 쉽고 재미있게 배울 수 있을까에 중점을 둔 원고입니다. 그 점 잊지 말아 주세요. 이해 안되는건 바로바로 리플 달아 주시구요.   

 

자 그럼...

오늘은 지난 번에 이은, '진짜 재밌는' 부분인 Dot 연산의 응용에 대해 계속 얘기해 보겠습니다.

 

1. 지난 강의의 줄거리

 

잊어버리셨을지도 모르지만...

저번 14강의의 핵심내용은 아래와 같죠.

dot(닷) 연산이란 것이 있고, 이걸로 '-조명 벡터'와 '노말벡터' 두 벡터를 연산하면, [각주:1]

두 벡터의 각도 차이에 따라 값이 다르게 나오는데, 대충 아래처럼 나온다는 것이었습니다.  

이 값은 코사인 그래프로 나오는 거라서, 그래프로 표현하면 아래와 같은 모양으로 나오게 되지요.

코사인 그래프처럼 살짝 휘었지요?

그치만 오늘 중요한건 그게 아니라

나오는 값이 1에서 0까지가 아닌,
1에서 -1 까지 나올 수 있다는 것입니다.

 

잊지마라!!!

 

 

여기에 일단 주목해야 해요.

일단 평소 계산할 때는 이 음수값이 오히려 오류가 날 수도 있는 귀찮은 값이라서 ,
음수가 안나오는 옵션을 켜고 계산을 합니다. [각주:2]

 

오늘은 이 봉인을 풀어서 재미있는 짓을 해 보겠습니다!!!

 

아따 재밌것다

 

 

2. 하프 램버트

시작의 발단은 자기네 자료란 자료는 전부 공개하기로 크게 유명하고, 하프 라이프라는 게임으로는 조금 유명한 ㅋ  대인배 밸브 횽아들께서 시그래프 2006년에 발표한 자료에서 시작합니다.

https://developer.valvesoftware.com/wiki/Half_Lambert

 

영어다 ... 영어야... 이히히히히

 

더 뭔 소린지 모르겠어

 

네, 저도 영어만 보면 머리가 멍해져요. 보통 이런거 공부하시는 아티스트 분들도 그렇잖아요. 영어 좋아하시는 아티스트분 얼마나 될까나. 난 지금 아티스트라고 보기도 애매하면서 영어보면 머리아프면 뭐지

그래도 공부해 보겠다고 막 찾아보면, 이런 글이 찾아지죠.

 "램버트 라이팅은 확산반사의 음영처리로 많이 알려진 일반형으로, 시선 방향에 의존하지 않고 광원의 입사방향과 면의 방향(법선 벡터)만으로 계산되는 음영처리 기법이다. 이 기법에는 「그 지점의 밝기는, 면의 방향과 빛의 입사 방향이 이루는 각도θ의 cosθ값에 비례한다」라는 「램버트 코사인법칙」이 정의되어 있지만, 실제로 이것으로 라이팅을 하면 명암이 매우 강렬하게 나오는 특성이 있다.하프라이프2에서는, 이 심하게 변하는 코사인 곡선에 바이어스를 걸어 어두운 부분의 계조(단계영역)를 들어 올리는 생각을 했다. 램버트 코사인 법칙의 코사인 곡선이 절반이 되도록 "1/2"을 곱한 다음, "1/2"을 더하고, 다시 이것을 제곱해서 완만한 곡선으로 변환해서 음영처리를 실시하기 때문에 「"하프" 램버트 라이팅」이라고 한다."

http://allosha.tistory.com/57 에서 인용합니다 .

... 솔직히 저렇게 글쓰는거 이해 안가요. 저거를 알아들으라고 쓴 건지 자기만 알아보려고 암호로 쓴 건지. ㅋ. 
솔직히 그래픽 아티스트들이 알아보기 힘들게 하려고 프로그래머들이 일부러 저렇게 꼬아서 쓴 게 아닐까 하는 음모론이 대두되고 있습니다.  

 

 

그러므로 이런 글을 읽고 나면 우리는 ,

더 뭔 소린지 모르겠어

 

이렇게 됩니다. 늘 이래왔었죠.
이것보다 더 큰 문제는, 일단 몇 번 읽어보고 이해하려고 노력한 후에...

   

"자기 블로그에 이 글을 그대로 복사해 가서 공부한 것인 양 붙여놓고서는, 언젠가는 읽어봐야지 라는 마음을 가진 채 블로그를 조용히 덮고 다시는 열어보지 않지요." [각주:3]

 

 

.....

 

 

 

 

... 자 너무 좌절하시지 말고, 오늘은 그 굴레를 좀 벗어나 보도록 합시다.

 

 

 

3. 하프 램버트는 왜 필요하게 되었는가?

...뭐 자기들이 필요하니까 필요했겠죠. 사실 이게 정답입니다 ㅋ
그렇지만 이렇게 말하면 수업이 안되니까, 일단 이거부터 만들어 보죠.

 

흔한 일반 램버트

 

 

네 지극히 단순한 램버트 공식입니다. 일반적인 라이트이지요.

근데 말입니다. 근데 말이죠.  또 근데 말이죠.

이 라이트 뭔가 좀 구린 것 같지 않아요?

 

그러니까 좀 자세히 보면, 저기 어두운 그림자로 떨어지는 부분, 그 부분이 너무 딱 떨어져 보이지 않느냐고요.
프로그래머들처럼 매정해 보이지 않냐고요 ㅋ

 

 

"괜찮은데 뭐" 라고요?

하긴, 많은 프로그래머들이 초기에 그렇게 얘기했죠 (사실 지금도 많은 프로그래머들은 '괜찮은데 뭐' 라고 말합니다 ㅋㅋ )

그렇지만 우리는 아티스트들이니까, 그렇게 생각하면 안됩니다.
여러분은 이미 이거를 보신 분이잖아요.

이거요 이거.

max에서 스카이라이트 걸고, 라이트 트레이서로 단순하게 건 이 이미지.
그림자도 없지만 이 이미지를 한 번 보고 나면,

 

이 이미지가 멋져 보이지는 않을거 아녜요.

물론 계산 자체의 양이 다르다는건 잘 알아요. 라이트 트레이서 사용하면 저기 위의 이미지 렌더링 하는 것도 한 장에 5초 정도 걸리는데, (제 컴에서) 아래 이미지처럼 게임용(Lambert:램버트)으로, 실시간으로 그리려면 적어도 1/30 초에 그려야 30프레임으로 나올테니까요. 계산 차원이 다르죠.

 

그런데 그렇게 하니까, 이미지가 너무 뭐랄까. 음영이 딱딱하게 져서 안이쁜거예요. 특히 캐릭터에서.

 

램버트를 이용한 캐릭터 조명.

 

캐릭터가 캐릭터처럼 보이게 하는 기법은 사실 굉장히 많고 복잡해요. 사람 피부가 마네킹과 다른 이유는 빛의 반사와 흡수, 투과 등이 완전히 다르기 때문이거든요. [각주:4]

 

아... 구글 검색한 사진인데.. 언젠가 제가 찍어야 겠군요..

 

사람이므니다 사람 2 이니므니다 우리 집 쌍둥이들이므니다 ㅋㅋ 맥락없는 딸자랑 ㅋㅋㅋ

근데 그것 이전에, 일단 빛의 음영부터가 영 아니예요. 아시다시피 실세계에서 저렇게 딱 끊어지는 조명이 나타나는 경우는 거의 없잖아요. 있다면 아주 강한 조명을 쓴 스튜디오 사진 정도?

그러니까, 꽤 어두운 배경에서 왠만큼 강한 조명으로 일직선으로 때리면서 조명을 조절하지 않는 한 저런 환경이 나타니기는 좀 힘들어요. 보통은 강한 빛을 때리면 그 빛이 주변에서 튕겨나와서 다시 뒷면을 밝게 비춰주죠. [각주:5]

게다가 아까 얘기한 것 처럼, 사람 피부라는게 그렇게 딱 끊어지는 확산광을 내놓지도 않아요. 플라스틱이라면 모를까.

 

사람이 아니므니다

 

 

네네 이렇게 여러 가지 이유로, 결론내자면

 

저건 마네킹

주저리주저리 설명하면 뭐해. 마네킹 같고 하여간 싫잖아요.

 

저걸로도 괜찮다고요? 뭐 괜찮을 수도 있겠죠. 네네 전 이해해요. 사람의 가치가 다 똑같은건 아니잖아요.
음영이나 재질같은게 뭐가 중요하겠어요. 그림만 제대로 있으면 되잖아요.  

그러니까 이것도 괜찮으시잖아요 . 그렇죠? ㅋㅋ 게임에는 흔한 빌보드 기법이잖아요.

 

그렇지만 사실은 어쨌건 '저건 구린' 거죠. 구려요.

 

픽사의 초기 작품이 지금 보면 구려 보이는 이유도 , 바로 그 조명의 반사와 투과 때문이잖아요.
근데 사실 게임도 딱 이 전철을 밟아 나가고 있는 거지요. 다른 점이라면 '속도' 가 중요하달까...

 

넹 얘기가 잠시 딴데로 샜는데, 어쨌거나 캐릭터가 나오는 장면에서, 저렇게 '딱 끊어지는 음영이 나오면 안이쁘다' 에서 시작해서, 그걸 개선하고자 밸브 사에서 제작해서 하프-라이프(Half Life) 에서 사용한 램버트 (Lambert) 변형 기법이 바로 하프-램버트 (Half Lambert) 입니다.

물론 이것만으로 캐릭터의 피부 느낌이 해결되진 않지요. 피부의 반사나 투과는 여기서는 완전히 신경쓰지 않고, 그냥 빛 떨어짐만 신경쓰자는 겁니다.  

 

램버트를 이용한 캐릭터 조명.   

 

 

4. 하프 - 램버트 만들기

뭐 알겠습니다. 막상 들어보니까 일단 시작한 이유는 쉽게 알 수 있겠죠? 그냥 '안이쁘니까 이쁘게' 가 모든 일의 발단인 겁니다.[각주:6]

어려운 것 같지만, 이거 사실 굉장히 쉬워요. 게임이라는게 속도에 민감하기 때문에, 사실 어려운 공식을 이렇게 간단하고 쉽게 만들어 내는게 진짜 기술입니다 :)
그래서 그래픽 아티스트들도 쉽게 따라 할 수 있지요. 한번 해 보겠습니다!!

 

자, 시작은 여기서부터입니다.

반도의 흔한 램버트지요. 조명 벡터와 노말벡터를 닷 시킨 후 그 결과물을 라이트 칼라와 곱해준 것을 볼 수 있습니다.

 

우선 해줘야 할 일은, DOT 공식을 선택한 후에, 음수값 제한을 풀어주는 겁니다 .

이제 어두운 부분이 무조건 0이 아니라, 음수값이 나오기 시작하는 거예요. [각주:7]

음수값이 나오기 시작!!! 1에서 -1 까지!!!!

 

눈으로는 별 변화 없습니다만... 이제 dot 값은 위 그림처럼 나오고 있을 겁니다. 
최대값이 1.0 이고, 최소값이 -1.0 인 값으로요.

네. 그러면 진짜 핵심을 한 번 저질러 보죠.

가장 중요한 마법의 주문을 가르쳐 드리겠습니다.
자 모두 따라서 외쳐 보세요! 마법의 주문입니다!!!

*0.5 +0.5

 

이게?

 

이게 왜 마법의 주문이냐고요?

잘 모르시겠다고요?

자, 다시 한 번 다른 그림으로 보여드리죠. 현재 이 상태란 말입니다. 각 지점의 값이 대에에에충 저런 상태예요. 
  

이 수치에 위의 공식을 대입해 보죠.

  1.0 일때 :  1.0 * 0.5 + 0.5 = 1.0
  0.5 일때 :  0.5 * 0.5 + 0.5 = 0.75
  0.0 일때 :  0.0 * 0.5 + 0.5 = 0.5
-0.5 일때 : -0.5 * 0.5 + 0.5 = 0.25
-1.0 일때 : -1.0 * 0.5 + 0.5 = 0.0

놀랍게도, 1.0 ~ -1.0 이었던 수치가, 1.0 에서 0까지로 변했습니다! 이 간단한 공식만으로 말이죠!

 

이제 갑자기 이해가 가는 코사인 그래프..

 

만약 이것을 dot 의 공식 그래프인 코사인 그래프로 보자면, 1에서 -1까지의 범위인 빨강색 그래프가, 1에서 0까지의 범위인 파랑색 그래프로 "끌어 올려진" 결과가 나오는 것이겠지요! 그야말로 마법(Magic)같은 공식이라고 할 수 있겠습니다! [각주:8]

[각주:9]

훌륭합니다.

 

자, 그럼 뭐 이론은 알겠으니까, 이걸 적용하면 어떻게 되는지 한번 보겠습니다.

 

시작은 여기서부터 시작합니다. dot으로 나온 저 결과물에서부터 말이죠.

 

Maps / constant 로 상수를 두 개 만들어 줍니다. 값은 0.5로 넣어 놓지요. 0.5 두 개가 필요하니까요

 

Math/MathOperator 를 이용해서 dot 결과물에 0.5를 곱해주고, 0.5를 더해줍니다. 간단하죠?
이렇게 해서 *0.5+0.5 가 완성되었습니다. 이제 결과물을 볼까요?

 

짜잔.

이전의 그림과 비교해 보세요. 뭔가 어두운게 상당히 뒤로 밀려났죠?

결과물은 어떻게 보이게 될까요?

비교해 봅시다.

 

일반 램버트

하프 램버트

어떻습니까? 어느게 더 '고급 렌더링 처럼' 보이나요? 어떤게 더 글로벌 일루미네이션 기법이 들어간 것처럼 보이나요? 어떤게 더 주변광이 반사되어 영향을 끼친 것 처럼 보이나요?

  

어떤게 위의 그림의 '스카이라이트' 를 이용한 라이트 트레이서의 결과물과 비슷해 보이나요????

 

두 말 할것 없이 하프 램버트 쪽이 훨씬 더 괜찮아 보입니다. 빛도 부드러워 보여요. 단지 0.5를 곱하고 0.5를 더했을 뿐인데 말이죠. [각주:10]

물론 이건 물리적으로는 완전히 말도 안되는 계산 방식입니다 .
이것은 그냥 '좀 더 이쁘게 보이도록' 하는 꼼수로, '마치 GI 라이트를 받은 것 같은 효과'를 가상으로 내기 위해서 만든 공식인 것입니다. Fake 라고요.

 

 

자, 어쨌건 그럼 이렇게 구현해 보고 아래 PT 문서를 한번 더 봅시다.

이제 이해가 되시죠????

하프 램버트를 사용하면 어떻게 되는지 말이죠???

 

 

 

이제 다시 이 글을 읽어보세요.

 "램버트 라이팅은 확산반사의 음영처리로 많이 알려진 일반형으로, 시선 방향에 의존하지 않고 광원의 입사방향과 면의 방향(법선 벡터)만으로 계산되는 음영처리 기법이다. 이 기법에는 「그 지점의 밝기는, 면의 방향과 빛의 입사 방향이 이루는 각도θ의 cosθ값에 비례한다」라는 「램버트 코사인법칙」이 정의되어 있지만, 실제로 이것으로 라이팅을 하면 명암이 매우 강렬하게 나오는 특성이 있다.하프라이프2에서는, 이 심하게 변하는 코사인 곡선에 바이어스를 걸어 어두운 부분의 계조(단계영역)를 들어 올리는 생각을 했다. 램버트 코사인 법칙의 코사인 곡선이 절반이 되도록 "1/2"을 곱한 다음, "1/2"을 더하고, 다시 이것을 제곱해서 완만한 곡선으로 변환해서 음영처리를 실시하기 때문에 「"하프" 램버트 라이팅」이라고 한다."

여전히 읽기 힘들게 씌여진 글이지만, 어쩐지 이해되지 않나요? 거기다가 우리가 한 것 외에 추가적인 무언가도 언급되어 있는 듯 합니다만... 그건 숙제로 내겠습니다.

ps.

숙제가 있습니다.

사실 *0.5 +0.5 를 대입하는 이 공식은, 실무에서 사용하기에 좀 과다하게 부드러운 감이 없지 않습니다.
노말맵 같은 요철까지 너무 죽어 버리곤 해서... 실제로는 조금 그 효과를 줄여서 사용하지요.

줄인다고 하는 것은 뭐 단순하게 뺀다는 것은 아닙니다. 0~1 까지의 숫자가 이미 나와 있는데, 이걸 단순히 빼면 음수가 또 튀어나오게 되지요.

그래서 보통은 이 *0.5+0.5 를 이용해 나온 결과물에, 제곱을 해서 평평해진 음영을 좀 더 날카롭게 해주곤 합니다.

결과물에 제곱을 해 준다...?

자, 이 결과물에 제곱을 한번 해 보세요. 어떻게 되나 보세요. 2배 제곱, 3배,4배 제곱을 해 보세요.

힌트를 가르쳐 드립니다. 제곱하는 함수는 power 라고 부르며, Math에 RaisetoPower 라고 하는 이름의 노드로 존재할 겁니다. (아마도...)

 

ps2.

최근 shaderFX의 다운로드 경로가 막혔습니다.
이전에 무료로 풀던 경로가 없어지고, 주인장이 오토데스크에 취직해서 더 서비스를 안한다는 말이 씌여 있네요...
그러면서도 데모 버전을 받아서 결재하면 사용가능하다는 안내 게시물은 있습니다만, 정작 데모 버전 받는 곳이 없어요...

이전에 사용하던 버전들은 물론 계속 사용이 가능합니다만, 그렇다고 제가 가지고 있는 버전을 여기다가 당당히 올릴 수도 없고 말이죠. (재배포 되나..?)

그래서 고민중입니다. shader FX가 앞으로 이렇게 계속 서비스를 하지 않는다면, 강의를 중단해야 하는건가...? 라고 말이죠. 어떻게 하는 것이 좋을까요?????

 

자 이렇게 해서 15강은 이걸로 끝!!! 아 KGC 강연준비 하러 가야징...

 

  1. 단, 두 벡터의 길이는 1이라는 전제가 붙어야 합니다. 나중에 기회되면 말하겠지만, 이것을 '단위벡터' 또는 'Normailze된 벡터' 라고 합니다. [본문으로]
  2. 코딩으로는, max(0,dot) 함수를 사용하면 되지요. [본문으로]
  3. 제가 그래서 잘 알아요. 크흑. 지금도 스크랩만 해놓은 게시물이 한가득... ㅠㅠ [본문으로]
  4. 흡수는 뭐.. 열 에너지가 되어 사라집니다. 반사와 투과만 보면 돼요. 피부는? 사실 은근히 반투명으로 투과되어요. [본문으로]
  5. G.I (Global Illumination : 전역조명) [본문으로]
  6. 셰이더를 하다 보니까, '물리 원칙에 맞게 만들기 위해서' 만드는 셰이더와 '알게뭐야 그냥 이쁘게' 만드는 셰이더 두 종류가 있더라고요. 저는 당근 후자편. [본문으로]
  7. 일단, 눈으로는 안보일 겁니다 [본문으로]
  8. 보통 이런 것을 그래서 매직 넘버 (Magic Number) 라고 부릅니다. 이론상으로는 복잡하지만, 열심히 연구해서 매우 간단하게 만든 것이지 허접한 것과는 차원이 다른 기술입니다. [본문으로]
  9. 보통 프로그래머들은 코드 안에 이런 '매직 넘버' 같은 상수를 넣어두는 것을 '하드코딩' 이라고 부르면서 안좋아 합니다. 실제로 유지보수할때 곤란해 지는 경우가 많아서 말이죠. 그렇지만 쉐이더는 일종의 외부 스크립트라서, 이런 매직 넘버를 많이 사용하는 편입니다. [본문으로]
  10. 개인적으로는 하프 램버트의 부드러움은 노말맵의 요철 표현까지 부드럽게 만들어 버려서, 저는 저 수치대로 그대로 쓰진 않습니다. 약간 개량해서 사용하죠. [본문으로]
반응형
,
Posted by 알 수 없는 사용자

졸업한지는 꽤 됐지만 요즘도 가끔 학교 동아리 활동하는 데에 가서 찝적대기도 합니다. 유피넬(UPnL)이란 곳인데 게임개발 전문 동아리는 아니지만 요새 게임에 관심 있는 애들도 많은 듯해서 게임 메커니즘 페스티벌이란 행사를 주최했었습니다.

행사 동기와 목적은 다음과 같았습니다.


동기

게임이 재미있는 이유는 무엇일까?

멋진 최신 그래픽, 예쁜 캐릭터…

이런 화려한 외면을 다 벗기더라도 재미있는 게임의 메커니즘은 영혼처럼 남아있지 않을까!


목적

제한된 그림과 소리 자원을 활용해 최대한 재미있는 게임의 메커니즘들을 개발해보자.

여기서 메커니즘은 게임을 세 요소로 나눠서 보는 MDA 모델에서의 메커니즘을 말합니다.

슈퍼마리오에서 가져온 20종의 그림과 인터넷에 떠돌아다니는 적당한 웨이브 파일을 긁어모은 7종의 효과음을 제공했으며 이 그림과 소리 외의 다른 자원을 쓰면 안 되는 것이 규칙이었습니다. 행사는 첫 날 오전 11시부터 오후 11시까지 12시간, 다음 날 오전 11시부터 정오까지 총 13시간을 개발에 사용하고 오후 2시까지 2시간 동안 시연 및 평가 시간을 가졌습니다. (근데 밤 샌 사람들이 많아서 개발 시간은 사실상 24시간 정도...)

개발 기반으론 C# 윈도우 폼 프로젝트에 제공하는 그림, 소리를 쉽게 출력할 수 있는 간단한 프레임워크를 만들어서 제공하였습니다. 사용 언어 제한은 없고 별도의 라이브러리를 사용해도 상관없었지만 제가 짠 기본 프레임워크가 훌륭해서 그런지(?) 참가자 모두 C#을 썼더군요.

총 참가자는 10명 정도... 게임은 모두 6개가 나왔고 심사는 참가자들과 관전자들의 가장 재미있었던 게임을 세 개 적어서 내서 취합하는 형식으로 진행됐습니다. 우승작, 준우승작을 소개해드립니다.

우승작, 돌려라! by 김알찬, 황호기

스테이지를 돌려 물건들을 적절히 이동시켜서 상자에 넣는 게임입니다. 자체 물리 엔진으로 구동되며 물건들이 합쳐지면 다른 물건으로 바뀌는 특징이 있습니다. 스크린샷 예시의 경우엔 아래 상자에 물음표 모양을 넣어야 되는데 있는 건 노란 별과 파란 별 밖에 없죠. 그냥 넣으면 폭발하면서 실패합니다. 노란 별과 파란 별을 합치면 물음표 모양으로 바뀌는데 그걸 상자에 넣어야 합니다. 물건이 남으면 안 된다는 룰도 있고요. 스테이지가 총 11개였던 것 같은데 난이도도 적절하고 재미있어서 몰표를 받고 우승했습니다.

준우승작, 동족상잔 by 심규민

특훈류 (일명 벫똏) 게임으로 자신의 캐릭터를 움직여서 사방에서 날아오는 적들을 피해야 하는 게임입니다. 특이한 점은 적과 부딪쳤을 때 나와 다르게 생긴 적이라면 죽는 게 아니라 그 적으로 변신 된다는 겁니다. 나와 똑같이 생긴 적과 부딪쳤을 때만 죽습니다. 마우스로 총알을 발사해 적을 잡을 수 있는데 나와 똑같이 생긴 적이 점수를 많이 줍니다. 말 그대로 동족상잔을 조장하는 게임. 꽤 어려운 난이도와 그 와중에 네트워크 상으로 구현한 점수 랭킹 시스템 덕에 인기를 끌었습니다.

게임 잼처럼 48시간 동안 사람들 개발하게 만드는 건 너무 비인간적인 것 같아서 처음엔 하루 12시간 만에 개발, 심사까지 다 하려고 했었는데 테스트로 해보니까 역시 시간이 부족하더군요. 공식 시간은 밤 새지 말라고 밤에 끝나도록 정해놨지만 역시 만들다보면 멈출 수 없어서 인간다운 개발은 실패. 차라리 약간 공모전 비슷하게 주제 내주고 한 일주일 정도 기간을 두어서 만들고 싶은 만큼 만든 다음 마지막 날에만 모여서 개발, 심사하는 방식은 어떨까 싶기도 하네요.

막 보자마자 기똥찬 느낌이 딱 드는 메커니즘이 나오진 않은 것 같아서 아쉽지만 첫 술에 배부르랴, 여러 번 하다보면 그런 보물 같은 메커니즘을 발굴할 수도 있지 않을까 싶고요. 그렇게 엄청난 아이디어까진 아니더라도 우승작 같은 경우는 폴리싱 잘 해서 폰 게임으로 만들면 인기가 괜찮을 것 같다는 의견이 많이 있었습니다. 게임들이 애초에 기대했던 것보다도 완성도와 밸런스면에서 좋게 나와서 의외였어요.

게임 회사에서 이런 형식으로 신작 게임의 핵심 메커니즘을 발상해보는 건 어떨까 하는 생각도 들었네요.

반응형
,

Siggraph 2012

기타 2012. 8. 19. 13:26
Posted by 알 수 없는 사용자

많은 분들이 이미 Siggraph에 대한 자료들을 보셨겠지만, 못 보신 분들을 위해서, 발표자료들이 올라온 것들을 전달(RT?)해 드립니다. ㅎ


Real-Time Rendering Blog에 Siggraph 2012의 발표자료들에 대한 소식이 마구 마구 올라오고 있네요... 

여기에 간단하게 링크를 올려봅니다.
 
[Beyond Programmable Shading]

[Advances in Real-Time Rendering in 3D Graphics and Games]

[Siggraph 2012 Links]
http://blog.selfshadow.com/2012/08/11/siggraph-2012-links/

[Optimizing Realistic Rendering with Many-Light Methods]

특이한 점은 Siggraph Mobile Course가 있다는 점인데, Siggraph 2011 Asia 부터 있었나본데, 역시 모바일에 대한 관심이 큰 것은 어쩔 수 없겠네요. (http://s2012.siggraph.org/attendees/siggraph-mobile)

모바일에서의 렌더링 주제들은 도움도 많이 되고, 발전 속도를 보면 엄청 놀라운 것 같아요... ㅎㅎ... 

그냥 틈틈히 보면 좋을 듯 합니다. ㅎㅎ

반응형
,