[Ndc11 박민근] deferred shading

Preview:

Citation preview

새로운 동적 라이팅의 세계 !

Deferred Shading ( 지연 세이딩 )

박민근 ( 알콜코더 )네오위즈 게임즈NDC 2011

강연자 소개박민근 (@agebreak)

네오위즈 게임즈 ( 프로젝트 S 개발중 )NTL-inc - 드래곤볼 온라인 개발엔씨소프트 – PlayNC 빌링 서버 개발

‘ 신입 게임 개발자의 서울 상경기’(http://agebreak.blog.me)‘ 초중급 게임 개발자 스터디 ( 데브루키 )’(cafe.naver.com/devrookie)VisualStudio 2010 공식 팀 블로그(http://vsts2010.net/)

게임 클라이언트 프로그래머30 대… 솔로 인생…

그리고 오타쿠 프로그래머 ...언젠가는 우즈벡에 .. 일류젼 우즈벡 지사를 설립할 예정

Real-Time Rendering최근 게임들은 수 많은 라이트와 수많은 오브젝트 들이 필요하다 .

-> 라이팅 계산양의 증가

수많은 작은 동적 라이팅

낮 (Day)

해질녘

저녁 (Night)

동영상 시연

리얼 타임 라이팅을 위한 세가지 주요 기법

• 포워드 렌더링 (Forward Rendering)• Single-pass, Multi-light• Multi-pass, Multi-light

• 디퍼드 렌더링• Deferred Shading

포워드 렌더링

Single-pass, multi-light

for each object dofor each light do

framebuffer = light_model(object,light);

Single-pass, multi-light

• 해당 라이트에 영향을 받지 않아도 라이트 연산 .

• 화면에 렌더딩 되지 않는 면 (Culling) 도

셰이딩 연산을 해야만 한다 .

• 멀티 라이트 상황에서 관리가 어렵다• 싱글 템플릿 셰이더에서 수천 가지의 조합의 코드가 생성될 수 있다 .

• 그림자와의 통합이 어렵다

Single-pass, multi-light1 억 개의 오브젝트 , 50 개의 라이트

[ 라이팅만을 위한 계산양 ]

1 억 * 50

Multi-pass, multi-light

for each light dofor each object affected by light do

framebuffer += light_model(object,light);

Multi-pass, multi-light

• 화면에 렌더딩 되지 않을 면도 셰이딩 연상을 해야만 한다 .

• 높은 배치 카운트

• 1/object/light

• 각 패스마다 중복된 작업이 많다 .• Vertex Transform & setup• Anisotropic filtering

Multi-pass, multi-light

1 억 개의 오브젝트 , 50 개의 라이트[ 라이팅만을 위한 계산양 ]

50 * 라이트의 영향을 받는 오브젝트 개수

디퍼드 렌더링

Deferred Shadingfor each object do

G-buffer = lighting properties of object;

for each light doframebuffer += light_model(G-buffer,light);

Deferred Shading• 굉장히 배치가 간단해지고 , 엔진에서 관리가 쉽다

• 일반적인 그림자 테크닉들과 통합이 쉽다

• 라이팅을 위한 계산이 “완전한” O(1) 복잡도를 가진다 .

• 오브젝트의 개수와 상관없다

• 수많은 작은 동적 라이팅 사용이 가능하다

Deferred Shading1 억 개의 오브젝트 , 50 개의 라이트

[ 라이팅만을 위한 계산양 ]

라이트 개수 * 라이트에 영향받는 픽셀 개수

Deferred Shading• 일종의 포스트 프로세싱처럼 수행된다

• 2D 렌더 타겟간의 계산이다 .

• 3D 계산을 -> 2D 계산으로 변환 시킨다 .

• 오브젝트는 라이팅 계산이 전혀 없이 속성만을 렌더링 한다 .

• 화면에 실제로 렌더링 되는 픽셀만 라이팅 계산을 수행한다 .

라이팅 계산을 먼저 하지 않고 , 미루어 두었다가

실행하기 때문에 지연 (Deferred) 셰이딩

이라고 불리운다 .

Deferred Shading

이미 1988 년의 시그래프 논문에서 이 기법이 소개 되었다 . • 그때는 Deferred 라는 용어는 사용하지 않았다 .

그래픽 카드의 발달으로 이젠 실시간에 사용 가능 !!

요구 조건• MRT(Multi Render Target) 을 기본적으로 4 장 이상 사용한다

• DirectX 9 이상

• 지포스 6800 이상

• ShaderModel 3.0 이상

• 위 조건이면 사용 가능

• 현재의 그래픽 카드로는 당연히 !! 전부 지원 가능

사용한 게임들

CryEngine 3

기타 등등…

실장된 엔진들

샘플 동영상• Unity 엔진 – Deferred Rendering

샘플 동영상

샘플 동영상

• UDK( 언리얼 ) - Samaritan

디퍼드 렌더링구현 방법

General Architecture

G-Buffer 란 ?

• Geometry Buffer

• Per-Pixel 라이팅에 필요한 모든 정보• Normal

• Position

• Deffuse / Specular Albedo, Other Attributes

1. 지오메트리

패스(G 버퍼 작성 )

지오메트리 패스• 3D 공간의 지오메트리 ( 오브젝트 ) 데이터의 속성값들을

G-Buffer 에 렌더링 하는 단계• 라이팅 처리는 하지 않는다 !

• MRT(Multi Render Target) 을 사용해서 , 한 패스에 4개의 렌더 타겟에 정보를 렌더링 한다 .• Depth

• Normal

• Diffuse / Specular

지오메트리 패스

2. 라이팅

패스( 픽셸 셰이딩 )

라이팅 패스 라이팅을 지오메트리 형태로 렌더링 한다 .

Point Light = Sphere Spot Light = cone Sun = full Screen Quad

라이팅 패스 각각의 라이팅에 대해서

라이팅에 영향을 받는 픽셀을 찾아내서 체크한다 . 만약 라이팅이 스크린에 영향을 준다면…

Render Shadow Map 라이팅 픽셀을 셰이딩하고 FrameBuffer 에 추가한다 .

라이팅 패스 각각의 라이팅에 영향을 받는 픽셀들의 계산 결과를

누적 (accumlation) 버퍼에 블렌딩 한다 . Diffuse 값과 , Specular 값은 별도로 저장한다 .

For each light:diffuse += diffuse(G-buff.N, L))specular += G-buff.spec *

specular(G-buff.N, G-buf-f.P, L)

라이팅 패스 최종적으로 원본의 Diffuse 값과 누적

버퍼에 누적된 픽셀 값들을 곱하여 결과를 출력한다 .framebuffer = diffuse * G-buff.diffuse + specular

Per-Pixel Lightingfloat4 PointLightingPS(VS_OUTPUT1 In) : COLOR{ half4 diffuseTex = tex2D(MRT0Sampler, In.TexCoord); half4 normalTex = tex2D(MRT1Sampler, In.TexCoord); half z = tex2D(MRT2Sampler, In.TexCoord);

//unpack half3 albedo = diffuseTex.xyz;…//reconstruct original view-space position…//normalize…//diffuse lighting half NdotL = dot(normal, lightVec); half selfShadow = (NdotL > 0) ? 1 : 0; half3 diffuse = albedo * NdotL * selfShadow * LightColor;

Per-Pixel Lightingfloat4 PointLightingPS(VS_OUTPUT1 In) : COLOR{ ( 앞페이지… ) //compute half angle half3 halfAngle = normalize(lightVec + eyeVec);

half3 specular = max(pow(dot(halfAngle, normal), SpecularExponent), 0) * selfShadow; … ( 후략 )}

디퍼드 셰이딩장점

완전한 O(1) 시간에 , 수많은 동적 라이팅의 처리가 가능

오브젝트의 개수에 상관없이 상수 시간에 라이팅의 처리가 가능하다 .

• 다수의 라이팅의 렌더링 처리 코드가

간단하며 , 관리가 쉽다 .

• 중간 과정에서 만들어진 G-Buffer 의

속성들을 다른 기법에 재활용이

가능하다 . ( 포스트 프로세싱 등 )

• 그림자 기법들과 통합이

용이하다 . ( 셀프 셰도우 ,

소프트 셰도우 , SSAO 등 )

디퍼드 셰이딩문제점

MRT(Multi Render Target) 많은 렌더 타겟을 필요로 한다 . 하지만 어차피 포스트

프로세싱을 한다면 ? 필요하니까…

MSAA(Anti Aliasing) 2D 스크린 화면에서의 계산이기 때문에 계단

현상 (Aliasing) 해결이 어렵다 .

포워드 렌더링에서는 지오메트리 단계에서 얼라이어싱이 되지만 , 디퍼드 렌더링에서는 되지 않음

여러가지 개선 방법이 연구 중

Transparency 반투명한 오브젝트의 렌더링이 어렵다 .

2D 공간 스크린 정보이기 때문 (뒤 픽셀의 정보를 담을 수 없다 )

파티클등의 반투명한 오브젝트는 나중에 포워드 렌더링으로 따로 렌더링 해야만 한다 .

같이 사용하면효율적인 기법

• SSAO (Screen Space Amibent Occlu-sion)

• Motion Blur• Bloom• HDR

• GI ( 전역 조명 )• 전역 셰도우 기법들• 기타 포스트 프로세싱 기법들

디퍼드 셰이딩개선 기법

Light Indexed Deferred Light-ing

• light volume 들이 scene 과 교차하는 지점에 light index 값을 저장하여 렌더링하는 기법

• 반투명 , MSAA 문제 해결됨• 포워드 렌더링과 디퍼드 렌더링의 장단점을 보완• 지오메트리를 2 pass 렌더링해야하고 , 그림자

제공이 어려움• 아직 연구의 여지가 있는 기법

결론

수많은 동적 라이팅을 화면상의 오브젝트의 개수와 관계없이 상수시간에 처리가 가능함

이론상 무한개의 동적 라이팅 사용 가능

어두운 실내나 , 어두운 배경에 동적 라이팅이 많은 경우 최적의 해결 방법 (ex. 데드 스페이스 2)

현재의 그래픽 카드에서는 당연히 지원됨

별다른 노력 없이 , 유명 상용 엔진에서는 기본적으로 지원됨 (한큐에 ~)

직접 구현 해도 , 개념이 어렵지 않고 , 관리가 쉬움

셀프 셰도우등 그림자 기법이 용이함

어차피 다른 포스트 프로세싱

(Bloom, HDR 등 ) 을 사용하는 게

요즘 게임의 기본 추세라면 ,

사용하지 않을 이유가 없음 . (G-Buf-

fer 재사용 가능 )

실제 개발하는 MMORPG 에

적용해서

개발했던 결과 , 전체적으로

그래픽 퀄리티가 확실히 상승하였음그래픽이 짱 좋아졌음~~!!

오빠 짱~! 멋있당 ~~~!

우리팀 TD

물론 , MSAA, Transparency 이 제대로 지원되지 않는 문제를 해결해야 하는 부분이 남아 있음 . ( 상용 엔진의 지원에서는 어느 정도 해결됨 )

아놔~~님아 .. 지금 이게 뭐임 ?반투명 안되잖아 ~~!님아 나하고 장난침 ?

우리팀 TD

동적 라이팅이 많고 , 그래픽 연출이

중요한 MMORPG나 FPS 등에

적용하면 상당히 좋은 효과를 얻을

수 있을거라 기대됨 !

참고 자료• Deferred Shading – 오종빈 (Shader Study) 발표 자료

• Deferred Shading – Codevania(김태우) 스프링 노트

• Deferred Shading Tutorial - Codevania

• Deferred Shading –NVIDIA ( 문서 )

• HDR Deferred Shading – NVIDIA (예제 코드)

• 니시카와 켄지의 3D게임 팬을 위한 「KILLZONE 2」그래픽스 강좌

• Light Indexed Deferred Lighting – Codevania

Q & A