[GpGiki 대문으로]

그림자 기법


여러가지 그림자 생성, 렌더링 기법들을 정리해 봅시다.

기하 기반

그림자 입체(shadow volume) - 빛을 가릴 물체의 외곽선을 구성하는 기하구조를 실시간으로 계산하는 것이 핵심.

스텐실 그림자 - 그림자 입체의 한 구현 방식으로, 렌더링 시 가려지는 픽셀과 가려지지 않는 픽셀을 선별하기 위해 스텐실 버퍼를 이용한다(이 측면은 픽셀 기반이라고도 할 수 있음).

정점 투영 그림자 - 물체의 정점들을 특정 표면에 투영해서 그림자 색으로 한 번 더 그려주는 방식. 외곽선 검출이나 텍스처 매핑은 필요가 없으나 그림자가 드리워질 기하구조가 단순해야 함.

기준 평면 그림자 - 정점 투영 그림자의 특별한 형태로 그림자가 드리워질 표면이 축에 정렬된 평면인 경우이다.

무한 거리에 광원이 있다는 가정하에서 메쉬를 원하는 기준 평면으로 변환(transform)을 해서 그림자를 그리는 기법 : 평면에만 가능하다. 그림자에 원근감이 없다.(물론 가능한 방법도 존재한다.)

픽셀 기반

텍스처 투영 그림자 - 그림자로 쓰일 텍스쳐를 먼저 만든 후 수신 객체에 투영 텍스쳐링기법을 이용해서 그림자를 그리는 방법 : Self Shadow를 구현하기 힘들다. back projection, shiny through문제가 있다.

그림자 매핑 - 광원을 시점으로 해서 빛을 가릴 물체를 버퍼에 렌더링하고 그것을 텍스처로 장면에 적용(즉 매핑)한다는 것이 핵심. 텍스처 투영 그림자의 일종(실시간 그림자 텍스처 생성).

광원에서 깊이값을 가지고 있는 그림자 텍스쳐를 만든 후, 카메라에서의 깊이값과 비교해서 깊이값이 다르면 그림자를 만든다. : Self Shadow가 구현이 된다.

그림자가 드리워질 픽셀과 아닌 픽셀의 선별을 위해 Z 값을 사용하는 경우 Z 버퍼 그림자라고도 함. (용어 통일 필요...)

기타

미리 그림자 맵 또는 그림자 입체를 만들어 두는 방식도 있다. 이런 개념은 2D 게임 시절부터 있었다(RPG에서 캐릭터 발 밑의 동그란 검은 원 등).

비교

그림자 입체

CPU에서 수행할 계산량이 많고 부드러운 그림자(가장자리가 뭉개진 모습)를 만들기 어렵다. 부드러운 그림자를 만들기 위해서는 jittering기법을 이용해야한다.

스텐실 버퍼를 쓰고 읽는 부담도 상당히 크다(최신 카드 기능을 이용한다면 어느 정도 줄일 수 있다).

frustum에서 near,far plane을 벗어나는 볼륨부분이 있을 때 문제가 생긴다.(카멕 아저씨가 해결책을 이미 제시했다 - CarmacksReverse.)


스텐실 쉐도우 기법의 장점

그림자를 받는 부분 (receiver) 의 복잡성 (즉, 몇개의 폴리곤으로 이루어졌는지, 몇개의 오브젝트로 이루어졌는지) 에 대해 전혀 영향을 받지 않는다. 따라서 그림자를 드리울 물체 (caster) 가 간단하게 생겼다면 다른 어떤 기법보다도 메리트가 있다.

Fill-rate 를 많이 소비하지만, 이것은 shadow-volume 을 얼마나 extrude 할지 모르기 때문에 낭비하게 되는 부분이 많다. RTS 같이 대부분의 유닛이 지면에 붙어다니는 형식이라면 어느정도 볼륨을 extrude 할지 쉽게 판단할 수 있으므로 낭비를 줄일 수 있다.

스텐실 쉐도우 기법의 구현예 :

  1. 직접 silhouette 를 detect 해서 원 모델로부터 최적화된 shadow volume 을 추출해 낸 후에, 그 volume 을 rendering 하는 방법. 동적으로 폴리곤을 만들어 내는 것이기 때문에 CPU 의 부담과, Vertex buffer 의 내용이 자꾸 변경된다는 단점이 있다.
  2. Vertex shader 를 이용해서 back-facing polygon 들을 뒤로 뽑아내는 방법 - 간단하고 CPU 부담이 없으며 vertex buffer 가 그대로 유지되며, shader 를 쓰는 것만으로 그릴 수 있지만 외곽부분에 폴리곤 갯수가 적은 경우에 면 모양의 변형이 일어난다
  3. Vertex shader 를 이용하고, degenerated quad 들을 삽입해놓았다가 back-facing polygon 들을 뽑는 경우 - 2 번과 비슷하지만 충분한 여백을 갖고 있기 때문에 어느방향으로 extrude 를 하더라도 외곽부분의 변형이 일어나지 않는다. 대신 vertex 의 양이 많아지고 (vertex 는 그대로 있고 index 만 많아지는 것으로 구현 가능할 것 같다), 전처리 작업이 필요해진다

그림자 매핑

CPU의 계산량은 많지 않지만 기본적으로 렌더링이 두 번 일어나야 한다.

텍스쳐를 이용하는 것이기 때문에 aspect ratio에 따라서 그림자가 약간 찌그러져 보일 수도 있고 작은 해상도의 텍스쳐를 사용하면 질이 떨어진다. 반대로 큰 해상도를 사용하면 속도가 느려진다.

텍스처 필터링에 의해 부드러운 그림자를 비교적 쉽게 얻을 수 있다.

정점 투영 그림자, 기준 평면 그림자

용도가 제한적이다. 그러나 유닛들이 많이 나오는 그리고 야외 지형이 주가 되는 실시간 게임이라면 유용할 것이다.

참고자료

http://www.spirit3d.net/cgi/ez2000/ezboard.cgi?db=freeboard&action=read&dbf=386&page=0&depth=4, neolith

http://www.spirit3d.net/cgi/ez2000/ezboard.cgi?db=freeboard&action=read&dbf=384&page=0&depth=5, toki

Game Programming Gems

Game Programming Gems 2

DirectX 실시간 렌더링 실전 테크닉

게임 프로그래머에게 배우는 게임 개발 테크닉

GameCodeOrg 의 방대한 링크 - http://www.gamecode.org/resource.php3?current=shadow


분류 그래픽프로그래밍


제일 위로
최종 수정 일시: 03월 23일(2003년) 01:31 AM 편집 | 정보 | 차이 | 비슷한 페이지 DebugInfo
유용한 페이지들: 분류 분류 | 자유로운 연습장 SandBox | 무작위 페이지들 RandomPages | 인기있는 페이지들 MostPopular