'지오메트리 셰이더'에 해당되는 글 2건

  1. 2009.12.07 지오메트리셰이더 : 새로운 표현
  2. 2009.12.07 지오메트리셰이더 : 가속을 위한 활용


아래에서 퍼옴

http://allosha.tistory.com/category/니시카와%20젠지/지오메트리%20셰이더




지오메트리셰이더 : 새로운 표현(Motion Blur)


2008-10-10 10:00:00
ジオメトリシェーダを活用した新表現(1)~モーションブラージオメトリシェーダの活用方針の二つ目、「ジオメトリシェーダを活用した新表現」とは、ジオメトリシェーダを用いることで、これまでのGPUでは難しかった ...... >> Read more

(C) Mainichi Communications Inc. All rights reserved.



 

지오메트리셰이더를 활용한 새로운 표현(1) ~ 모션블러(Motion Blur)

지오메트리셰이더를 활용하는 방침의 두번째인 「지오메트리셰이더를 활용한 신표현」이란 것은 지오메트리셰이더를 이용해 지금까지의 GPU에서는 어려웠던 표현을 가능하게 하는 것을 말한다.

서서히 독특한 테크닉이 등장하기 시작하고 있지만, 여기에서는 가장 기본적인 것들을 소개하고 싶다.

비교적, 구현이 간단하고 효과가 큰 것이 지오메트리셰이더를 활용한 모션블러이다.

실은, 지오메트리셰이더를 사용한 모션블러에는 몇가지 종류들이 있다. 여기에서는 그 중 3가지 패턴을 소개한다.

우선 모션블러란 무엇인가? 이 기본을 정리해 두자.

리얼타임 컴퓨터 그래픽스는 어떤 의미에서는 셔터속도 1/∞초의 카메라로 촬영하고 있는 것과 같기 때문에 , 아무리 피사체가 고속으로 움직이고 있다고 해도, 생성한 프레임이 흐려지지는(번지지는) 않는다. 이것이 「그야말로 CG」같은 느낌인 것이 사실이고, 이것을 마치 카메라로 촬영한 것 처럼, 포토 리얼리스틱하게 보이게 하기 위해, 빠른 움직임에 대해서 "흐림(흔들림)" 효과를 추가해 주는 테크닉을 「모션블러」라고 부른다.

모션블러의 부차적인 효과로서는, 표시 프레임수가 일정하지 않아도, 보는 것 만으로는 알 수 없도록 해주므로, 최근의 많은 3D게임등에서 채용되어져 왔다.

결국, 모션블러는 어떠한 기법으로 "흐림(흔들림) 효과"를 그려갈지 ……가 키포인트가 된다.

가장 기본적인 것은, 영상 프레임 전체에 한결같이 걸어 버리는 「카메라블러」이다.

이것은, 현재의 렌더링 프레임을, 시점(카메라)의 이동 벡터에 따라 형태를 확대, 축소, 혹은 회전등을 시켜서, 반투명하게 중복합성하는 것으로 실현될 수 있다.

이 카메라블러는 레이싱 게임과 같은 화면 전체가 주로 움직이는 케이스에는 잘 맞는다. 말에 타서 달린다거나, 돌아 다니는 거상에 매달린, 카메라 전체가 drastic하게 움직이는 액션이 눈에 띄었던 PS2용 「완다와 거상」에서는 이 기법을 활용해, 매우 높은 효과를 얻었다.

가로방향으로 2차원적인 처리를 하는 카메라블러의 개념도

원래 프레임(좌)과 블러 처리한 프레임(우) ※「원다와 거상」에서 인용

깊이 방향으로 2차원적인 처리를 하는 카메라 블러의 개념도

원래 프레임(좌)과 블러처리한 프레임(우) ※「완다와 거상」에서 인용

그러나, 이 카메라블러에서는, 씬내에 존재하는 하나 하나의 3D오브젝트가, 각각의 임의의 빠른 움직임을 실시한다고 해도, 그 움직임 각각에 맞는 블러 처리를 해줄 수는 없다. 이것은 카메라 블러가 표시 프레임(2D영상)을 단지 화상처리 해주는 것 뿐인 「2D블러」이기 때문이다.

뒤에 소개하는 3개의 모션블러 기법은, 각각의 캐릭터들에게 개별적으로 입체적인 블러를 해 줄 수 있는, 이른바 3차원 베이스의 모션블러를 실현한다. 그리고, 이 3차원적인 흐림(흔들림) 생성에 지오메트리셰이더를 이용한다.


그 캐릭터의 움직임에 블러를 실시하는「 액션블러


캐릭터가 펀치나 킥등의 고속 액션을 했을 때에 일어나는 블러 표현에 적합한 기법이다. 굳이 이름을 붙힌다면 「액션블러」라는 느낌의 기법이다. 최근에는 「오브젝트 모션 블러」(OMB, Object Motion Blur)로도 많이 불린다.

이 기법에서는, 3D의 캐릭터의 정점 정보에 속도벡터(속력, 움직이는 방향) 값을 갖게해 이 정보를 바탕으로 지오메트리셰이더에서 정점을 잡아 늘리는 그런 이미지로 폴리곤을 새로 생성한다. 덧붙여 그 동작의 과거의 궤적 뿐만이 아니라, 미래의 진행 방향으로도 폴리곤을 생성하는 것이 특징이다.

지오메트리셰이더를 활용해서, 움직이고 있는 속도와 그 방향으로 폴리곤을 생성함. 현재 위치를 중심으로 과거의 궤적과 미래의 궤도에도 생성해 주는 것이 특징임.

<그림 설명>
(검은선) 현재 타임에서의 트라이앵글
(녹색선) 이전과 다음 타임들에서의 extruded 트라이앵글
(빨간선) 트라이앵글의 모션 라인

그리고, 생성한 다각형에 대해서, 현재를 기준으로서 멀리 떨어지면 떨어질 수록 α값(0~1 사이의 값을 취해, 0은 완전히 투명, 1은 완전히 불투명)을 낮게 설정한다. 이 α정보는 근사적으로는 「화면상의 각 픽셀 단위의 속도정보의 분포에 해당된다」고 볼 수 있으므로, 원래 폴리곤에 붙이는 텍스처에 대해서, 이 정보에 따라 조금 옮겨서 텍셀을 참조해 적용해 간다. 현재 시간에서 멀면 멀수록, α값이 제로(투명)에 가까워지므로 샘플링 한 텍셀의 색은 연하게 합성된다. 이것에 의해 가장 먼 과거와 제일 먼 미래의 픽셀은 연하고, 현재에 가까울 수록 진하게 …… 라는 그림이 되어 속도감을 연출할 수 있게 된다.(계속)

현재 위치에서 멀면 멀수록 α값은 0으로. 이것은 근사적으로 화면상에서 픽셀 단위의 속도를 나타내고 있다. 이 값을 오프셋값으로 해서, 텍스처로부터 샘플링 해서 블러를 표현한다

다이렉트X10의 데모로 부터. 풍차는 항상 등속 회전운동을 하고, 몬스터는 격투 액션을 선보임. 각각의 속도와 방향에 맞는 블러가 잘 나오고 있는 점이 카메라 블러와는 크게 다른 점



지오메트리셰이더 : 새로운 표현(2.5D Blur)



지오메트리셰이더를 활용한 새로운 표현(2) ~
입체적인 모션블러를 화상처리로 실현시키는 2.5D 블러기법

지난회에서 다룬 오브젝트 모션블러(액션블러)와 매우 흡사하지만, 미묘하게 구현방법이 다른 기법이 2003년 의 게임 개발자 회의 「GDC 2003」에서 NVIDIA의 Simon Green씨에 의해 발표되었다. 그것이 「2.5D 블러」라고 불리는 기법이다. 이것은 캡콘의 「로스트 플라넷」이나 크라이텍의 「CRYSIS」에서 효과적으로 구현되었던 것으로, 그 유효성이 널리 알려진 것이다.

기본방침은 아래의 수순과 같다.

우선, 씬을 통상대로 렌더링하고, 이것을 뒤의 렌더링 패스에서 참조하기 위한 소재로 한다.

블러를 하고 싶은 3D 대상 오브젝트의 정점에는 앞 프레임에서의 화면상의 좌표를 저장해 두고, 정점셰이더에서, 현재 프레임의 화면 좌표를 계산해서, 보관하고 있던 이전 프레임의 화면 좌표와의 차분(差分)을 산출해 속도와 방향을 계산해, 이 값들을 텍스처에 렌더링한다. 폴리곤을 색 정보가 아닌 이 속도와 방향 정보를 그린다 …… 라는 이미지이다. 이 처리에 의해서 생성되는, 화면상의 모든 픽셀의 속도 정보들을 이 기법에서는 특히 「속도맵」(Velocity Map)이라고 부른다.

최종 렌더링 패스에서는, 이 속도맵을 참조해 속도 정보를 가져와 처음에 렌더링 한 씬 텍스체에서 이 속도 만큼 옮겨서 샘플링(읽어 내다)함으로써 최종 프레임을 생성한다.

                               속도맵의 개념

                       속도맵을 참조한 블러생성의 원리


<그림 설명>
상:
이전(前)、현재、
(박스 상) A의 속도와 방향은 (A의 위치 - A‘의 위치) ÷ dt 로 구한다. B,C도 같다.
※dt는 앞프레임에서 현재 프레임까지 경과한 시간
(박스 중) 속도정보와 방향 정보로 폴리곤을 렌더링
(박스 하) 모든 픽셀의 속도와 방향정보 이것이 속도맵
하:
(박스 좌) 이 □<픽셀>이 이 방향(화살표방향). 이 속력(화살표의 길이)이라고 하면
(박스 중) 이 속도벡터 만큼 되돌아간 위치의 씬 텍스처의 텍셀을 샘플링
(박스 중) 실제로는 샘플링 지점을 많이 추가해서 파란색□, 녹색□도 샘플링한다.


씬 텍스처로부터의 샘플링은 1개만이 아닌, 현재 프레임에서의 위치와 이전 프레임에서의 위치까지의 거리를 N등분 한 각 지점에서 총 N개의 값을 읽어 오는 것이 일반적이다. 현재 위치와 이전 프레임에서의 위치가 많이 떨어져 있는 경우는 속도가 그만큼 빨랐음을 의미하고, 씬 텍스처로부터 샘플링한 텍셀은 연하게 블렌드 하는 방법도 자주 사용된다. 이렇게 해서 현재위치에 가까운 곳의 잔상은 진하게 보이고, 먼 곳의 잔상은 연하게 할 수 있어, 보다 약동감이 있다.

이 방법에서 포인트가 되는 것은 속도맵을 작성하는 부분이다.

어떤 점이 다른 위치로 움직였을 때에는 그 전후의 위치 정보의 차분(差分)만으로 속도와 방향을 산출할 수 있지만, 이것이 폴리곤이면 좀더 까다롭다. 어떤 폴리곤이 어떤 위치로부터 다른 위치로 움직였을 때에, 이전 위치에서 현재 위치까지의 그 폴리곤의 "면(面)"으로서의 궤적과 방향을 구하고 싶은 것이다.

이것은 이미지적으로 말하면, 움직이고 있는 폴리곤에 대해, 이전 프레임에서의 위치로부터 현재 위치까지 "붕~"하고 잡아늘인 것 같은 폴리곤으로 변형함으로써 구할 수 있다.

이 변형처리에는 미국 브라운 대학의 Matthias M. Wloka씨등이 「Interactive Real-Time Motion Blur」(1995)에서 발표한, 움직임에 맞는 폴리곤 변형처리 기법를 응용한다.

이것은, 각 정점에 주목해서, 그 방향(법선벡터)이, 진행 방향에 가까우면 가까울수록 현재 상태에 가까운 정점좌표로 하고, 차이가 나면 차이가 날수록 과거의 정점좌표로 정점을 변위시킨다 ……라고 하는 처리를 통해 실현된다.

즉, 이 처리에서는 원래부터 가지고 있던 현재 위치의 정점과, 이전 프레임에서의 위치에 새로운 정점을 생성해서 새로운 폴리곤을 만들 필요가 생긴다. 그래서, 지오메트리셰이더가 여기서 활약하는 것이다.

이동벡터와 폴리곤의 법선 벡터와의 관계성을 보고, 그 폴리곤의 궤적을 생성. 실제의 속도맵은 이 폴리곤의 궤적에 대해서 행해지는 것이 된다.

<그림 설명>
1:
현재、이전、폴리곤법선벡터
이 폴리곤이 이렇게 움직였다고 했을 때
2:
(버블 상) A의 법선벡터는 이동 벡터와 같기(가깝기) 때문에 현재 위치를 사용한다.
(버블 하) B와 C는 이동벡터와 방향이 다르기 때문에 앞 타임에서의 위치에 정점을 생성해서 결합한다 -> B‘, C‘
지오메트리셰이더의 활약!
3:
폴리곤의 궤적이 완성됨
4:
이 폴리곤의 궤적에 대한 속도, 방향 정보를 생성 -> 속도맵


또한, 지오메트리셰이더를 가지고 있지 않은 다이렉트X 9세대 SM3.0대응 GPU에서, 이 2.5D 블러 기법을 구현하려면 , 이전 위치로 잡아늘이기 위한 정점을, 3D모델 쪽에 넣어 두는……고안이 필요했었다. 정확히 스텐실 그림자 볼륨 기법의 그림자 생성에서, 그림자 영역 생성을 위해 잡아 늘이는 용도의 정점을 (사전에) 넣어 두는 것과 매우 비슷하다.

캡콘의 「로스트 플라넷」에서는 폴리곤 궤적 생성을 위한 더미 폴리곤(축퇴 폴리곤)이 3D모델에 넣어져 있었다. 지오메트리셰이더가 사용 가능한 GPU라면 이런 사전 처리는 필요가 없다. 그런 의미에서는, 이 2.5D 블러 기법에 있어서는, 지오메트리세이더를 가속화를 위해서 활용한다고도 말할 수 있다.(계속)

왼쪽이 축퇴 폴리곤이 없는 12,392 폴리곤이고 오른쪽이 축퇴 폴리곤이 있는 17,765 폴리곤이다. 이 차이 만으로도 이 모션블러 생성을 위한 불필요한 정점 처리 부하가 생길 수 있다.




지오메트리셰이더 : 새로운 표현(Line-Based Blur)


지오메트리 셰이더를 활용한 새로운 표현(3) ~ 라인베이스 블러

지난회에서 다룬 2.5D 블러 기법에는, 한가지 문제가 있다.

그것은, 최종적으로는 화상처리적으로 블러 처리를 하므로, 속도가 다른 물체들이 서로 겹쳐 있는 곳에서는, 부자연스러운 블러가 나와 버리는 것이다. 예를 들면, 움직이고 있는 물체 보다 정지해 있는 물체가 더 앞에 있을 경우(시점에서 더 가까울 경우), 이 정지물의 픽셀이 뒤의 움직이는 물체의 블러로 들어가 버리거나 하는 것이다.

이것에 대해서는, 조금만 생각해 보면 대처가 가능하다고 여겨진다.

속도맵을 생성할 때에는, 지난회에서 말한 3D모델을 잡아서 늘리는 처리를 하는데, 이 처리가 끝났을 때는, 잡아 늘린 3D모델을 포함하는 씬의 깊이 정보(Z버퍼)가 완성 되어 있게 된다. 블러 생성 단계에서 씬 텍스처를 읽어 올 때, 이 Z버퍼를 참조해서, 그 참조하려는 곳이 보다 앞이면(시점에서 더 가까우면), 이것은 잔상 생성을 위해 참조할 대상으로는 적합하지 않다고 판단을 내린다. 이것에 의해 부적절하게 블러 픽셀이 흘러 들어오는 것을 피할 수 있다.

「로스트 플라넷」(캡콘)으로 부터. 씬 텍스처

         씬 텍스처의 깊이 정보

                          속도맵

방법을 고안하지 않으면 이와 같이, 블러가 되는 곳에 씬의 전후관계를 무시한 픽셀의 침입이 일어나 버린다

속도맵의 깊이 정보를 구해서, 이것을 비교해, 앞에 있는 오브젝트의 픽셀이 뒤의 블러에 영향을 주지 않도록 해 주면……

픽셀의 침입을 큰폭으로 감소 시킬 수 있다


덧붙여, 캡콤의 「로스트 플라넷」에서는, 먼 곳의 움직임에 대해서는, 이 2.5D 블러를 해줘도 눈에 잘 띄지 않기 때문에, 평범한 카메라 블러로 대신 할 수 있다라는 근사 개념을 도입해서, 모션 블러의 생성 부하를 감소 시키고 균일화를 도모하고 있다.

하지만 앞에서 기술한 이론 그대로 카메라 블러를 도입해 버리면, 화면 전체가 너무 움직여, 2.5D 블러와의 친화력이 좋지 않기 때문에, 카메라 블러를 2.5D블러에 통합하는 형태를 취한다.

여기에는 씬의 깊이정보를 이용한다. 씬의 깊이정보는 씬의 각 픽셀의 원근 정보가 기록되어 있으므로, 각각의 픽셀에 대해, 이 원근 정보와 카메라의 이동 벡터 정보를 이용해 계산해서, 속도맵용의 값을 출력해 버리는 것이다. 예를 들면 카메라가 옆으로 이동했을 경우, 가까운 픽셀은 옆으로 많이 이동하고, 먼 픽셀은 옆으로 조금 이동한다. 이러한 정보를 속도맵에 그려 넣어 버린다. 이렇게 해서, 카메라 블러와 2.5D블러를 통합시킬 수 있다.

지오메트리셰이더에 의한 라인베이스 블러

「로스트 플라넷」의 다이렉트X 10 패치 적용 후에는, 앞에서 기술한 2.5D 블러에, 한층더 지오메트리셰이더를 효과적으로 활용한 라인 베이스의 모션 블러를 추가 합성하고 있다.

라인 베이스의 모션 블러에서도, 속도맵을 생성하는 곳과 블러 생성원이 되는 통상적으로 렌더링 한 씬 텍스처를 준비하는 곳까지는, 2.5D 블러와 같다.

그리고, 속도맵을 참조해서, 꺼내 온 속도와 같은 방향의 선분(라인)을 지오메트리세이더를 이용해 생성한다.

이 선분의 색은, 씬 텍스처로부터 꺼낸 색을, 선분의 시점에서의 색으로 하고 종점으로 갈수록 색을 연하게 해서 그린다. 라인이 길면 길수록 색이 연해져, 그 연해지는 정도를 α값으로 넣어 간다. 나중에 이 α값은 2.5D 블러와의 합성 마스크로 이용한다.

덧붙여, 라인을 그리는 것은 스크린좌표계에서 하지만, 제대로 씬의 깊이값을 비교하면서 실시하므로, 씬의 차폐구조를 고려한 블러가 그려지게 된다.

                                    라인 블러의 개념도

<그림 설명>
(박스 좌) 속도맵으로 부터
(박스 중) 라인을 생성한다. 그릴 때에는 씬 텍스처에서 대응하는 위치의 색을 샘플링해서 가져온다
(원) 씬텍스처
(박스 우) 꺼내온 색에서 라인의 시작점에서 끝나는 점까지 그라디에이션해서 그린다.(점점 연하게)
(원) 라인블러 출력 버퍼
(버블)                  현재위치     이전 위치
             색           진하다         연하다
            알파값      불투명         투명
이 처리를 속도맵의 모든 텍셀에 대해서 해준다.


이 공정을 속도맵의 모든 텍셀에 대해서 하게 되지만, 이것을 렌더링 해상도로 하면 선분이 너무 많아 지므로 , 선분 생성용 속도맵은 적당한 저해상도로 하고, 라인블러를 생성하는 버퍼도 똑같이 적당한 저해상도로 한다.

최종적으로는 저해상도의 라인블러 결과를 확대해서, 렌더링 해상도와 똑같은 해상도인 2.5D 블러 결과와 해상도를 일치시켜서 합성해서 완성한다.(계속)

 

「로스트 플라넷」에서. 2.5D 블러만 한 경우.
블러에 면의 경계와 같은 것이 나와 버린다.

  2.5D 블러에 라인블러를 추가한 경우.
  면의 경계감이 사라져, 움직임의 약동감을
  강조하는 극적인 효과선(效果線)으로 보인다.




지오메트리셰이더 : 새로운 표현(Displacement Mapping)


지오메트리셰이더를 활용한 새로운 표현(4) ~
변위매핑(Displacement Mapping)

완전히 평평한 평면(단일 폴리곤)에 대해서, 미세한 요철이 있는 것처럼 음영 처리를 하는 테크닉을 범프 맵핑이라 부르고, 이것의 주류 기법은 법선맵을 활용한다고 본연재의 14회~ 16회에서 이미 말했다.

법선맵을 활용한 범프매핑에서는 실제로 요철이 생기는 것이 아니라, 요철이 있는 것처럼 음영 처리를 할 뿐이므로, 그 폴리곤면에 시점을 접근 시켜서 그 요철을 보면, 실제로는 요철이 없는 것이 드러나 버린다.

이것을 보다 발전시켜, 텍스처에 기재된 요철정보(높이맵)에 따라서, 실제로 3D모델을 지오메트리 레벨로 변위(displace) 시켜 버리는 기술을 「변위매핑」(Displacement Mapping)이라고 부른다.

이미지적으로는, 이미 존재하는 기본 모델에 대해서, 텍스처에 기재된 요철 정보로 디테일을 변형시킨다(정형한다)……는 그런 느낌이다.

텍스처에 쓰여져 있는 요철 정보로 3D모델을 변형시키는 것은 「정점셰이더에서 텍스처를 읽어내 정점을 변위시킨다」라고 하는 작업이 필요하게 된다. 즉, 정점으로부터 텍스처를 참조하는 「Vertex Texture Fetching」(VTF:정점 테크스체링)이라고 불리는 기능에 GPU가 대응하고 있어야 한다. VTF는 다이렉트X 9 세대 SM3.0 대응 GPU에서는, 지원되고 있는 GPU가 혼재했기 때문에, 호환성면에서 적극적으로 활용되는 국면이 적었지만, 다이렉트X 10 세대 SM4.0 대응 GPU에서는 모든 GPU가 대응해야 할 필수기능이 되었기 때문에 적극적으로 이용해도 문제가 없다.

여기에서는, 범프맵핑(법선매핑)보다 좀더 앞선, 변위매핑을 실현하는 두가지 방법을 소개해 나간다.

                                         법선맵에 의한 범프매핑과 변위매핑의 차이

<그림 설명>
平面 (평면)
상:
(제목) 법선맵을 활용한 범프매핑
(박스 좌) 법선맵을 활용했다.
(버블 좌) 법선벡터를 텍스처화 한 것이 법선맵
(박스 우) 픽셀단위의 라이팅을 해서 요철이 있는 것처럼 보이게 한다.
(버블 우) 실제로는 요철(凹凸)이 있을리 없기에 시선을 접근시켜 보면 요철이 없는 것이 드러난다.
하:
(제목) 변위매핑
(버블 좌) 요철을 농담(濃淡)으로 표현한 텍스처가 높이맵(Height Map)
(박스) 이 높이맵을 활용해 실제로 지오메트리 레벨의 요철(凹凸)을 생성하는 것이 변위매핑
(버블 우) 실제로 요철을 생성하기 때문에 시점을 가까이해서 봐도 확실하게 요철이 보인다.

폴리곤을 분할해서 변위매핑을 해 주는 방법

이미 존재하는 3D모델에 대해서 변위매핑을 실행하는 경우, 디테일의 요철(凹凸)을 기재한 높이맵 해상도와, 그것을 적용하는 쪽의 3D모델의 정점 해상도와, 균형이 맞지 않으면 변위매핑의 품질은 떨어져 버린다. 그런 해상도 밸런스를 신경쓰지 않으면 안되는 경우에는, 변위매핑은 활용하지 않고 , 모델제작(othoring) 단계에서 처음부터 그 디테일을 적용한 3D모델을 준비하는 것이 실행시의 부하도 적어 지고 덜 귀찮다.


변위매핑을 하려면 , 높이맵 텍스처와 3D모델의 폴리곤수의 밸런스가 중요하다

<그림 설명>
높이맵、광원
(버블) 이런 요철을 높이맵化
(박스 상좌) 평면이 적절한 폴리곤 수로 구성되어 있으면..
(박스 상우) 그대로의 요철 품질로 변위매핑이 가능하지만...
(박스 하좌) 평면이 충분한 폴리곤 수가 아니면...
(박스 하우) 요철이 정확하게 폴리곤 모델에 반영되지 않는다.

그러나, 만약, 정점수가 적은 폴리곤모델에 대해서, 해상도가 높은 요철(凹凸) 정보를 적용해서, 필요에 따라서 정점을 증가시켜서 변위매핑이 가능하다면, 매우 편리하다. 시점에서 멀 때는 저폴리곤으로, 법선맵으로 요철을 표현하고, 시점에 가까워지는 정도에 따라서 폴리곤 분할수를 올리고, 요철 정보의 반영량도 늘리고, 정밀도가 높은 정형(변형)을 실시하도록 하면, 지오메트리의 LOD(Level of Detail)를 실현할 수 있다.

시점으로부터의 거리에 따라 필요한 폴리곤 분할을 실시하고 나서 변위매핑을 실시하는 것이 이상적

<그림 설명>
높이맵、광원
(박스 좌) 시점이 가까울 때는 하이폴리곤으로 변위매핑
(박스 중) 시점이 멀 때는 로우폴리곤으로 변위매핑
(박스 우) 변위매핑
(버블 상) 변위대상의 정점이 적으면 변위매핑 후의 요철의 품질이 떨어지지만 멀기 때문에 눈에 띄지 않는다.
(버블 하) 하이폴리곤의 변위매핑에서는 요철의 품질은 향상된다. 3D모델이 크게 그려지는, 시점이 가까울 때 사용

이 구조를 실현하기 위해서는 적용하는 요철 정보의 정밀도에 맞추어, 3D모델의 정점을 늘려주는 구조가 필요하다.

3D모델의 정점의 증가……는 좀더 자세히 말하면, 원래의 3D폴리곤 모델을 세세하게 분할해 줄 필요가 있다는 것이다.

이 「폴리곤 분할 처리」(Subdivision)를 실현하는 것이 「테셀레이션」(Tessellation)이라는 테크닉이다. 테셀레이션을 실시하는 기능 모듈을 특히 「테셀레이터」(Tessellator)라고 부른다.

                   테셀레이터는 폴리곤을 분할해 주는 상점

<그림 설명>
테셀레이터、
(버블 좌) 사각형(삼각형 두개)를 분할 레벨2로
(버블 중) 예~ 분할할게요~♪
(박스 상) 테셀레이터는 폴리곤을 주어진 조건으로 분할하는 기계
(박스 하) 폴리곤분할이란 정점이 증가하는 것
(버블 우) 지오메트리셰이더에서 구현 가능해?


ATI의Radeon HD 2000/3000시리즈에는, 실제로 이 테셀레이터의 구조를 하드웨어적으로 구현한 기능블럭이 탑재되어 있지만, 다이렉트X 10에서는 표준기능으로 지원되지 않기 때문에, 호환성의 측면에서는 사용하기가 약간 어렵다. 덧붙여서, 테셀레이터 기능의 다이렉트X에의 편입은 다이렉트X 11에서 실현되는 것이 거의 확실히 약속되어 있다.(계속)

민간 전용GPU로서 세계에서 처음으로 하드웨어 테셀레이터를 탑재한 것은, Matrox가 2002년에 발표한 「Parhelia-512」였다

   최근에는 AMD가 2007년에 발표한「Radeon
   HD 2000」시리즈가 하드웨어 테세레이터를
   탑재했다. 사진은 최상위모델의 「Radeon
   HD 2900 XT」



 

지오메트리셰이더를 활용한 새로운 표현(5) ~ Displacement Mapping

테셀레이션은, 단적으로 말하면 정점의 증가, 즉 폴리곤을 늘리는 것이다. 그렇다는 것은, 「지오메트리셰이더를 사용할 수 있는 것 아닌가?」라는 것이 된다.

ATI는, Radeon HD 2000/3000 시리즈에 테셀레이터 하드웨어가 있음에도 불구하고, 이 테셀레이터를 지오메트리셰이더로 구현하는 예을 제시했다.

ATI의 샘플에서는, 3D모델의 애니메이션이나 스키닝 처리는 통상대로 정점셰이더에서 해 버리고, 한차례, 좌표변환을 끝낸 정점 데이터들을 지오메트리셰이더로 보내, 여기서 테셀레이션을 한다.

ATI의 구현 샘플에서 테셀레이션은 지정한 1에서 9까지의 테셀레이션 레벨(분할 레벨)로 가변적으로 할 수 있는 구조로 되어 있었다.

분할 레벨을 2로 설정했을 때는, 본래의 삼각형의 변들을 2등분 한다. 3이면 변이 3등분,4면 4등분이다. 이 구현에서는 분할 레벨은 정수만 가능하다. 덧붙여, 이런 분할 레벨을 정수로 주어지는 테셀레이터의 구조를 「이산형 테셀레이션」(Discrete Tessellation) 이라고 한다. 그리고 부동 소수점으로 주어지는 구조는 「연속형 테셀레이션」(Continuous Tessellation)이라고 부르고, 한층더 삼각형의 변마다 다른 분할 레벨을 설정할 수 있는 구조는 「적응형 테셀레이션」(Adaptive Tessellation)이라고 부른다.

                                              테셀레이션의 종류(이산형, 연속형, 적응형)


막연히 「분할한다」라고 이야기 하지만, 지오메트리셰이더에서 「어떻게 폴리곤을 생성하면 좋을까?」쉽게 떠오르지 않을지도 모르겠다.

ATI의 구현에서는, 프로그램 루프로 돌리는데도 괜찮은, 심플하고 독특한 분할 방법을 구현하고 있다.

우선, 분할 레벨이 몇 개라 할지라도 최초의 삼각형은 최소 사이즈로 1개 생성하고, 이어서,3개를 서로 엇갈리게 나열해 생성하고, 이어서 5개, 7개…… 로 홀수개로 서로 엇갈려서 나열해 간다. 이것으로 지오메트리셰이에서 삼각형 한변을 분할레벨의 값으로 분할한 형태의 삼각형을 생성할 수 있게 되는 것이다.(계속)

지오메트리세이더를 사용한 폴리곤 분할. 분할이라고 하기 보다는, 분할한 사이즈의 폴리곤을 지오메트리셰이더를 사용해 생성한다는 이미지

<그림 설명>
상:
(제목) 분할레벨이 3인 경우
(박스) 각변을 3등분
분할완료
하:
(제목) 실제의 구현에서는...
(박스 좌) 분할레벨이 3인 경우라면...
(박스 우) 우선 여기부터 1개 생성 -> 다음은 3개 생성 -> 다음은 5개 생성
             분할레벨이 3이라면 1개, 3개, 5개의 3단계 분할처리로 완료
             다른 분할레벨에서도 똑같은 형태의 수순

지오메트리셰이더를 활용한 새로운 표현(6) ~ 변위매핑

분할만 한 3D모델에, 직접 변위매핑을 해도 좋지만, 모처럼 폴리곤 분할을 했으므로, 이 분할한 3D모델을 보다 부드럽게 보이게 하는 방법도 고안하면 고품위의 렌더링을 기대할 수 있다.

ATI의 지오메트리셰이더를 사용한 테셀레이션 기능은, 그러한 아이디어까지 구현되어 있다.

테셀레이션 시에 새롭게 생성된 폴리곤에 대해서, 그 정점 좌표를 고차 곡면 생성 기법인 「베지에 곡면」(Bezier Curved Surface) 방정식으로 산출된 위치로 근사하는 것이다. 베지에 곡면의 좌표나 법선벡터의 계산 방법이나, 그런 정보들을 분할된 삼각형의 정점 정보에 넣어주는 구체적인 수단에 대해서는,ATI의 개발자 사이트에 논문이 게재되어 있으므로, 그 쪽을 참조하기 바란다.

간단히 개념만 설명하면, 분할 대상인 삼각형의 세정점을 지나는 베지에 곡면을 생성해서, 그 곡면에, 분할한 삼각형을 적용시켜 가는 그런 이미지다. ATI의 구현에서는 세개의 정점을 베지에 곡면의 제어점으로 해서 삼차 베지에 곡면을 사용하고 있다. 덧붙여 이 법선 벡터를 부드럽게 뽑아 나가는 곡면 분할 방법은, 「법선벡터(Normal Vector)」의 "N"과, 「모직을 짠다」 「덧댄다」의 "PATCH"를 취해서 N-PATCH법, 혹은 「PN Triangle」(PN=Point Normal)법이라고 불린다.

                     삼차 베지에 곡면

                   입력 정점

 

왼쪽이 각 정점을 직선으로 묶고 나서 음영 처리를 실시한 것. 오른쪽은 각 정점을 삼차 베지에 곡면으로 묶어 음영 처리를 실시한 것

  다각형 분할 레벨(상단)과, 그
  분할 레벨로 베지에 곡면을 적용했을
  때의 렌더링 결과(하단)


세정점을 지나는 베지에 곡면은 몇개의 패턴을 생각할 수 있는데, 제어 파라미터로서 각 정점의 법선 벡터를 도입하면 적합한 베지에 곡면은 저절로 결정되어져 온다. 그림은 세정점의 법선벡터에 따라서 달라지는 세개의 베지에 곡면을 나타낸 것

이와 같이 해서, 폴리곤을 분할하고, N-PATCH로 변위시켜서 생겨난 3D모델을, 다시 정점셰이더에 되돌려 VTF에서 요철 정보로 변형해 변위매핑을 실행……이것으로 지오메트리 관련 처리는 완료 된다. 이 이후의 것은 픽셀셰이더 phase로 이행한다

로우폴리곤 모델을 적당하게 폴리곤을 분할해서, 높이맵으로 변위매핑한다……라는 것이 이상적인 구현. VTF와 테셀레이션의 기능을 구현하면 이것이 가능하게 된다

더욱더 이 기능를 고도로 한다면 , 시점으로부터의 거리에 따라서, 볼룩한 상태나 오목한 상태가 어떤 일정 레벨 이상인 요철에 대해서만, 변위매핑으로 지오메트리 레벨에서의 변위를 해주고, 그 이하의 요철에 대해서는, 법선 맵에 의한 범프 맵핑으로 표현하면 좋을 것이다. 이러한 적응형 처리로 변위매핑과 법선맵에 의한 범프매핑을 나누어 사용하면, 지오메트리 부하와 픽셀 부하의 균형을 맞출 수 있을 것이다.(계속)

이상적인 것은 시점으로부터의 거리에 따라 범프 맵핑과 변위매핑을 동시에 사용하는 하이브리드 방식

<그림 설명>
(버블 좌) 이런 크고 작은 요철(凹凸)이 있다고 가정했을 때
상:
광원, 법선맵
(박스 상) 범프매핑
(박스 하) 시점에서 멀 때는 범프매핑만으로 요철을 표현
하:
법선맵, 높이맵
(버블 상) 그 시점에서 눈에 띄지 않는 것은 범프매핑
(버블 하) 그 시점으로 부터 확실하게 만들지 않으면 부자연스러운 요철은 확실하게 변위 맵핑
(박스 좌) 시점에 가까워지는 것에 따라 폴리곤을 분할해 감...
(박스 우) 시점으로 부터 실제로 요철이 없으면 부자연스럽게 보이는 요철은 변위매핑하고, 눈에 띄지 않는 요철은 범프매핑한다.



지오메트리셰이더를 활용한 새로운 표현(7) ~

폴리곤 기둥을 세워 국소적으로 볼륨렌더링을 하는 변위매핑 

형태가 크게 바뀌지 않는, 이를테면 디테일한 장식 정도의 3D모델의 형태 변형이라면, 테셀레이터를 구현하지 않는 변위매핑(Displacement Mapping)의 실현방법 쪽이 더 무게가 실린다.

그것은 기본 형태의 3D모델의 외피(外皮)에 각주(角柱, 각이 진 기둥 모양의 폴리곤)를 세워, 거기에 대해서만 국소적으로 볼륨 렌더링을 실행해주는 방식이다.

각주(角柱)를 세우는 것은 계산량 면에서 베지에 곡면을 계산하는 것보다는 부하가 낮다. 그러나, 실제로 지오메트리레벨의 볼록다각형을 만는 것이므로 입체적인 요철(오목과 볼록) 표현이 가능하다.

이 방법에서는, 대상 3D모델을 구성하고 있는 폴리곤(삼각형) 중에, 변위매핑을 할 대상에 대하여, 지오메트리셰이더를 이용해 그 폴리곤을 바닥면(밑면)으로 하는 각주(角柱)를 세우는 것 부터 시작한다.

폴리곤 기둥을 세우고, 국소적으로 볼륨 렌더링을 해주는 변위매핑의 개념

<그림 설명>
(박스 좌) 지오메트리셰이더에서 법선벡터 방향으로 3개의 옆면(변)을 만든다.
(박스 우) 삼각 기둥을 생성
(버블) 이 삼각 기둥에 대해서 국소적으로 볼륨 렌더링을 한다.
완성

접근방법에 대한 이미지로서는, 각주(角柱)로 대략적인 볼록(凸)을 만들고, 거기서 부터 높이맵을 이용해서, 픽셀 단위의 요철을 볼륨 렌더링이라는 조각칼로 깎아 나가는 느낌을 연상하면 될 것이다.

앞에서 말한 것처럼, 삼각기둥의 바닥면(밑면)은 3D모델의 폴리곤이다. 이 바닥면으로부터 세운 세 옆면은, 이 바닥면 폴리곤의 세정점들의 법선 벡터 방향으로 세운다. 이렇게 함으로써, 인접한 3D모델의 폴리곤으로부터 차례차례로 각주를 세워 갈 때에도  틈새 없이 끝난다.

바닥면 폴리곤의 세정점의 각각의 법선벡터의 방향으로 옆면들을 세워 삼각기둥을 만든다.

이 바닥면 폴리곤의 법선 벡터 방향으로 늘린 삼각기둥을 지탱하는 세변의 길이는, 만들어 낼 볼록부분의 최대 높이값으로 한다.

삼각기둥의 옆면들은 두개의 삼각형으로 만들어지므로, 이것을 이용하면 이 삼각기둥들은 3개의 사면체로 분할할 수 있다.

삼각기둥은 옆면 폴리곤을 한면으로 하는 세개의 사면체로 분할할 수 있다

이후는 이 3개의 사면체에 대해서, 각 사면체의 밑면의 깊이값과, 요철(凹凸)을 기록한 높이맵으로부터 꺼낸 높이값을 비교해서 시선이 충돌하고 있는지 아닌지를 판단해 볼륨 렌더링을 해 나간다. 이 부분은 본연재 제17회 「시차 차폐 매핑」과 거의 같다.

시선을 조금씩 늘려 가면서 그 위치에서의 사면체의 밑면의 깊이값과 높이맵의 높이값를 비교해 충돌하고 있는지를 판정. 충돌하고 있으면 거기에 대해서 픽셀 음영 처리를 실시한다. 아니면 시선을 좀더 늘리고……이후 반복. 마지막, 세번째 사면체를 빠져 나오는 시점에 처리를 종료한다

이 방법의 경우, 맨처음 방법과 비교해 정점셰이더나 지오메트리셰이더의 부하는 적지만, 그 만큼 픽셀셰이더에서의 부하는 높아진다.

변위매핑에서 생성된 요철(凹凸)의 셀프 그림자 표현도, 시차 차폐 매핑에서 소개한 셀프 그림자를 추가하는 방법을 응용하면 불가능하지는 않지만, 부하와 난이도는 높아진다.

 

이 방식의 변위매핑 데모(다이렉트X SDK의 데모로 부터). 변위매핑에 의해 등지느러미와 가시가 추가되어 있다.

  끄면(Off) 등지느러미와 가시가 사라진다


 

Posted by 노을삼킨별
,

아래에서 퍼옴

http://allosha.tistory.com/category/니시카와%20젠지/지오메트리%20셰이더



지오메트리셰이더 : 가속을 위한 활용(Stencil Shadow Volume 가속)

2008-09-15 22:05:00
2007年1月、Windows Vistaの登場と共にDirectX 10がリリースされ、同時にプログラマブルシェーダ仕様(SM:Shader Model)は4.0へとバージョンアップがなされた。このSM4.0で最大のトピックといえるのが「ジオメトリシ ...... >> Read more

(C) Mainichi Communications Inc. All rights reserved.



 

2007년 1월, 윈도우즈 비스타의 등장과 함께 다이렉트X 10이  릴리즈됨과 동시에 셰이더 사양(SM:Shader Model)은 4.0으로 버전업 되었다. 이 SM 4.0에서 최대 토픽이라 할 수 있는 것이 「 지오메트리셰이더 」(Geometry Shader)이다. 이것은 지금까지 GPU 내부에서는 할 수 없었던 정점을 증가 또는 감소 시킬 수 있는 획기적인 기능이다.

아직 나온지 얼마 되지 않은 기능이라서, 그 응용방법은 현재도 각 개발씬들에서 연구들이 진행되고 있는 상황인데, 서서히 독특한 사용법들이 계속해서 등장하고 있다.

여기에서는 지오메트리셰이더의 대표적인 활용방법 몇가지를 소개한다.


지오메트리셰이더란?

본연재 초반에서도 말한 것처럼, 지오메트리셰이더는 다이렉트X 10 / SM 4.0 환경이 아니면 사용할 수 없다. 다이렉트X10은 윈도우즈 비스타 전용으로 공급되므로, 즉 윈도우즈 비스타 환경이 아니면 사용할 수 없다.

지오메트리셰이더가 하는 일은 프로그램에 따라서 정점을 증가 또는 감소시켜주는 것이다. 정확하게 말하면 선분, 폴리곤(삼각형), 파티클 같은 「프리미티브」를 증가 혹은 감소 시킬 수 있다. 덧붙여서 여담이지만, 지오메트리셰이더는 다이렉트X 10 개발 초기에는 「 프리미티브셰이더 」(Primitive Shader)라고도 많이 불렸다.

                              지오메트리셰이더의 개념


<그림 설명>
정점、지오메트리셰이더프로그램
(버블 상) 지오메트리셰이더는 셰이더프로그램에 따라 정점을 증가/감소 시키는 일을 한다.
ポリゴン(폴리곤)
(버블 하) 실질적으로 지오메트리셰이더는 폴리곤이나 선분등을 만들어 낼 수 있다.


그런데, 이 지오메트리셰이더를 사용하면 대체 어떤것이 가능한 걸까?

지금까지 등장한 여러가지 지오메트리셰이더의 활용들을 분류해 보면 2종류로 나눌 수 있다.

하나는 「렌더링 가속을 위한 활용」이고, 또 하나는 「새로운 표현을 위한 활용」이다.
전자는 표현된 결과는 똑같지만, 지오메트리셰이더에 의해서 렌더링 퍼포먼스를 크게 증가 시키기 위한 것이다. 후자는, 지금까지는 실현이 어려웠던 표현이 지오메트리셰이더를 활용해서 쉽게 실현될 수 있다 ……는 것이다.

현재는, 앞에서 이야기 한 것처럼 등장한지 얼마 않되서, 말하자면 지오메트리셰이더의 여명기라고도 할 수 있는 시기여서 어느쪽이라고 말한다면, 전자의 가속을 위한 활용쪽이 더 많은 것 같다.

우선은, 이 「 가속을 위한 활용 」쪽 부터 보도록 하자.


지오메트리셰이더의 가속을 위한 활용 그 첫번째 ~
스텐실 그림자 볼륨 기법의 그림자 생성을 가속한다

지난회까지의 「 그림자 생성 」부분에서 다룬 「 스텐실 그림자 볼륨 」기법에서는  광원에서 봤을 때 윤곽이 되는 정점을 광원 벡터 방향으로 잡아 늘여서 그림자 볼륨(그림자 영역)을 생성하는 것부터 시작했다.

SM 3.0 세대까지의 정점셰이더와 픽셀셰이더 밖에 없던 GPU에서는, 이 그림자 영역 생성용의……즉, 잡아 늘일 정점들을 그림자를 생성할 3D모델에 넣어 줄 필요가 있었다. 이 방법에서는 그림자 생성과 아무 관계 없어도 그림자 영역(볼륨)을 위한 정점 계산에 정점셰이더가 사용되기 때문에 부하가 높다. 부하를 감소시키기 위해 그림자 볼륨 생성 전용의, 화면에는 표시하지 않는 로우폴리곤 모델을 준비해서, 이것에 대한 그림자 볼륨을 생성하는 테크닉도 있다. 그러나 이 최적화에서는 그림자의 생성원이 로우폴리곤이기 때문에, 그저 그런 컬리티의 그림자가 생기기 쉽다는 약점이 있다.

근본적으로 문제를 해결하기 위해서는, 동적으로 광원 방향에서 보고 윤곽인가 아닌가를 판단하고, 만일 그렇다면 여기서 그림자 영역용의 정점을 동적으로 생성하면 된다.

지오메트리셰이더를 사용하면 이런 처리가 가능하다. 지금까지 귀찮았던 「볼륨생성용 정점」을 3D모델에 넣어줄 필요가 없고, 또 그림자 영역(볼륨)과 관계 없는 불필요한 정점처리로부터도 해방되어 개발 작업 효율도, 데이터 레벨에도, 퍼포먼스적으로도 가속화가 실현된다. (계속)

그림자 볼륨을 가시화한 예. 광원에 대해서 윤곽이 되는 정점들을, 동적으로 지오메트리 셰이더에서 복제해서, 이것을 잡아늘리는 처리를 하도록 처리를 개선



지오메트리셰이더 : 가속을 위한 활용(Fur Shader 가속)

3D캐릭터에 털(毛)을 만들어 주는 「 퍼셰이더 」(Fur Shader)라고 불리는 테크닉이 있다.

이 퍼셰이더에는 크게 두가지 방법이 있고, 한쪽 또은 양쪽을 조합해서 사용하는 것이 일반적이다.


가속을 위한 활용(2) ~ 퍼셰이더를 가속한다

하나는 털(毛)을 그린 텍스처를 붙인 폴리곤을 3D캐릭터에 심는 접근방법인 「핀」(Fin:지느러미) 방법이다.

 

"털 Fin"을 심어서 털을 재현하는 핀법. 털 Fin을 연결시켜 장발(長髮)을 표현하는 경우도 있다

 


이 기법에서는, 사전에 3D캐릭터에 모를 심듯 털 Fin들을 3D캐릭터 본체에 심어 둘 필요가 있다.

이 방법에서는 털의 유무를 알기가 어려운, 시점에서 멀리 위치한 3D캐릭터에도, GPU는 심은 털을 위한 정점 처리나 픽셀 그리기를 해야 할 필요가 있기 때문에 낭비가 심하다.

지오메트리셰이더를 이용하면, 미리 3D모델에 털을 만들 필요가 없고, 렌더링 시에 리얼타임으로 동적으로
 " 털을 심는 " 것이 가능하다.

동적 생성으로 인해 이차적인 메리트도 생긴다.

예를 들면, 3D모델 정보를 만지지 않고도 , 하나의 3D모델을 재사용해 털의 길이나 털의 밀도를 바꾼 3D캐릭터를 렌더링 할 수 있다.

또, 시점에서 멀리 있는 캐릭터에 대해서는 털 Fin을 심는 개수를 줄여서 대충하거나 너무 먼 경우는 털 Fin을 심지 않는 LOD(Level of Detail:시점에서의 거리에 따라 고부하의 처리와 저부하의 처리를 나누어 처리)적인 기능을 구현할 수도 있다.

                               Fin법의 개념도


< 그림 설명>
제목: 핀(Fin)법의 퍼셰이더
상:
털(毛)을 그린 텍스처 폴리곤을 심는다.
(버블) 단, 사전에 3D모델에 심어두지 않으면 않된다.
하:
지오메트리셰이더,
지오메트리리셰이더를 활용하면 런타임 때 털을 심을 수 있다.


핀법의 Fur 표현에서의 라이팅에 대해서는 여러가지가 고안되어 있지만, 가장 단순한 것은 털 Fin에 대해서 간이적인 정점 단위의 라이팅을 하는 것이 비교적 부하가 적고, 자주 사용되는 것 같다.

이것은, 털 Fin에 대해서 광원 방향에 가까운 방위각 부터 명→암의 그라데이션을 걸기만 하는 간단한 방법이다. 털의 밑부분은 다른 털에 의해서 빛이 차단되지만, 이 간이 방법에서는 거기까지 대처할 수가 없기 때문에, 하이라이트가 털의 밑부분 쪽에서는 별로 나오지 않도록 방법을 고안해 줄 필요가 있다.(계속)

                              핀법에서의 털에 대한 간이 라이팅

<그림 설명>
상:
(박스 좌) 그대로 사용하지 않고
(박스 우) 정점단위의 라이팅을 해준다
명,
털 Fin에 대해서 정점단위의 라이팅을 해주면 씬에 동화된 털의 표현이 가능하다.
하:
(버블 좌) 털의 밑부분이 밝게 보일리는 없음에도...
(버블 중, 우) 털의 밑부분이 지나치게 밝지 않도록 바이어스를 걸어두는 게 좋을지도




지오메트리셰이더 : 가속을 위한 활용(Shell법 Fur Shader)


퍼셰이더(Fur Shader)를 가속한다 / 그 두번째~ 쉘법(Shell法) 퍼셰이더

핀법(Fin法)으로 생성된 퍼(Fur, 毛)는, Fur Fin을 측면에 가까운 방향에서 바라볼 경우에는 탐스럽게 많이 늘어진 느낌이 들지만, 털끝이 시선 방향에 가까우면, 즉 Fur Fin을 수직으로 내려다 볼 때는 털의 볼륨감이 사라진다는 약점이 있다.

또 하나의 퍼셰이더는 Fin방법의 약점을 보완하고 극복하는 기법이다.

핀법(Fin法)에서는 털을 세로 방향으로 자른 단면도(斷面圖)를 준비했지만, 또하나의 방법에서는, 나있는 털을 가로방향으로 둥글게 자른 듯한 단면도를 준비해, 이것들을 종이를 겹쳐 쌓는 느낌으로 일정 간격으로 겹쳐서 그려 간다. 둥글게 자른 단면도를 겹처서 원래대로 되돌리는 것 같은 이미지로, 마치 외피(Shell)를 형성하듯이 적층(積層)시키는 듯한 느낌에서, 이런 접근의 퍼셰이더를 「쉘」(Shell)법이라고 부른다. 단면 텍스처로 입체적인 물건을 재구성하는 렌더링 기법에는 볼륨 렌더링이라는 것이 있는데, 이미지적으로는 이것에 가깝다고도 할 수 있다. 덧붙여, 단면도 화상 텍스처에 투명성분(알파성분)를 가미해 반투명(半透明)하게 해서 털의 투명한 감촉을 낼 수도 있다.

                        셀법(Shell法)의 개념

<그림 설명>
좌:
단면도 텍스처를 생성(↓)
단면도 텍스처를 붙인 폴리곤을...(↓)
적층(積層)시켜서 그림

우:
(제목) 쉘법(Shell法)의 Fur 셰이더
(버블) 쉘법에서도 사전에 단면텍스처 폴리곤을 적층시킨 3D모델을 준비할 필요가 있다.
ジオメトリシェーダ (지오메트리셰이더)
(버블) 지오메트리셰이더가 있으면 단면 텍스쳐 폴리곤의 적층을 런타임 때 할 수 있다.


쉘법은 단면도를 적당한 간격으로 적층시키지만, 이 간격을 얼마나 조밀하게 다량의 단면도를 적층시킬것인가가 퀄리티를 좌우한다. 적층시키는 매수가 적으면 부식된 것처럼 보이고, 많으면 부하가 커진다. 그다지 시선이 대상물에 가까이 접근하지 않는다면, 최근의 3D게임에서는 4~8층 정도가 일반적인 것 같은데, 시선이 3D캐릭터에 의존할 때는 적층수가 많은 편이 보기에 좋을 것이다.

하지만, 핀법과 마찬가지로 SM 3.0세대까지의 GPU에서는 쉘법 또한 단면도 텍스처를 적용한 폴리곤을, 3D모델에 미리 넣어둘 필요가 있었다.

지오메트리셰이더를 활용하면, 이런 사전 작업 없이, 실시간으로 동적으로 생성하는 것이 가능하다. 또, 시선과 대상물의 위치 관계에 따라서, 단면도 텍스처의 적층수를 증가 또는 감소 시키는 LOD적인 구현도 가능하다.

쉘법에 의해 만들어진 털

PS2용 게임「완다와 거상」에서는 털 표현에 쉘법의 퍼셰이더를 활용했다

PS2에는 지오메트리셰이더는 없었기 때문에, 3D모델 제작단계에서, 이 Fur를 적층시켜야만 했다.

단면도 텍스처는 단순한 화상 텍스처만으로도 괜찮지만, 함께 대응하는 법선맵(노말맵)도 준비해, 광원 벡터나 시선벡터의 위치 관계에 따라 픽셀 단위의 이방성 라이팅을 해서, Fur에 독특한 광택감을 낼 수도 있다.

라이팅은, Fin 때처럼, 역시 털의 밑부분은 하이라이트가 어둡도록 조정하는 편이 좋을 것이다.

융단과 같이 짧은 털에서는, 시선으로부터 털이 "점"으로 보이는 털끝에는 하이라이트가 약해지고, 반대로 털의 측면 …… 즉 털이 "선"으로 보일 때는 빛이 잘 반사해서 하이라이트가 나오기 쉽다. 이 특성을 구현하려면 , 통상적인 확산 반사 처리에 추가해서, 법선벡터가 시선 벡터와 마주보고 있으면 하이라이트를 약하게 하는 이방성 처리를 하면 좋다. 이 아이디어는 PS 2용 게임 「완다와 거상」에 활용되었다. (계속)

보통의 확산 반사 라이팅에서는 광원과 마주볼 수록 하이라이트가 더 나온다.

시선과 면의 방향(법선 벡터)이 서로 마주 보고 있는 곳에서는 하이라이트를 감소 시키는 처리를 넣으면 짧은 털의 음영이 리얼해진다.

지오메트리셰이더 : 가속을 위한 활용(Fur Shader 응용)

퍼셰이더(Fur Shader)를 가속한다 / 그 3번째 ~ 퍼셰이더의 응용

쉘법(Shell法)은 핀법(Fin法)과는 반대로, 털끝의 연장선 상에 시선이 있는 것 같은, 시선과 털끝이 마주보는 위치 관계일 때에도, 폭신한 볼륨감을 얻을 수 있는 퍼셰이더이다.

핀법과 쉘법은 서로 보완 관계에 있으므로, 실제로 몸에 털이 짙게 나있는 캐릭터를 리얼하게 표현고자 하는 경우에는 양쪽을 동시에 조합해 사용하는 것이 좋다고 여겨진다.

이것을 지오메트리셰이더 없이 하려면 사전에 Fur(毛) Fin을 심어 놓지 않으면 안되고, 털의 단면도(斷面圖) 폴리곤을 미리 적층(積層) 시켜 놓지 않으면 않되기 때문에 뭔가 일이 커진다.

지오메트리셰이더가 있으면, 두종류의 "털 생성 기법"을 사전준비 없이도 모두 할 수 있다.

핀과 쉘 양쪽 모두 구현한 NVIDIA 데모의 구현예

좀더 고도의 구현을 하려 한다면, 털을 심을 맨살갗 폴리곤의 법선벡터와, 시선과의 관계를 확인해서, 털의 측면이 보이는 위치에 있는 살갗에는 핀법으로 털을 넉넉하게 적용하고, 털끝과 시선이 마주 보는 위치의 살갗에는 쉘법으로 털을 넉넉하게 해주는 적응형 콤비네이션 퍼(Fur, 毛)도 가능하다.

                           퍼셰이더의 응용 발전형

시선에서 봤을 때 윤곽이 되는 정점에서 지오메트리셰이더를 사용해 폴리곤을 생성해서 여기에 Fur Fin을 심는 NVIDIA 데모의 구현예

<그림 설명>
상:
(제목) 퍼셰이더의 적재적소
시점、
(버블 좌) 살갗과 시선이 서로 마주하는 곳에는 쉘법(Shell法)으로
(버블 우) 시선에서 볼 때 윤곽 부근이면 핀법(Fin법)으로
중:
(제목) 퍼세이더의 LOD구현
(좌) 시점에서 가까울 때는 털을 많이
(우) 시점에서 멀 때는 털을 감소 시키면 부하가 준다
하:
(좌) 지오메트리쉐이더 상에서 실루엣 검출
노말벡터 N1과 시선벡터의 내적이 0보다 크고, 노말벡터 N2와 시선벡터의 내적이 0보다 작으면 외곽선
(우) 실루엣 extrusion
N2 노말벡터가 0보다 작으면(실루엣 엣지이면) 두개의 삼각형으로 그것을 extrude


또, 지오메트리셰이더나 정점셰이더 프로그램을 좀더 고도로 만들어서, 털을 바람에 나부끼게 한다든지, 가속이나 감속, 중력이나 완성 등을 고려해, 생성한 털에 애니메이션을 주는 것도 재밌는 응용이 될 것이다. 이 경우, 털끼리의 충돌이나, 털과 다른 오브젝트와의 충돌은 해주기 어렵기 때문에 무시하게 되겠지만, CPU가 개입되지 않아도 털의 애니메이션을 실현시킬 수 있다.

또, 이러한 퍼셰이더는 털을 생성하는 것 뿐만이 아니라, 응용에 따라서 다른 표현에도 사용할 수 있다.

가장 흔한 예가 잡초의 표현이다.

핀법에서 머리카락의 텍스처로 하고 있는 것을 초목의 옆에서 본 면으로해서 이것을 지면에 기르면 밀집한 초목이 완성된다.

또, 쉘법이라면, 단면도 텍스처의 색을 적당한 초록색 계열이나 갈색계열로 해서 지면에 적용하면 잔디와 같은 잎이 짧은 식물이 융단처럼 밀집해서 우거져 있는 지면을 표현할 수 있다.

이 경우에도 바람에 나부끼는 것처럼 하면, 리얼리티는 한층 더 향상된다.

다만, 3D캐릭터가 초목을 밀치고 가는 것과 같은, 동적인 캐릭터와 퍼셰이더로 기른 초목과의 interaction를 취하는 것은 어렵다. 초목의 길이를 너무 길게 하면 잎이 동적 캐릭터의 몸속으로 들어간다거나 하는 부자연스러움이 눈에 띄게 된다.

쉘법으로 생성한 키 작은 초목이면, 동적 캐릭터가 밟은 부분은 적층 간격을 좁힌다든지 또는 퍼(Fur) 자체를 생성하지 않음으로써 발자국의 표현 같은 것은 가능할 것 같다.(계속)

「완다와 거상」에서는 퍼셰이더를 초목의 표현에도 응용했다.
(C) 2005 Sony Computer Entertainment Inc.


Posted by 노을삼킨별
,