Transcript [0326_박민근] Deferred Shading
Deferred Shading (지연 세이딩)
박민근(알콜코더) 네이버 초중급 게임 개발자 스터디 [데브루키] 2011.03.26
Real-Time Rendering
최근 게임들은 수 많은 라이트와 수많은 오브젝트 들이 등장한다.
-> 라이팅 계산양의 증가
리얼 타임 라이팅을 위한 세가지 주요 기법
• • •
포워드 렌더링 (Forward Rendering) Single-pass, Multi-light Multi-pass, Multi-light
• •
디퍼드 렌더링 Deferred Shading
Single-pass, multi-light
for each object do for each light do framebuffer= light_model(object,light);
Single-pass, multi-light
• • •
화면에 렌더딩 되지 않을 면도 셰이딩 연상을 해야만 한다.
•
멀티 라이트 상황에서 관리가 어렵다 싱글 템플릿 셰이더에서 수천 가지의 조합의 코드 가 생성될 수 있다.
그림자와의 통합이 어렵다
Single-pass, multi-light
1억 개의 오브젝트, 50개의 라이트 [라이팅만을 위한 계산양]
Multi-pass, multi-light
for each light do for 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 Shading
for each object do G-buffer = lighting properties of object; for each light do framebuffer+= light_model(G-buffer,light);
Deferred Shading
• • • •
굉장히 배치가 간단해지고, 엔진에서 관리가 쉽다 일반적인 그림자 테크닉들과 통합이 쉽다
•
라이팅을 위한 계산이 가진다.
“완전한” O(1) 복잡도 를 오브젝트의 개수와 상관없다 수많은 작은 동적 라이팅 사용이 가능하다
Deferred Shading
1억 개의 오브젝트, 50개의 라이트 [라이팅만을 위한 계산양] 라이트 개수 * 라이트에 영향받는 픽셀 개수
Deferred Shading
• • • • •
일종의 포스트 프로세싱처럼 수행된다 2D 렌더 타겟간의 계산이다.
3D 계산을 -> 2D 계산으로 변환 시킨다.
오브젝트는 라이팅 계산이 전혀 없이 더링 한다.
속성만 을 렌 화면에 실제로 렌더링 되는 수행한다.
픽셀 만 라이팅 계산을
Deferred Shading
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
지오메트리 패스
• • •
3D 공간의 지오메트리(오브젝트) 데이터의 속성값들을G Buffer에 렌더링 하는 단계 라이팅 처리는 하지 않는다!
• • •
MRT(Multi Render Target)을 사용해서, 한 패스에 4개의 렌더 타겟에 정보를 렌더링 한다.
Depth Normal Diffuse / Specular
지오메트리 패스
라이팅 패스
라이팅을 지오메트리 형태로 렌더링된다.
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-buff.P, L)
라이팅 패스
최종적으로 원본의 Diffuse 값과 누적 버퍼에 누적된 픽셀 값들을 곱하여 결과를 출력한다.
framebuffer = diffuse * G-buff.diffuse + specular
Per-Pixel Lighting
float4 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 Lighting
float4 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 Occlusion) Motion Blur Bloom HDR
• • • • •
Light Indexed Deferred Lighting
light volume들이 scene과 교차하는 지점에 light index 값을 저장하여 렌더링하는 기법 반투명, MSAA 문제 해결됨 포워드 렌더링과 디퍼드 렌더링의 장단점을 보완 지오메트리를 2 pass 렌더링해야하고, 그림자 제공이 어려움 아직 연구의 여지가 있는 기법
수많은 동적 라이팅을 화면상의 오브젝 트의 개수와 관계없이 상수시간에 처리 가 가능함 이론상 무한개의 동적 라이팅 사용 가 능 어두운 실내나, 어두운 배경에 도억 라 이팅이 많은 경우 최적의 해결 방법 (ex. 데드 스페이스2)
현재의 그래픽 카드에서는 당연히 지원 됨 별다른 노력 없이, 유명 상용 엔진에서 는 기본적으로 지원됨 직접 구현 해도, 개념이 어렵지 않고, 관리가 쉬움 셀프 셰도우등 그림자 기법이 용이함
어차피 다른 포스트 프로세싱(Bloom, HDR등)을 사용하는 게 요즘 게임의 기 본 추세라면, 사용하지 않을 이유가 없 음. (G-Buffer 재사용 가능)
실제 개발된 MMORPG에 적용해서 개 발했던 결과, 전체적으로 그래픽 퀄리 티가 확실히 상승하였음
물론, MSAA, Transparency 이 제대 로 지원되지 않는 문제를 해결해야 하 는 부분이 남아 있음. (상용 엔진의 지 원에서는 어느 정도 해결됨)
간단한 캐쥬얼 게임이나 모바일 게임이 외에 그래픽이 중요한 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