SlideShare a Scribd company logo
1 of 97
2010/10/23
Devrookie 엠에스박( 박민수 )
 그림자란?
 3D에서의 그림자
 그림자 구현의 역사
 깊이 버퍼 그림자 구현
 시연
 Q & A
 참고자료
 그림자 : 빛이 지나가는 경로에 불투명한
물체가 존재하여 빛이 통과하지 못해 생기
는 어두운 부분.
 물체의 가장자리를 지나가는 빛은 회절 현
상에 의해 물체를 넘어갈 수도 있어서 가장
자리 부분은 비교적 밝은 그림자가 생긴다.
반 그림자 : 흐릿하다.
본 그림자 : 진하다.
 3D에서는 그림자를 크게 2가지로 나눌 수 있다.
그림자
음영
 음영은 보통 Lighting 계산으로 구한다.
 특별한 처리를 하지 않아도 기본적인 파이프라인
에서 음영은 제공해 준다.
 그림자는 애초부터 따로 구현해야 하는 부분이였
다.
 Circle Shadow
 Projected Shadow Mapping
 Stencil Shadow Volume
 Depth Buffer Shadow
 Perspective Shadow Map( PSM )
 Light Space Perspective Shadow Map( LSPSM )
 Cascaded LSPSM
 Soft Shadow
 Variance Shadow Map( VSM )
 3D 그래픽스 매니악스를 훑어보자!
 Circle Shadow
 캐릭터의 위치를 계산하여 발 밑 부분에 원
형의 그림자 텍스쳐를 적용시켜준다.
 다른 캐릭터들도 원형의 그림자를 갖게 되
어 리얼리티가 떨어진다.
캐릭터의 위치정도는
파악할 수 있게 해준다.
 Circle Shadow
 심플하게 생각해보자.
 머리 위에서 캐릭터를 향해 빛이 비친다.
 이 때 쉽게 그림자를 생성하는 법은?
 캐릭터의 y좌표를 땅의 높이로 두고 검은색으
로 렌더링한다!
 심플하게 생각해보자.
빛의 방향
 심플하게 생각해보자.
 빛이 다른 방향에서 비춘다면?
 심플하게 생각해보자.
빛의 방향
 Projected Shadow Mapping
 앞의 아이디어를 기본으로 나온 기법이다.
 광원에서 본 오브젝트의 실루엣을 그림자
텍스쳐에 저장한다.
 광원방향으로 투영하듯 텍스쳐를 매핑한
다.
 Projected Shadow Mapping
캐릭터 형태가
나온다!
 Projected Shadow Mapping
 그림자를 생성하고 적용하는 과정에서 별
다른 연산이 없으므로 호환성이 뛰어나다.
 캐릭터의 모습을 적용할 수 있다.
 매 프레임마다 그림자를 갱신해 줘야 하는
이슈가 있지만 멀리 있는 녀석의 그림자는
생략하는 등 트릭으로 극복가능.
 Projected Shadow Mapping
 문제점 1 : 셀프 그림자가 적용되지 않는다.
이런 것
들
이런 것
들
이런 것
들
 Projected Shadow Mapping
 문제점 1 : 셀프 그림자가 적용되지 않는다.
 왜냐하면 그림자가 오브젝트 단위로 생성
되기 때문이다.
 그렇기 때문에 오브젝트 자신의 차폐를 계
산하기 어렵다.
 Projected Shadow Mapping
 문제점 2 : 투영을 잘 시켜야 한다.
 Projected Shadow Mapping
 문제점 2 : 투영을 잘 시켜야 한다.
 계산을 잘 못하면 벽 넘어에 그림자가 생기
는등 버그가 발생 할 수 있다.
 Stencil Shadow Volume
 셀프 쉐도우를 위해서는 광원을 기준으로
차폐 여부를 가지고 그림자를 적용해야 한
다.
 Stencil Shadow Volume
셀프 쉐도우
볼륨
 Stencil Shadow Volume
 일단 씬을 렌더링하고 깊이정보를 저장한다.
 오브젝트의 외곽에 있는 버텍스를 광원방향
으로 잡아 늘린다.
 앞서 저장한 깊이정보와 그림자 볼륨을 비교
하여 그림자인지 아닌지를 스텐실 버퍼에 기
록한다.
 최종 렌더링시에 스텐실 버퍼를 참고하여 그
림자를 그린다.
 Stencil Shadow Volume
그림자 볼륨 중 앞에 면만
스텐실 버퍼에 1로 기록한다.
*계산 전에 스텐실 버퍼를
0으로 초기화 해두자!
 Stencil Shadow Volume
볼륨의 뒷면은 -1로 그려준다.
 Stencil Shadow Volume
1인 부분을 그림자로 보면 된다.
 Stencil Shadow Volume
 광원이 여러 개가 있거나 오브젝트가 서로
겹치는 등 경우에 따라서 스텐실 버퍼의 값
이 1보다 클 수도 있다.
 0이 아니면 그림자로 생각해도 무방하다!
 Stencil Shadow Volume
 깊이정보를 이용해서 차폐를 계산했기 때
문에 셀프쉐도우가 가능해 졌다.
 기타 다른 그림자의 문제도 해결된 듯 보인
다!
 Stencil Shadow Volume
 구현을 보면 알겠지만 그림자를 처리할 때
폴리곤 단위로 처리를 한다.
 아까는 오브젝트가 그림자 단위였는데 폴
리곤 단위니 전보다 세밀해 졌다!
 Stencil Shadow Volume
잎사귀 텍스쳐도 어차피
네모판일 뿐…
 Stencil Shadow Volume
그림자가 사각형이다.
 Stencil Shadow Volume
 볼륨을 생성하는 부분도 생각을 해봐야 한
다.
 잘못 늘리면 그 만큼 그림자가 잘못 생성된
다.
 Stencil Shadow Volume
 그리고 원래 캐릭터의 모양을 유지하면서
정점을 늘려야 하기 때문에 늘릴 정점이 따
로 필요하다.
 보이는 것보다 더 많은 정점이 쓰이게 된다.
 Stencil Shadow Volume
 Stencil Shadow Volume
 하지만 이전 Direct10 스터디 때도 나왔듯
이 정점을 생성해주는 쉐이더가 추가 되었
기 때문에 위의 문제점은 해결이 될 듯 하
다.
 Depth Buffer Shadow
 위의 Stencil Shadow Volume도 문제가 있
다.
 그런데 GPU는 발전해가고 픽셀 계산능력
이 올라가면서 Depth Buffer Shadow 기법
이 사용되기 시작했다.
 Depth Buffer Shadow
 광원을 기준으로 오브젝트들과의 거리( 깊
이 )를 저장한다.( 그림자 맵 )
 실제 렌더링 시에 다시 광원과 오브젝트의
거리를 비교하고 위에서 저장해둔 차폐 정
보를 비교하여 그림자를 판별하고 적용한
다.
 Depth Buffer Shadow 광원의 시점에서 깊이가 저장되면
노란색 부분은 기록되고 주황색 부분은
묻히게 된다.
위에서 무시된 부분이
그림자가 됨을 알 수 있다.
 Depth Buffer Shadow
위에서 저장된 값은 결국 광원이
도달하는 부분이다.
실제 렌더링할 때 다시 한번 광원과
오브젝트의 거리를 재서 위에 저장한
값과 비교해 보고 그림자인지 아닌지
판단한다.
D > S : 그림자
D == S : 그림자 아님
 Depth Buffer Shadow
 차폐 정보를 이용해 처리한 것이니까 셀프
쉐도우가 가능하다.
 아까는 폴리곤 단위였지만 지금은 픽셀 단
위이므로 위의 문제도 해결된다.
 Depth Buffer Shadow
 모든 구현에는 문제점이 존재한다.
 픽셀 단위의 구현으로 인해 그림자 맵의 해
상도가 적으면 그만큼 그림자의 세밀함이
떨어지게 된다.
 Depth Buffer Shadow
픽셀 돋네..
 Depth Buffer Shadow
 해결방안은??
 그림자 맵의 해상도를 높인다. -> 한계가 있다.
 요즘 게임 특히 야외를 보여주는 게임은 점점
먼 곳 까지 보여주기 때문에 커버할 수 없다.
 그래도 해상도만 괜찮으면 쓸만한 그림자니까
개량해서 사용해야 겠다!
 Perspective Shadow Map( PSM )
 그림자 맵 해상도 이슈가 발생하는 이유는
간단하다.
 게임 상의 오브젝트들을 모두 그림자 맵에
담기 때문에 넓을 수록 한 텍셀이 표현해야
할 그림자 영역이 점점 넓어지다 보니 품질
이 떨어지게 된다.
 Perspective Shadow Map( PSM )
 위의 구현 방법은 맵이 100m x 100m면 전
체를 그림자 맵에 담아서 사용하게 된다.
 텍스쳐 사이즈가 256 x 256이면 한 텍셀은
40cm x 40cm가 된다고 보면 된다.
 Perspective Shadow Map( PSM )
 시점이 가까운 곳이나 먼 곳이나 동일한 해
상도를 사용하게 된다. 먼 곳에 있는 녀석
들은 자세히 그릴 필요가 없지 않은가?
 가까운 녀석에게 해상도를 집중하고 먼 녀
석은 대충 그려주자가 PSM의 목적이다.
 Perspective Shadow Map( PSM )
 시점에서 가까운 곳과 먼 곳은 카메라에 의
해 결정된다. ( View )
 가까운 물체는 커보이고 멀리 있는 물체는
작아보인다. ( Projection )
 View x Projection 변환된 녀석을 그림자 맵
으로 뽑아내자!
 Perspective Shadow Map( PSM )
기존에 쉐도우 맵을 뽑을 때완 달리 가까운 녀석의
비중이 더 커지게 그림자 맵을 생성할 수 있다.
 Perspective Shadow Map( PSM )
 Perspective Shadow Map( PSM )
 Perspective Shadow Map( PSM )
 기존의 그림자 맵보다 효율적으로 만들 수
있어서 더 매끄러운 그림자가 나온다.
 이런 부분만 보면 완벽할 것 같다!!
 Perspective Shadow Map( PSM )
 PSM은 광원을 기준으로 그림자 맵을 생성
한다. 따라서 광원에선 멀리 있는 그림자를
카메라 시점에서는 가까이 볼 수도 있다.
 이 때는 마찬가지로 그림자의 품질이 떨어
진다.
 Perspective Shadow Map( PSM )
 PSM은 광원을 기준으로 그림자 맵을 생성
한다. 따라서 광원을 기준으로 보이는 녀석
들에 대해서만 그림자 맵을 만들게 된다.
 오브젝트는 보이지 않지만 그림자만 보여
야 하는 상황에서는 올바르게 그림자가 생
성되지 않을 수 있다.
 Light Space Perspective Shadow Map( LSPSM )
 PSM의 문제를 해결하기 위해 개량된 방법을 제
시하였다. 그것이 바로 LSPSM이다.
 위의 문제를 정리하면 광원 기준의 그림자 생성
과 보이지 않는 오브젝트가 있을 수 있다는 것이
다.
 Light Space Perspective Shadow Map( LSPSM )
 하지만 저런 특정 상황을 제외하고는 그림자 맵
을 카메라에 맞게 옮겨서 생성하는 아이디어는
괜찮은 것 같다.
 그렇다면 위의 문제를 해결하면서 그림자 맵을
옮겨서 생성하자!
 그림자 맵 생성을 위한 좌표계를 만들어 내고 그림자를 생성하자!
 Light Space Perspective Shadow Map( LSPSM )
 그림자를 생성할 가능성이 있는 오브젝트는 모두
포함시키게 시야 거리를 조정한다.
 최대한의 해상도를 구하기 위해 최대한 가까운
곳에서 그림자 맵을 뽑아낸다.
 좌표계는 다음과 같은 방식으로 생각해 볼 수 있
다.
 Light Space Perspective Shadow Map( LSPSM )
 빛의 방향의 반대되는 방향을 Y축
 뷰 벡터와 Y축을 외적해서 구한 방향을 X축
 X축과 Y축을 외적해서 구한 방향을 Z축
 Light Space Perspective Shadow Map( LSPSM )
PSM은 뒷 부분 그림자의 품질이 낮다.
 Light Space Perspective Shadow Map( LSPSM )
LSPSM은 뒷 부분 그림자까지 제대로 그려준다.
 Cascaded LSPSM
 LSPSM을 가지고 좋은 그림자를 생성해 냈으나
점점 더 야외 맵은 넓어지고 멀리 보이게 되고 있
다.
 LSPSM을 이용해 처리를 해도 마찬가지로 먼 곳
까지는 텍스쳐 해상도의 한계에 부딪치게 된다.
 Cascaded LSPSM
 해상도에 한계가 있어서 계속 그림자 맵을 효율
적으로 생성하는 것에만 신경을 쓰다가 그림자
맵을 여러 개 두면 되지 않을까? 로 생각이 넘어
오게 된다.
 지금까지 구현을 보아 가까운 녀석에게는 그림자
해상도를 많이 투자하는게 맞고 먼 녀석에게는
적게 투자하더라도 어느정도는 투자가 되어야 한
다.
 Cascaded LSPSM
 근거리용 그림자 맵( 가까운 물체의 해상도는 높
게 )
 중거리용 그림자 맵( 중간 물체도 위보단 높게 )
 장거리용 그림자 맵( 멀리있는 물체도 최소한 보
이게 )
 이런식으로 나누면 되겠구나!
 물론 게임마다 거리를 나누는 기준과 몇 단계로 나눌
것이냐는 따로 정해야 한다.
 Cascaded LSPSM
 Cascaded LSPSM
 Soft Shadow
 지금까지 그림자 맵을 찍는 부분에 대해서
만 생각해 왔다.
 문제는 그림자 품질이 떨어지는 현상이다.
 Post Processing으로 해결할 수 있지 않을
까?
 Soft Shadow
 계단현상이 생긴 부분을 뭉게버리자!
 뭉게지면 부드러워 지고 실제 그림자의 뿌
연 느낌도 줄 수 있을 것 같다!
 Soft Shadow
뭉게기 전 뭉게기 후
그림을 확대해서 둘 다 뭉게진 듯 하지만 자세히 보면 보인다.
 Soft Shadow
뭉게기 전 뭉게기 후
 Soft Shadow
 Post Processing이다 보니 격렬하게 뭉게
면 3D모델 렌더링에 영향을 끼칠 수 있다.
 Soft Shadow역시 이것 저것 개량해서 쓰면
좋은 퀄리티를 낼 수 있겠다. ( 이건 다음
에.. )
 Variance Shadow Map( VSM )
 언리얼 엔진 3.0에서 사용한다고 한다.
 그림자 맵에 광원에서 오브젝트까지의 거
리와 그 제곱값을 저장한다.
 이 값을 이용해 그림자가 생길 확률을 계산
하고 그림자를 입혀준다.
 Variance Shadow Map( VSM )
 VSM을 위한 그림자 맵을 만들기 위해서는
부동 소수점을 저장하는 텍스쳐를 이용해
야 한다.
 이 기법을 이용하면 소프트 쉐도우와 같은
구현이 된다고 한다.
 Variance Shadow Map( VSM )
 기존의 그림자 맵은 그림자다 아니다.
 0 아니면 1 이런 느낌.
 반면 VSM은 체비쇼프 부등식을 이용하여 깊
이값을 기반으로 빛이 비치는 정도를 확률로
구한다.
 빛이 안 비칠 확률이 높을 수록 어둡게 만든다.
 나름 자연스러운 그림자 완성!
 Variance Shadow Map( VSM )
 그 중에서 깊이 버퍼 그림자 구현 부분을
자세히 알아보자.
 깊이 버퍼 그림자 구현의 기초를 이해하면
나머지 그림자 구현을 이해하는데 도움이
될 것이다.
 깊이 버퍼 그림자는 2패스로 진행된다.
 그림자 맵 생성
▪ 광원의 위치에서 본 장면을 렌더링한다.
▪ 렌더링 할 색은 광원으로 부터의 거리로 한다.
 그림자 맵과 실제 거리 비교 후 그림자 적용
▪ 그림자 맵이 가리키는 픽셀 값과 실제 거리를 비교한
다.
▪ 그림자 맵이 가리키는 픽셀 값이 더 작으면 그림자다.
 그림자 맵 생성
 그림자 맵을 저장하기 위한 텍스쳐를 생성한다.
 그림자 맵 생성시 사용할 깊이 버퍼를 만든다.
 렌더 타겟과 깊이 버퍼를 만든 녀석들로 바꾼다.
 그림자 맵에 맞게 뷰포트를 잡아준다.
 장면을 렌더링 한다.
 뷰포트 , 깊이 버퍼 , 렌더 타겟을 복구한다.
 그림자 맵 생성
 전에 포스트 이펙트 발표 때를 기억하시면 됩니
다.
 이따가 소스를 간단하게 훑어 보겠습니다.
 그림자 맵 생성
 광원에서 본 장면을 렌더링해야 한다.
 장면을 그리기 위해 넘어온 좌표들을 광원을 중심으
로 한 행렬로 변환해야 한다.
 광원을 중심으로 한 행렬 구하기
 월드 행렬 x 뷰 행렬 x 투영 행렬
 광원위치를 기준으로한 뷰 행렬
 광원을 기준으로 적당한 FOV등을 설정한 투영 행렬
 그림자 맵 생성
 버텍스 쉐이더
 버텍스들을 광원을 중심으로한 행렬로 변환한다.
 픽셀 쉐이더에서 깊이값을 저장할 수 있게 변환된 위
치를
넘겨 준다.
 픽셀 쉐이더
 넘어온 변환된 위치를 이용해 깊이 값을 저장시킨다.
 깊이 : z / w ( 0 ~ 1 값 )
 그림자 맵 생성
 그림자 맵 생성
 위의 소스를 보면 z / w 구문이 픽셀 쉐이더에
있음을 알 수 있다.
 버텍스 쉐이더에서 계산을 하는게 더 빨라 보이
지만 값이 불안정해 질 수 있다.
 픽셀 쉐이더에서는 버텍스 사이 사이에 있는 픽
셀들의 값을 채워줘야 한다.
 그림자 맵 생성
 우리가 원하는 깊이의 저장은 이런 모습이다.
 두 버텍스 p0 = ( z0 , w0 ) , p1 = ( z1 , w1 )가 있다고
하고 이 버텍스들의 중심 부분을 얻어온다고 생각해
보자.
 z’ = ( ( z0 + z1 ) / 2 )
( ( w0 + w1 ) / 2 )
 하지만 버텍스 쉐이더에서 먼저 계산을 하고 넘
긴다면? 오차가 날 것이다.
 z’ = ( ( z0 ) + ( z1 ) ) * 1
( ( w0 ) ( w1 ) ) 2
 그림자 맵 적용
 퍼스펙티브 보정에 의한 보간에서는 비선형 깊
이가 바르게 보간 되지 않는단다…
 비선형 깊이가 무엇인가 하면 투영행렬까지 거
친 위치정보는 원근처리가 되어있기 때문에 깊
이값을 구하면 선형적인 값이 나오지 않는다.
 그렇기 때문에 깔끔하게 픽셀쉐이더에서 그 순
간 깊이를 계산해서 저장하는 것이다.
 그림자 맵 적용
 그렇단 말은 선형적인 값을 갖는 깊이를 버텍스
쉐이더에서 계산할 수 있으면 그냥 픽셀 쉐이더
에 넘겨줘도 된다는 말이다.
 선형 깊이를 구하는 식은
 z’ = ( z - zn ) * ( zf )
( zf - zn ) ( z )
 그림자 맵 적용
( x , y , z , 1 )을 변환하면?
( w * x , h * y , Q * z – Q * Zn , z )
Z와 W만 집중해서 봅시다!
( Q * z – Q * Zn ) / W
-> ( Zf * z ) – ( Zf * Zn ) * ( 1 )
( Zf – Zn ) ( Zf – Zn ) ( z )
-> ( Zf * ( z – Zn ) )
z * ( Zf – Zn )
 그림자 맵과 실제 거리 비교 후 그림자 적용
 그림자 맵을 만들었으니 그림자 맵을 이용하자.
 렌더링할 때 그림자 맵을 매핑할 수 있어야 한
다.
 그림자 맵 : X : ( -1 , 1 ) , Y : ( -1 , 1 ) , Z : ( 0 ,
1 ) 텍스쳐의 UV : X : ( 0 , 1 ) , Y : ( 0 , 1 )
 그림자 맵을 UV좌표계로 변환해 보자.
 U = +0.5X + 0.5
 V = - 0.5Y + 0.5
 그림자 맵과 실제 거리 비교 후 그림자 적용
 위의 변환식을 행렬로 묶으면?( -1 , 1 ) -> ( 0 ,
1 )
 ( 0.5 0 0 0.5 )
( 0 -0.5 0 0.5 )
( 0 0 1 0 )
( 0 0 0 1 )
 그림자 맵과 실제 거리 비교 후 그림자 적용
 투영했을 때 ( 0 , 1 )범위로 갔다는 것은 w = 1,
즉 W값으로 나누었다는 이야기가 된다. W로
나누기 전이라면 다음과 같이 적용해야 한다.
 ( 0.5 0 0 0.5 + ( x / w ) )
( 0 -0.5 0 0.5 + ( y / w ) )
( 0 0 1 0 )
( 0 0 0 1 )
 그림자 맵과 실제 거리 비교 후 그림자 적용
X = 1 , Y = 1 , W = SHADOW_MAP_SIZE
 그림자 맵과 실제 거리 비교 후 그림자 적용
 그림자 맵과 실제 거리 비교 후 그림자 적용
 조명 처리를 위한 부분은 제외하고 보면
 Out.ShadowMapUV = mul(Pos, mWLPB);
 그림자 맵을 입히기 위해서 변환한다.
 Out.Depth = mul(Pos, mWLP);
 그림자 맵의 값과 거리를 비교하기 위해 변환한다.
 그림자 맵과 실제 거리 비교 후 그림자 적용
 그림자 맵과 실제 거리 비교 후 그림자 적용
 거리비교 부분
 그림자 맵의 값을 얻어온다.
 현재 투영된 녀석과 거리를 맞추기 위해 w값을 곱한
다.
 그 값을 z값과 비교한다.
 Bias를 막기 위해 0.03이라는 마법의 숫자를 넣었다.
 그림자 맵의 깊이보다 넘어온 녀석이 크면 그림자!
 아니면 그냥 텍스쳐 디퓨즈 색.
 최종적으로 조명계산까지 덧 붙인다.
 http://ko.wikipedia.org/wiki/%EA%B7%B8%EB%A6%BC%EC%9E%90 - 그림자
 http://allosha.tistory.com/ - 알로샤님 블로그
 http://en.wikipedia.org/wiki/Shadow_volume - Stencil Shadow Volume Wiki
 http://x66vx.egloos.com/3808794 - PSM ~ PPSM까지 정리해 주셨음.
 http://www-sop.inria.fr/reves/Marc.Stamminger/psm/ PSM 정리
The End

More Related Content

What's hot

김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019
김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019
김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019
devCAT Studio, NEXON
 
5강 알파와알파소팅
5강 알파와알파소팅5강 알파와알파소팅
5강 알파와알파소팅
JP Jung
 
Hierachical z Map Occlusion Culling
Hierachical z Map Occlusion CullingHierachical z Map Occlusion Culling
Hierachical z Map Occlusion Culling
YEONG-CHEON YOU
 
Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술
Ndc2010 전형규   마비노기2 캐릭터 렌더링 기술Ndc2010 전형규   마비노기2 캐릭터 렌더링 기술
Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술
henjeon
 

What's hot (20)

Shadow mapping 정리
Shadow mapping 정리Shadow mapping 정리
Shadow mapping 정리
 
Motion blur
Motion blurMotion blur
Motion blur
 
멀티스레드 렌더링 (Multithreaded rendering)
멀티스레드 렌더링 (Multithreaded rendering)멀티스레드 렌더링 (Multithreaded rendering)
멀티스레드 렌더링 (Multithreaded rendering)
 
[Kgc2012] deferred forward 이창희
[Kgc2012] deferred forward 이창희[Kgc2012] deferred forward 이창희
[Kgc2012] deferred forward 이창희
 
Tips and experience of DX12 Engine development .
Tips and experience of DX12 Engine development .Tips and experience of DX12 Engine development .
Tips and experience of DX12 Engine development .
 
Compute shader DX11
Compute shader DX11Compute shader DX11
Compute shader DX11
 
NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술
NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술
NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술
 
김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019
김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019
김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019
 
5강 알파와알파소팅
5강 알파와알파소팅5강 알파와알파소팅
5강 알파와알파소팅
 
[데브루키/141206 박민근] 유니티 최적화 테크닉 총정리
[데브루키/141206 박민근] 유니티 최적화 테크닉 총정리[데브루키/141206 박민근] 유니티 최적화 테크닉 총정리
[데브루키/141206 박민근] 유니티 최적화 테크닉 총정리
 
Hierachical z Map Occlusion Culling
Hierachical z Map Occlusion CullingHierachical z Map Occlusion Culling
Hierachical z Map Occlusion Culling
 
Ssao
SsaoSsao
Ssao
 
나만의 엔진 개발하기
나만의 엔진 개발하기나만의 엔진 개발하기
나만의 엔진 개발하기
 
Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술
Ndc2010 전형규   마비노기2 캐릭터 렌더링 기술Ndc2010 전형규   마비노기2 캐릭터 렌더링 기술
Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술
 
Ndc17 - 차세대 게임이펙트를 위해 알야아할 기법들
Ndc17 - 차세대 게임이펙트를 위해 알야아할 기법들Ndc17 - 차세대 게임이펙트를 위해 알야아할 기법들
Ndc17 - 차세대 게임이펙트를 위해 알야아할 기법들
 
빠른 렌더링을 위한 오브젝트 제외 기술
빠른 렌더링을 위한 오브젝트 제외 기술빠른 렌더링을 위한 오브젝트 제외 기술
빠른 렌더링을 위한 오브젝트 제외 기술
 
[Unite2015 박민근] 유니티 최적화 테크닉 총정리
[Unite2015 박민근] 유니티 최적화 테크닉 총정리[Unite2015 박민근] 유니티 최적화 테크닉 총정리
[Unite2015 박민근] 유니티 최적화 테크닉 총정리
 
Ndc11 이창희_hdr
Ndc11 이창희_hdrNdc11 이창희_hdr
Ndc11 이창희_hdr
 
카툰 렌더링
카툰 렌더링카툰 렌더링
카툰 렌더링
 
스크린 스페이스 데칼에 대해 자세히 알아보자(워햄머 40,000: 스페이스 마린)
스크린 스페이스 데칼에 대해 자세히 알아보자(워햄머 40,000: 스페이스 마린)스크린 스페이스 데칼에 대해 자세히 알아보자(워햄머 40,000: 스페이스 마린)
스크린 스페이스 데칼에 대해 자세히 알아보자(워햄머 40,000: 스페이스 마린)
 

Similar to [1023 박민수] 깊이_버퍼_그림자

Real-Time Global Illumination Techniques
Real-Time Global Illumination TechniquesReal-Time Global Illumination Techniques
Real-Time Global Illumination Techniques
Jangho Lee
 
GameMath-Chapter 08 고급렌더링
GameMath-Chapter 08 고급렌더링GameMath-Chapter 08 고급렌더링
GameMath-Chapter 08 고급렌더링
Mark Choi
 
구세대 엔진 신데렐라 만들기 최종본 유트브2
구세대 엔진 신데렐라 만들기 최종본 유트브2구세대 엔진 신데렐라 만들기 최종본 유트브2
구세대 엔진 신데렐라 만들기 최종본 유트브2
Kyoung Seok(경석) Ko(고)
 
6강 light shadow 기초
6강 light shadow 기초6강 light shadow 기초
6강 light shadow 기초
JP Jung
 
6강 light shadow 기초
6강 light shadow 기초6강 light shadow 기초
6강 light shadow 기초
JP Jung
 
6강 light shadow 기초
6강 light shadow 기초6강 light shadow 기초
6강 light shadow 기초
JP Jung
 
후처리알아보기
후처리알아보기후처리알아보기
후처리알아보기
종규 우
 

Similar to [1023 박민수] 깊이_버퍼_그림자 (20)

Reflective Shadow Maps
Reflective Shadow MapsReflective Shadow Maps
Reflective Shadow Maps
 
Bump Mapping
Bump MappingBump Mapping
Bump Mapping
 
Unity cookbook 17
Unity cookbook 17Unity cookbook 17
Unity cookbook 17
 
Real-Time Global Illumination Techniques
Real-Time Global Illumination TechniquesReal-Time Global Illumination Techniques
Real-Time Global Illumination Techniques
 
파이어몽키 3D 애플리케이션 만들기
파이어몽키 3D 애플리케이션 만들기파이어몽키 3D 애플리케이션 만들기
파이어몽키 3D 애플리케이션 만들기
 
제노블레이도 2 ray marching을사용한 구름 표현
제노블레이도 2 ray marching을사용한 구름 표현제노블레이도 2 ray marching을사용한 구름 표현
제노블레이도 2 ray marching을사용한 구름 표현
 
[0918 박민수] 범프 매핑
[0918 박민수] 범프 매핑[0918 박민수] 범프 매핑
[0918 박민수] 범프 매핑
 
GameMath-Chapter 08 고급렌더링
GameMath-Chapter 08 고급렌더링GameMath-Chapter 08 고급렌더링
GameMath-Chapter 08 고급렌더링
 
구세대 엔진 신데렐라 만들기 최종본 유트브2
구세대 엔진 신데렐라 만들기 최종본 유트브2구세대 엔진 신데렐라 만들기 최종본 유트브2
구세대 엔진 신데렐라 만들기 최종본 유트브2
 
Voxel based game_optimazation_relelase
Voxel based game_optimazation_relelaseVoxel based game_optimazation_relelase
Voxel based game_optimazation_relelase
 
[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법
[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법
[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법
 
크게, 아름답게,빠르게, 일관되게 만들기: Just Cause 2 개발에서 배운 교훈들 (GPU Pro)
크게, 아름답게,빠르게, 일관되게 만들기: Just Cause 2 개발에서 배운 교훈들 (GPU Pro)크게, 아름답게,빠르게, 일관되게 만들기: Just Cause 2 개발에서 배운 교훈들 (GPU Pro)
크게, 아름답게,빠르게, 일관되게 만들기: Just Cause 2 개발에서 배운 교훈들 (GPU Pro)
 
실전프로젝트 정서경 양현찬
실전프로젝트 정서경 양현찬실전프로젝트 정서경 양현찬
실전프로젝트 정서경 양현찬
 
6강 light shadow 기초
6강 light shadow 기초6강 light shadow 기초
6강 light shadow 기초
 
6강 light shadow 기초
6강 light shadow 기초6강 light shadow 기초
6강 light shadow 기초
 
Uncharted4 part1
Uncharted4 part1Uncharted4 part1
Uncharted4 part1
 
6강 light shadow 기초
6강 light shadow 기초6강 light shadow 기초
6강 light shadow 기초
 
언차티드4 테크아트 파트2 mipFog
언차티드4 테크아트 파트2 mipFog언차티드4 테크아트 파트2 mipFog
언차티드4 테크아트 파트2 mipFog
 
후처리알아보기
후처리알아보기후처리알아보기
후처리알아보기
 
마른 하늘에 날구름 넣기
 마른 하늘에 날구름 넣기 마른 하늘에 날구름 넣기
마른 하늘에 날구름 넣기
 

More from MoonLightMS (6)

네트워크 스터디(Tcp 소켓 프로그래밍)
네트워크 스터디(Tcp 소켓 프로그래밍)네트워크 스터디(Tcp 소켓 프로그래밍)
네트워크 스터디(Tcp 소켓 프로그래밍)
 
[0212 박민수]환경 매핑
[0212 박민수]환경 매핑[0212 박민수]환경 매핑
[0212 박민수]환경 매핑
 
[Gpg1권 박민수] 4.4 빠른 원통 절두체 교차 판정
[Gpg1권 박민수] 4.4 빠른 원통 절두체 교차 판정[Gpg1권 박민수] 4.4 빠른 원통 절두체 교차 판정
[Gpg1권 박민수] 4.4 빠른 원통 절두체 교차 판정
 
[1113 박민수]a star_알고리즘
[1113 박민수]a star_알고리즘[1113 박민수]a star_알고리즘
[1113 박민수]a star_알고리즘
 
Depth buffershadow
Depth buffershadowDepth buffershadow
Depth buffershadow
 
Assert에 대해서
Assert에 대해서Assert에 대해서
Assert에 대해서
 

[1023 박민수] 깊이_버퍼_그림자

  • 2.  그림자란?  3D에서의 그림자  그림자 구현의 역사  깊이 버퍼 그림자 구현  시연  Q & A  참고자료
  • 3.  그림자 : 빛이 지나가는 경로에 불투명한 물체가 존재하여 빛이 통과하지 못해 생기 는 어두운 부분.  물체의 가장자리를 지나가는 빛은 회절 현 상에 의해 물체를 넘어갈 수도 있어서 가장 자리 부분은 비교적 밝은 그림자가 생긴다.
  • 4. 반 그림자 : 흐릿하다. 본 그림자 : 진하다.
  • 5.  3D에서는 그림자를 크게 2가지로 나눌 수 있다. 그림자 음영
  • 6.  음영은 보통 Lighting 계산으로 구한다.  특별한 처리를 하지 않아도 기본적인 파이프라인 에서 음영은 제공해 준다.  그림자는 애초부터 따로 구현해야 하는 부분이였 다.
  • 7.  Circle Shadow  Projected Shadow Mapping  Stencil Shadow Volume  Depth Buffer Shadow  Perspective Shadow Map( PSM )  Light Space Perspective Shadow Map( LSPSM )  Cascaded LSPSM  Soft Shadow  Variance Shadow Map( VSM )  3D 그래픽스 매니악스를 훑어보자!
  • 8.  Circle Shadow  캐릭터의 위치를 계산하여 발 밑 부분에 원 형의 그림자 텍스쳐를 적용시켜준다.  다른 캐릭터들도 원형의 그림자를 갖게 되 어 리얼리티가 떨어진다.
  • 9. 캐릭터의 위치정도는 파악할 수 있게 해준다.  Circle Shadow
  • 10.  심플하게 생각해보자.  머리 위에서 캐릭터를 향해 빛이 비친다.  이 때 쉽게 그림자를 생성하는 법은?  캐릭터의 y좌표를 땅의 높이로 두고 검은색으 로 렌더링한다!
  • 12.  심플하게 생각해보자.  빛이 다른 방향에서 비춘다면?
  • 14.  Projected Shadow Mapping  앞의 아이디어를 기본으로 나온 기법이다.  광원에서 본 오브젝트의 실루엣을 그림자 텍스쳐에 저장한다.  광원방향으로 투영하듯 텍스쳐를 매핑한 다.
  • 15.  Projected Shadow Mapping 캐릭터 형태가 나온다!
  • 16.  Projected Shadow Mapping  그림자를 생성하고 적용하는 과정에서 별 다른 연산이 없으므로 호환성이 뛰어나다.  캐릭터의 모습을 적용할 수 있다.  매 프레임마다 그림자를 갱신해 줘야 하는 이슈가 있지만 멀리 있는 녀석의 그림자는 생략하는 등 트릭으로 극복가능.
  • 17.  Projected Shadow Mapping  문제점 1 : 셀프 그림자가 적용되지 않는다. 이런 것 들 이런 것 들 이런 것 들
  • 18.  Projected Shadow Mapping  문제점 1 : 셀프 그림자가 적용되지 않는다.  왜냐하면 그림자가 오브젝트 단위로 생성 되기 때문이다.  그렇기 때문에 오브젝트 자신의 차폐를 계 산하기 어렵다.
  • 19.  Projected Shadow Mapping  문제점 2 : 투영을 잘 시켜야 한다.
  • 20.  Projected Shadow Mapping  문제점 2 : 투영을 잘 시켜야 한다.  계산을 잘 못하면 벽 넘어에 그림자가 생기 는등 버그가 발생 할 수 있다.
  • 21.  Stencil Shadow Volume  셀프 쉐도우를 위해서는 광원을 기준으로 차폐 여부를 가지고 그림자를 적용해야 한 다.
  • 22.  Stencil Shadow Volume 셀프 쉐도우 볼륨
  • 23.  Stencil Shadow Volume  일단 씬을 렌더링하고 깊이정보를 저장한다.  오브젝트의 외곽에 있는 버텍스를 광원방향 으로 잡아 늘린다.  앞서 저장한 깊이정보와 그림자 볼륨을 비교 하여 그림자인지 아닌지를 스텐실 버퍼에 기 록한다.  최종 렌더링시에 스텐실 버퍼를 참고하여 그 림자를 그린다.
  • 24.  Stencil Shadow Volume 그림자 볼륨 중 앞에 면만 스텐실 버퍼에 1로 기록한다. *계산 전에 스텐실 버퍼를 0으로 초기화 해두자!
  • 25.  Stencil Shadow Volume 볼륨의 뒷면은 -1로 그려준다.
  • 26.  Stencil Shadow Volume 1인 부분을 그림자로 보면 된다.
  • 27.  Stencil Shadow Volume  광원이 여러 개가 있거나 오브젝트가 서로 겹치는 등 경우에 따라서 스텐실 버퍼의 값 이 1보다 클 수도 있다.  0이 아니면 그림자로 생각해도 무방하다!
  • 28.  Stencil Shadow Volume  깊이정보를 이용해서 차폐를 계산했기 때 문에 셀프쉐도우가 가능해 졌다.  기타 다른 그림자의 문제도 해결된 듯 보인 다!
  • 29.  Stencil Shadow Volume  구현을 보면 알겠지만 그림자를 처리할 때 폴리곤 단위로 처리를 한다.  아까는 오브젝트가 그림자 단위였는데 폴 리곤 단위니 전보다 세밀해 졌다!
  • 30.  Stencil Shadow Volume 잎사귀 텍스쳐도 어차피 네모판일 뿐…
  • 31.  Stencil Shadow Volume 그림자가 사각형이다.
  • 32.  Stencil Shadow Volume  볼륨을 생성하는 부분도 생각을 해봐야 한 다.  잘못 늘리면 그 만큼 그림자가 잘못 생성된 다.
  • 33.  Stencil Shadow Volume  그리고 원래 캐릭터의 모양을 유지하면서 정점을 늘려야 하기 때문에 늘릴 정점이 따 로 필요하다.  보이는 것보다 더 많은 정점이 쓰이게 된다.
  • 35.  Stencil Shadow Volume  하지만 이전 Direct10 스터디 때도 나왔듯 이 정점을 생성해주는 쉐이더가 추가 되었 기 때문에 위의 문제점은 해결이 될 듯 하 다.
  • 36.  Depth Buffer Shadow  위의 Stencil Shadow Volume도 문제가 있 다.  그런데 GPU는 발전해가고 픽셀 계산능력 이 올라가면서 Depth Buffer Shadow 기법 이 사용되기 시작했다.
  • 37.  Depth Buffer Shadow  광원을 기준으로 오브젝트들과의 거리( 깊 이 )를 저장한다.( 그림자 맵 )  실제 렌더링 시에 다시 광원과 오브젝트의 거리를 비교하고 위에서 저장해둔 차폐 정 보를 비교하여 그림자를 판별하고 적용한 다.
  • 38.  Depth Buffer Shadow 광원의 시점에서 깊이가 저장되면 노란색 부분은 기록되고 주황색 부분은 묻히게 된다. 위에서 무시된 부분이 그림자가 됨을 알 수 있다.
  • 39.  Depth Buffer Shadow 위에서 저장된 값은 결국 광원이 도달하는 부분이다. 실제 렌더링할 때 다시 한번 광원과 오브젝트의 거리를 재서 위에 저장한 값과 비교해 보고 그림자인지 아닌지 판단한다. D > S : 그림자 D == S : 그림자 아님
  • 40.  Depth Buffer Shadow  차폐 정보를 이용해 처리한 것이니까 셀프 쉐도우가 가능하다.  아까는 폴리곤 단위였지만 지금은 픽셀 단 위이므로 위의 문제도 해결된다.
  • 41.  Depth Buffer Shadow  모든 구현에는 문제점이 존재한다.  픽셀 단위의 구현으로 인해 그림자 맵의 해 상도가 적으면 그만큼 그림자의 세밀함이 떨어지게 된다.
  • 42.  Depth Buffer Shadow 픽셀 돋네..
  • 43.  Depth Buffer Shadow  해결방안은??  그림자 맵의 해상도를 높인다. -> 한계가 있다.  요즘 게임 특히 야외를 보여주는 게임은 점점 먼 곳 까지 보여주기 때문에 커버할 수 없다.  그래도 해상도만 괜찮으면 쓸만한 그림자니까 개량해서 사용해야 겠다!
  • 44.  Perspective Shadow Map( PSM )  그림자 맵 해상도 이슈가 발생하는 이유는 간단하다.  게임 상의 오브젝트들을 모두 그림자 맵에 담기 때문에 넓을 수록 한 텍셀이 표현해야 할 그림자 영역이 점점 넓어지다 보니 품질 이 떨어지게 된다.
  • 45.  Perspective Shadow Map( PSM )  위의 구현 방법은 맵이 100m x 100m면 전 체를 그림자 맵에 담아서 사용하게 된다.  텍스쳐 사이즈가 256 x 256이면 한 텍셀은 40cm x 40cm가 된다고 보면 된다.
  • 46.  Perspective Shadow Map( PSM )  시점이 가까운 곳이나 먼 곳이나 동일한 해 상도를 사용하게 된다. 먼 곳에 있는 녀석 들은 자세히 그릴 필요가 없지 않은가?  가까운 녀석에게 해상도를 집중하고 먼 녀 석은 대충 그려주자가 PSM의 목적이다.
  • 47.  Perspective Shadow Map( PSM )  시점에서 가까운 곳과 먼 곳은 카메라에 의 해 결정된다. ( View )  가까운 물체는 커보이고 멀리 있는 물체는 작아보인다. ( Projection )  View x Projection 변환된 녀석을 그림자 맵 으로 뽑아내자!
  • 48.  Perspective Shadow Map( PSM ) 기존에 쉐도우 맵을 뽑을 때완 달리 가까운 녀석의 비중이 더 커지게 그림자 맵을 생성할 수 있다.
  • 51.  Perspective Shadow Map( PSM )  기존의 그림자 맵보다 효율적으로 만들 수 있어서 더 매끄러운 그림자가 나온다.  이런 부분만 보면 완벽할 것 같다!!
  • 52.  Perspective Shadow Map( PSM )  PSM은 광원을 기준으로 그림자 맵을 생성 한다. 따라서 광원에선 멀리 있는 그림자를 카메라 시점에서는 가까이 볼 수도 있다.  이 때는 마찬가지로 그림자의 품질이 떨어 진다.
  • 53.  Perspective Shadow Map( PSM )  PSM은 광원을 기준으로 그림자 맵을 생성 한다. 따라서 광원을 기준으로 보이는 녀석 들에 대해서만 그림자 맵을 만들게 된다.  오브젝트는 보이지 않지만 그림자만 보여 야 하는 상황에서는 올바르게 그림자가 생 성되지 않을 수 있다.
  • 54.  Light Space Perspective Shadow Map( LSPSM )  PSM의 문제를 해결하기 위해 개량된 방법을 제 시하였다. 그것이 바로 LSPSM이다.  위의 문제를 정리하면 광원 기준의 그림자 생성 과 보이지 않는 오브젝트가 있을 수 있다는 것이 다.
  • 55.  Light Space Perspective Shadow Map( LSPSM )  하지만 저런 특정 상황을 제외하고는 그림자 맵 을 카메라에 맞게 옮겨서 생성하는 아이디어는 괜찮은 것 같다.  그렇다면 위의 문제를 해결하면서 그림자 맵을 옮겨서 생성하자!  그림자 맵 생성을 위한 좌표계를 만들어 내고 그림자를 생성하자!
  • 56.  Light Space Perspective Shadow Map( LSPSM )  그림자를 생성할 가능성이 있는 오브젝트는 모두 포함시키게 시야 거리를 조정한다.  최대한의 해상도를 구하기 위해 최대한 가까운 곳에서 그림자 맵을 뽑아낸다.  좌표계는 다음과 같은 방식으로 생각해 볼 수 있 다.
  • 57.  Light Space Perspective Shadow Map( LSPSM )  빛의 방향의 반대되는 방향을 Y축  뷰 벡터와 Y축을 외적해서 구한 방향을 X축  X축과 Y축을 외적해서 구한 방향을 Z축
  • 58.  Light Space Perspective Shadow Map( LSPSM ) PSM은 뒷 부분 그림자의 품질이 낮다.
  • 59.  Light Space Perspective Shadow Map( LSPSM ) LSPSM은 뒷 부분 그림자까지 제대로 그려준다.
  • 60.  Cascaded LSPSM  LSPSM을 가지고 좋은 그림자를 생성해 냈으나 점점 더 야외 맵은 넓어지고 멀리 보이게 되고 있 다.  LSPSM을 이용해 처리를 해도 마찬가지로 먼 곳 까지는 텍스쳐 해상도의 한계에 부딪치게 된다.
  • 61.  Cascaded LSPSM  해상도에 한계가 있어서 계속 그림자 맵을 효율 적으로 생성하는 것에만 신경을 쓰다가 그림자 맵을 여러 개 두면 되지 않을까? 로 생각이 넘어 오게 된다.  지금까지 구현을 보아 가까운 녀석에게는 그림자 해상도를 많이 투자하는게 맞고 먼 녀석에게는 적게 투자하더라도 어느정도는 투자가 되어야 한 다.
  • 62.  Cascaded LSPSM  근거리용 그림자 맵( 가까운 물체의 해상도는 높 게 )  중거리용 그림자 맵( 중간 물체도 위보단 높게 )  장거리용 그림자 맵( 멀리있는 물체도 최소한 보 이게 )  이런식으로 나누면 되겠구나!  물론 게임마다 거리를 나누는 기준과 몇 단계로 나눌 것이냐는 따로 정해야 한다.
  • 65.  Soft Shadow  지금까지 그림자 맵을 찍는 부분에 대해서 만 생각해 왔다.  문제는 그림자 품질이 떨어지는 현상이다.  Post Processing으로 해결할 수 있지 않을 까?
  • 66.  Soft Shadow  계단현상이 생긴 부분을 뭉게버리자!  뭉게지면 부드러워 지고 실제 그림자의 뿌 연 느낌도 줄 수 있을 것 같다!
  • 67.  Soft Shadow 뭉게기 전 뭉게기 후 그림을 확대해서 둘 다 뭉게진 듯 하지만 자세히 보면 보인다.
  • 68.  Soft Shadow 뭉게기 전 뭉게기 후
  • 69.  Soft Shadow  Post Processing이다 보니 격렬하게 뭉게 면 3D모델 렌더링에 영향을 끼칠 수 있다.  Soft Shadow역시 이것 저것 개량해서 쓰면 좋은 퀄리티를 낼 수 있겠다. ( 이건 다음 에.. )
  • 70.  Variance Shadow Map( VSM )  언리얼 엔진 3.0에서 사용한다고 한다.  그림자 맵에 광원에서 오브젝트까지의 거 리와 그 제곱값을 저장한다.  이 값을 이용해 그림자가 생길 확률을 계산 하고 그림자를 입혀준다.
  • 71.  Variance Shadow Map( VSM )  VSM을 위한 그림자 맵을 만들기 위해서는 부동 소수점을 저장하는 텍스쳐를 이용해 야 한다.  이 기법을 이용하면 소프트 쉐도우와 같은 구현이 된다고 한다.
  • 72.  Variance Shadow Map( VSM )  기존의 그림자 맵은 그림자다 아니다.  0 아니면 1 이런 느낌.  반면 VSM은 체비쇼프 부등식을 이용하여 깊 이값을 기반으로 빛이 비치는 정도를 확률로 구한다.  빛이 안 비칠 확률이 높을 수록 어둡게 만든다.  나름 자연스러운 그림자 완성!
  • 73.  Variance Shadow Map( VSM )
  • 74.  그 중에서 깊이 버퍼 그림자 구현 부분을 자세히 알아보자.  깊이 버퍼 그림자 구현의 기초를 이해하면 나머지 그림자 구현을 이해하는데 도움이 될 것이다.
  • 75.  깊이 버퍼 그림자는 2패스로 진행된다.  그림자 맵 생성 ▪ 광원의 위치에서 본 장면을 렌더링한다. ▪ 렌더링 할 색은 광원으로 부터의 거리로 한다.  그림자 맵과 실제 거리 비교 후 그림자 적용 ▪ 그림자 맵이 가리키는 픽셀 값과 실제 거리를 비교한 다. ▪ 그림자 맵이 가리키는 픽셀 값이 더 작으면 그림자다.
  • 76.  그림자 맵 생성  그림자 맵을 저장하기 위한 텍스쳐를 생성한다.  그림자 맵 생성시 사용할 깊이 버퍼를 만든다.  렌더 타겟과 깊이 버퍼를 만든 녀석들로 바꾼다.  그림자 맵에 맞게 뷰포트를 잡아준다.  장면을 렌더링 한다.  뷰포트 , 깊이 버퍼 , 렌더 타겟을 복구한다.
  • 77.  그림자 맵 생성  전에 포스트 이펙트 발표 때를 기억하시면 됩니 다.  이따가 소스를 간단하게 훑어 보겠습니다.
  • 78.  그림자 맵 생성  광원에서 본 장면을 렌더링해야 한다.  장면을 그리기 위해 넘어온 좌표들을 광원을 중심으 로 한 행렬로 변환해야 한다.  광원을 중심으로 한 행렬 구하기  월드 행렬 x 뷰 행렬 x 투영 행렬  광원위치를 기준으로한 뷰 행렬  광원을 기준으로 적당한 FOV등을 설정한 투영 행렬
  • 79.  그림자 맵 생성  버텍스 쉐이더  버텍스들을 광원을 중심으로한 행렬로 변환한다.  픽셀 쉐이더에서 깊이값을 저장할 수 있게 변환된 위 치를 넘겨 준다.  픽셀 쉐이더  넘어온 변환된 위치를 이용해 깊이 값을 저장시킨다.  깊이 : z / w ( 0 ~ 1 값 )
  • 81.  그림자 맵 생성  위의 소스를 보면 z / w 구문이 픽셀 쉐이더에 있음을 알 수 있다.  버텍스 쉐이더에서 계산을 하는게 더 빨라 보이 지만 값이 불안정해 질 수 있다.  픽셀 쉐이더에서는 버텍스 사이 사이에 있는 픽 셀들의 값을 채워줘야 한다.
  • 82.  그림자 맵 생성  우리가 원하는 깊이의 저장은 이런 모습이다.  두 버텍스 p0 = ( z0 , w0 ) , p1 = ( z1 , w1 )가 있다고 하고 이 버텍스들의 중심 부분을 얻어온다고 생각해 보자.  z’ = ( ( z0 + z1 ) / 2 ) ( ( w0 + w1 ) / 2 )  하지만 버텍스 쉐이더에서 먼저 계산을 하고 넘 긴다면? 오차가 날 것이다.  z’ = ( ( z0 ) + ( z1 ) ) * 1 ( ( w0 ) ( w1 ) ) 2
  • 83.  그림자 맵 적용  퍼스펙티브 보정에 의한 보간에서는 비선형 깊 이가 바르게 보간 되지 않는단다…  비선형 깊이가 무엇인가 하면 투영행렬까지 거 친 위치정보는 원근처리가 되어있기 때문에 깊 이값을 구하면 선형적인 값이 나오지 않는다.  그렇기 때문에 깔끔하게 픽셀쉐이더에서 그 순 간 깊이를 계산해서 저장하는 것이다.
  • 84.  그림자 맵 적용  그렇단 말은 선형적인 값을 갖는 깊이를 버텍스 쉐이더에서 계산할 수 있으면 그냥 픽셀 쉐이더 에 넘겨줘도 된다는 말이다.  선형 깊이를 구하는 식은  z’ = ( z - zn ) * ( zf ) ( zf - zn ) ( z )
  • 85.  그림자 맵 적용 ( x , y , z , 1 )을 변환하면? ( w * x , h * y , Q * z – Q * Zn , z ) Z와 W만 집중해서 봅시다! ( Q * z – Q * Zn ) / W -> ( Zf * z ) – ( Zf * Zn ) * ( 1 ) ( Zf – Zn ) ( Zf – Zn ) ( z ) -> ( Zf * ( z – Zn ) ) z * ( Zf – Zn )
  • 86.  그림자 맵과 실제 거리 비교 후 그림자 적용  그림자 맵을 만들었으니 그림자 맵을 이용하자.  렌더링할 때 그림자 맵을 매핑할 수 있어야 한 다.  그림자 맵 : X : ( -1 , 1 ) , Y : ( -1 , 1 ) , Z : ( 0 , 1 ) 텍스쳐의 UV : X : ( 0 , 1 ) , Y : ( 0 , 1 )  그림자 맵을 UV좌표계로 변환해 보자.  U = +0.5X + 0.5  V = - 0.5Y + 0.5
  • 87.  그림자 맵과 실제 거리 비교 후 그림자 적용  위의 변환식을 행렬로 묶으면?( -1 , 1 ) -> ( 0 , 1 )  ( 0.5 0 0 0.5 ) ( 0 -0.5 0 0.5 ) ( 0 0 1 0 ) ( 0 0 0 1 )
  • 88.  그림자 맵과 실제 거리 비교 후 그림자 적용  투영했을 때 ( 0 , 1 )범위로 갔다는 것은 w = 1, 즉 W값으로 나누었다는 이야기가 된다. W로 나누기 전이라면 다음과 같이 적용해야 한다.  ( 0.5 0 0 0.5 + ( x / w ) ) ( 0 -0.5 0 0.5 + ( y / w ) ) ( 0 0 1 0 ) ( 0 0 0 1 )
  • 89.  그림자 맵과 실제 거리 비교 후 그림자 적용 X = 1 , Y = 1 , W = SHADOW_MAP_SIZE
  • 90.  그림자 맵과 실제 거리 비교 후 그림자 적용
  • 91.  그림자 맵과 실제 거리 비교 후 그림자 적용  조명 처리를 위한 부분은 제외하고 보면  Out.ShadowMapUV = mul(Pos, mWLPB);  그림자 맵을 입히기 위해서 변환한다.  Out.Depth = mul(Pos, mWLP);  그림자 맵의 값과 거리를 비교하기 위해 변환한다.
  • 92.  그림자 맵과 실제 거리 비교 후 그림자 적용
  • 93.  그림자 맵과 실제 거리 비교 후 그림자 적용  거리비교 부분  그림자 맵의 값을 얻어온다.  현재 투영된 녀석과 거리를 맞추기 위해 w값을 곱한 다.  그 값을 z값과 비교한다.  Bias를 막기 위해 0.03이라는 마법의 숫자를 넣었다.  그림자 맵의 깊이보다 넘어온 녀석이 크면 그림자!  아니면 그냥 텍스쳐 디퓨즈 색.  최종적으로 조명계산까지 덧 붙인다.
  • 94.
  • 95.
  • 96.  http://ko.wikipedia.org/wiki/%EA%B7%B8%EB%A6%BC%EC%9E%90 - 그림자  http://allosha.tistory.com/ - 알로샤님 블로그  http://en.wikipedia.org/wiki/Shadow_volume - Stencil Shadow Volume Wiki  http://x66vx.egloos.com/3808794 - PSM ~ PPSM까지 정리해 주셨음.  http://www-sop.inria.fr/reves/Marc.Stamminger/psm/ PSM 정리