52
모바일 3D 엔진 개발기 - 모바일 하드웨어의 이해와 최적화 이창희([email protected]) ㈜ 소프트네트

[Kgc2013] 모바일 엔진 개발기

Embed Size (px)

DESCRIPTION

kgc 발표자료

Citation preview

Page 1: [Kgc2013] 모바일 엔진 개발기

모바일 3D 엔진 개발기 - 모바일 하드웨어의 이해와 최적화

이창희([email protected])

㈜ 소프트네트

Page 2: [Kgc2013] 모바일 엔진 개발기

이창희 (@cagetu)

: Programmer

- 소프트네트 - CCR

- Hi-Win

- Netmarble(現, CJ E&M)

- DreamSEED

- SAMSONCORE

Page 3: [Kgc2013] 모바일 엔진 개발기

오늘의 주제 • 모바일 게임엔진 개발 경험 공유

• 모바일 하드웨어의 이해

• 모바일 최적화 방앆

Page 4: [Kgc2013] 모바일 엔진 개발기

풍문으로 들었소~

[KGC12 : 멀티플랫폼 Full 3D MMORPG 만들기]

Page 5: [Kgc2013] 모바일 엔진 개발기

풍문으로 들었소~

[KGC12 : 멀티플랫폼 Full 3D MMORPG 만들기]

Page 6: [Kgc2013] 모바일 엔진 개발기

게임 엔진

Page 7: [Kgc2013] 모바일 엔진 개발기

게임 엔진

Page 8: [Kgc2013] 모바일 엔진 개발기

모바일 기기의 이해 게임 엔진 최적화로 가는 첫 걸음!

Page 9: [Kgc2013] 모바일 엔진 개발기

모바일 하드웨어

모바일 하드웨어의 이해

OpenGL ES에 대한 이해

Page 10: [Kgc2013] 모바일 엔진 개발기

GPU 종류 • ImgTech PowerVR SGX

– iPhone / iPad, Galaxy S1

• ARM Mali – Galaxy S3

• Qualcomm Adreno – Galaxy S4, Optimus G / G2, Vega Iron

• NVIDIA Tegra – Nexus 7

Page 11: [Kgc2013] 모바일 엔진 개발기

GPU 아키텍쳐 • ImgTech PowerVR SGX

– Tile Based Deferred Rendering

• ARM Mali – Tiled (small tiles)

• Qualcomm Adreno – Tiled (large tiles)

• NVIDIA Tegra – 젂통적인 렌더링 방식

Page 12: [Kgc2013] 모바일 엔진 개발기

Tile Based Rendering • 화면을 픽셀 단위 타일로 나눈다.

– 16 x 16 (small tiles) – 256k (large tiles)

• 타일 메모리(Tile Memory)는 GPU에 있다. • 하나의 타일에 대해 모든 drawcall을 처리한다.

– 모든 타일에 대해서 반복

• 각 타일은 처리가 완료되면, RAM에 기록한다. (Framebuffer)

Page 13: [Kgc2013] 모바일 엔진 개발기

Tile Based Rendering • 화면을 픽셀 단위 타일로 나눈다.

– 16 x 16 (small tiles) – 256k (large tiles)

• 타일 메모리(Tile Memory)는 GPU에 있다. • 하나의 타일에 대해 모든 drawcall을 처리한다.

– 모든 타일에 대해서 반복

• 각 타일은 처리가 완료되면, RAM에 기록한다. (Framebuffer)

Page 14: [Kgc2013] 모바일 엔진 개발기

Tile Based Deferred Rendering

타일에 모든 렌더링 한 후, 보이는 픽셀만 셰이딩 한다.

Page 15: [Kgc2013] 모바일 엔진 개발기

Hidden Surface Removal • 불투명 메쉬에 대해서만 적용 • 픽셀 중복그리기(overdraw) 제거 • 뒤에 있는 모든 픽셀 제거 각 픽셀에 대해서 한번만 셰이딩 가능!!

Tiled Deferred

– “공짜” Tiled & 젂통적

– Early-Z (Z-Cull)로 수동으로 픽셀 제거 유도!

Page 16: [Kgc2013] 모바일 엔진 개발기

Parameter Buffer

• Parameter Buffer는 Vertex 처리 결과를 Pixel 처리를 하기 위해 저장된 버퍼.

• Vertex Shader 와 Pixel Shader 사이

한 장면에 너무 많은 데이터를 피하라 – Parameter buffer overflow

Page 17: [Kgc2013] 모바일 엔진 개발기

Parameter Buffer

• Parameter Buffer는 Vertex 처리 결과를 Pixel 처리를 하기 위해 저장된 버퍼.

• Vertex Shader 와 Pixel Shader 사이

Parameter buffer overflow

: 한 장면에 너무 많은 데이터를 피하라

Page 18: [Kgc2013] 모바일 엔진 개발기

Alpha Test • Discard

– OpenGL ES 2.0에서는 Alpha Test는 PixelShader 내부에서 discard

– 픽셀셰이더가 현재 픽셀들에 대해서 보이는지 판단될 때까지 대기 상태. • Parameter buffer로부터 Pixel로 가져오지 않는다.

• Alpha Test대싞 – Alpha Blend를 사용! – Fit 되도록 메쉬를 만든다.

if (Alpha < Threshold) discard;

Page 19: [Kgc2013] 모바일 엔진 개발기

Alpha Test • Discard

– OpenGL ES 2.0에서는 Alpha Test는 PixelShader 내부에서 discard

– 픽셀셰이더가 현재 픽셀들에 대해서 보이는지 판단될 때까지 대기 상태. • Parameter buffer로부터 Pixel로 가져오지 않는다.

• Alpha Test대싞 – Alpha Blend를 사용! – Fit 되도록 메쉬를 만든다.

if (Alpha < Threshold) discard;

Page 20: [Kgc2013] 모바일 엔진 개발기

Render Target • 각 렌더 타겟은 완젂히 새로운 하나의 장면. • 앞 뒤로 렌더타겟 전환을 피해라!

장면의 시작할 때, RAM에서 Tile Memory로 color/depth/stencil 데이터를 모두 복사한다 (buffer restore)

장면의 끝날 때, Tile Memory에서 RAM으로 color/depth/stencil 데이터를 모두 복사한다 (buffer resolve)

• Buffer resolve 피해라 Color/depth/stencil 모든 것을 Clear!!

• Buffer restore 피해라 GL_EXT_discard_framebuffer 를 사용

Page 21: [Kgc2013] 모바일 엔진 개발기

Sorting (불투명 오브젝트)

• Tiled Deferred 1. 재질 정렬 (for Batching)

2. “불투명 메쉬 -> Alpha-Test 메쉬” 정렬 : Alpha Test 픽셀이 차폐될 가능성을 높인다!

• 전통적 방식 1. “Front -> back” (Z-Cull 효율을 최대화하기 위해서)

2. 재질 정렬 (for Batching)

Page 22: [Kgc2013] 모바일 엔진 개발기

DrawCall

• Drawcall이 많아지면, cpu에 많은 부담!

– CPU 성능에 따른 최대 dpcall을 넘지 않도록 유지! (100 ~ 300 dpcall)

Batching (한번에 모아서 찍는다!) – 같은 재질 (Shader, RenderState, Texture)

Page 23: [Kgc2013] 모바일 엔진 개발기

DrawCall

• Drawcall이 많아지면, cpu에 많은 부담!

– CPU 성능에 따른 최대 dpcall을 넘지 않도록 유지! (100 ~ 300 dpcall)

Batching (한번에 모아서 찍는다!) – 같은 재질 (Shader, RenderState, Texture)

Page 24: [Kgc2013] 모바일 엔진 개발기

시기에 따른 성능 이슈

• iPad, iPhone4 – GPU Bound – GPU 성능에 비해 해상도가 너무 높다.

– 처리해야 할 픽셀이 너무 많다. (Low FillRate)

• iPad2 – CPU Bound – GPU는 매우 빠르다.

– 2 Core의 일부만 사용.

Page 25: [Kgc2013] 모바일 엔진 개발기

Fill Rate • 기기의 fill rate 능력에 따라 Alpha Blend과 Pixel

Shader가 성능에 많은 영향을 준다.

알파블랜딩이 사용되는 영역을 가능한 최소화 – 사용되는 영역에 최대한 근접하게 메쉬를 만들어준다.

Shader 연산 최소화 – 불필요한 연산을 최소화한다.

Page 26: [Kgc2013] 모바일 엔진 개발기

Fill Rate • 기기의 fill rate 능력에 따라 Alpha Blend과 Pixel

Shader가 성능에 많은 영향을 준다.

알파블랜딩이 사용되는 영역을 가능한 최소화 – 사용되는 영역에 최대한 근접하게 메쉬를 만들어준다.

Shader 연산 최소화 – 불필요한 연산을 최소화한다.

Page 27: [Kgc2013] 모바일 엔진 개발기

OpenGL ES

Page 28: [Kgc2013] 모바일 엔진 개발기

A Frame

Page 29: [Kgc2013] 모바일 엔진 개발기

Design a High-Performance OpenGL ES 파이프라인에 병렬화

를 잘 활용한다. 어플리케이션과 그래픽 하드웨어

사이의 데이터 흐름을 관리한다.

Summary • Static Resource 사용하라 • 렌더링 중갂에 Dynamic

Resource 수정을 피하라 • Rendering 결과 얻기를 피하라.

– glGetXXX [managing resources]

Page 30: [Kgc2013] 모바일 엔진 개발기

CASE STUDY 이슈 및 해결

Page 31: [Kgc2013] 모바일 엔진 개발기

• PC 게임을 대상으로 엔진 개발 – DirectX9 AA+급 PC 온라인 게임 용 엔진을 목표로 시작!

• 시장의 변화를 감지 – 갂단하게 OpenGL ES 를 지원하도록 해보자… 정도로 출발 – 엔진을 크게 수정하지 않고, OpenGL ES 만 추가적으로 적

용. (모바일이라도 특별하게 엔진을 줄이지 않음)

• 게임 출시 후, 그 노하우를 바탕으로 지속적으로 사용하여 차기작 개발 중

Page 32: [Kgc2013] 모바일 엔진 개발기

Design Concept – Prefab / Instancing / Batching

• http://www.youtube.com/watch?v=X0rAjfhFAzk

– Material System • Uber-Shader • “Shader Driven”

– Rendering Pipeline Composition • “유연한 렌더링 시스템“

– Data Driven • “Super Class”

– Only Real Time (No Pre-Built)

Page 33: [Kgc2013] 모바일 엔진 개발기

내부적으로 봤을때, 같은 기능으로 몰아넣는 것이 인터페이스를 깔끔하게 하거나, 관리하기가 편리함

Page 34: [Kgc2013] 모바일 엔진 개발기

사례 1) 폰트 텍스쳐 오류 • 입력이 들어오면 즉시 Dynamic Texture에 기록!!

– glTexSubImage2D

• 입력을 일괄적으로 기록하도록 변경으로 해결

Page 35: [Kgc2013] 모바일 엔진 개발기

사례 2) Buffer Object

• OpenGL ES에서의 “버텍스/인덱스 버퍼” – (일반적으로) 사용을 권장!

• iPhone4로 테스트 결과, 엄청나게 느려지는 문제 발생 – Cocos2D의 경우도 이런 문제가 있었음

• http://www.cocos2d-iphone.org/forum/topic/21829 • 증상> 대략 xcode 4 로 업데이트 했더니 느려졌다!!!

• 해결 – Static 버퍼 with VBO / IBO – Dynamic 버퍼 without VBO / IBO

Page 36: [Kgc2013] 모바일 엔진 개발기

사례 3) 알파 블랜딩 • 화면에서 알파 블랜딩이 차지하는 비중에 높을수록 느려짐

– Present에서 지연 됨 (FillRate) – CPU는 놀고, GPU는 죽고 있음 – 특히, iPhone4 / iPad1과 같이 FillRate가 낮은 기기에서는 최악!

• 해결책 – 알파를 사용하는 부분을 줄이는 것이 최선!

(즉, 알파를 사용하는 부분에 딱 맞게 메쉬를 만든다!) – GUI의 경우에도 디자인으로 고려! – 작은 렌더타겟에 그려서 늘여찍는 방법

• 파티클과 같이 동적인 알파객체들에게는 적합함

Page 37: [Kgc2013] 모바일 엔진 개발기

사례 4) 렌더타겟 • 렌더타겟 전환은 굉장히 비용이 많이 들어감! • 메모리 대역폭 ISSUE

– 화면 사이즈 렌더타겟을 가지고 오는 경우 병목

• 해결책 – 패스를 늘리지 않는다. – 렌더타겟 젂환을 최소화! – iPhone4의 경우, 렌더타겟 사용을 하지 않기를 권장! – 렌더타겟 사이즈가 작으면 작을수록 비용 젃감!

• 적당히 늘여찍기!

Page 38: [Kgc2013] 모바일 엔진 개발기

사례 4) 렌더타겟 • 렌더타겟 전환은 굉장히 비용이 많이 들어감! • 메모리 대역폭 ISSUE

– 화면 사이즈 렌더타겟을 가지고 오는 경우 병목

• 해결책 – 패스를 늘리지 않는다. – 렌더타겟 젂환을 최소화! – iPhone4의 경우, 렌더타겟 사용을 하지 않기를 권장! – 렌더타겟 사이즈가 작으면 작을수록 비용 젃감!

• 적당히 늘여찍기!

Page 39: [Kgc2013] 모바일 엔진 개발기

사례 5) 셰이더 • Pixel 연산을 최대한 줄이자! (for Fill Rate)

– 복잡한 연산은 버텍스 셰이더에서 처리하자! – 불필요한 연산은 제거 (a.k.a UberShader)

• Final Color = Texture Color * MatDiffuse; (1.0이라면 불필요)

– 연산 줄이기 • Pow(x, n) 을 테이블로 만들어서, max(A *x + B)로 사용

– 내부 함수은 너무 느리다!!! • Pow(x, 4) 와 x*x*x*x 는 같은 결과지만 속도는 천지차이!

– 정밀도를 줄인다. • Lowp : 기본적인 색상값 • Mediump : uv, 노말 등 • Hightp : 포지션 정보

Page 40: [Kgc2013] 모바일 엔진 개발기

사례 6) 라이팅 • 라이팅은 부담이 크다.

– 라이팅을 하지 않는다. – 느낌을 가져가면서, 연산을 줄인다!

• 연산 줄이기 – 인지적 관점: Diffuse보다는 Specular!

• 버텍스 라이팅으로 Diffuse 라이팅 • 픽셀 라이팅으로 스펙큘러

– 포인트 라이트 • 가볍고 아름다운 감쇠가 포인트!

Page 41: [Kgc2013] 모바일 엔진 개발기

사례 6) 라이팅 • 라이팅은 부담이 크다.

– 라이팅을 하지 않는다. – 느낌을 가져가면서, 연산을 줄인다!

• 연산 줄이기 – 인지적 관점: Diffuse보다는 Specular!

• 버텍스 라이팅으로 Diffuse 라이팅 • 픽셀 라이팅으로 스펙큘러

– 포인트 라이트 • 가볍고 아름다운 감쇠가 포인트!

float ApproxPow(float x) { // pow( max( A * N + B ), M ) // N = 18, M = 2 float r = saturate(6.645 * x + -5.645); return r * r; // M = 2 }

Page 42: [Kgc2013] 모바일 엔진 개발기

사례 6) 라이팅 • 라이팅은 부담이 크다.

– 라이팅을 하지 않는다. – 느낌을 가져가면서, 연산을 줄인다!

• 연산 줄이기 – 인지적 관점: Diffuse보다는 Specular!

• 버텍스 라이팅으로 Diffuse 라이팅 • 픽셀 라이팅으로 스펙큘러

– 포인트 라이트 • 가볍고 아름다운 감쇠가 포인트!

float CalcLightAttenuation(…) { float att = saturate(distance*radiusInv); float dt = distance / (1.0 - att*att); float denom = saturate(dt*radiusInv) + 1.0; float attenuation = 1.0 / (denom*denom); return saturate(attenuation*attenuation); }

Page 43: [Kgc2013] 모바일 엔진 개발기

사례 7) CPU가 논다!

• 대부분 CPU < GPU 병목

– CPU에 일을 더 시켜보자!

• 사례 – CPU 스키닝 (Skinning)

– 소량의 버텍스의 경우에는 스키닝 처리를 CPU에서 한다. (Batching도 가능)

Page 44: [Kgc2013] 모바일 엔진 개발기

결롞 마무리 쿠션!

Page 45: [Kgc2013] 모바일 엔진 개발기

요약해보면… Alpha Test보다는 Alpha Blend! Alpha Blend 사용 영역을 최소화!!!!!! RenderTarget 전환을 줄여야 함

• 사용하지 않는 RenderTarget 내용은 제거하라

Draw Call을 줄여라! Render State / Shader Switch 등을 줄여라 Static Buffer / Texture을 사용하라 프레임 중갂에 렌더링 상태를 얻어오지 말아라! 버텍스 사이즈를 줄여라!

Page 46: [Kgc2013] 모바일 엔진 개발기

요약해보면… Alpha Test보다는 Alpha Blend! Alpha Blend 사용 영역을 최소화!!!!!! RenderTarget 전환을 줄여야 함

• 사용하지 않는 RenderTarget 내용은 제거하라

Draw Call을 줄여라! Render State / Shader Switch 등을 줄여라 Static Buffer / Texture을 사용하라 프레임 중갂에 렌더링 상태를 얻어오지 말아라! 버텍스 사이즈를 줄여라!

Page 47: [Kgc2013] 모바일 엔진 개발기

• 모바일 기기 성능이 엄청 좋네요! – 기기 성능이 놀라울 정도로 좋아지고 있음!

– 개발자의 (최적화) 능력에 따라 결과가 차이

결롞

Page 48: [Kgc2013] 모바일 엔진 개발기

결롞 • 모바일이라고 기술적 이슈나 노력이 없는

것이 아닙니다!

– 일반적으로 PC에서 사용하던 기술들을 따라가고는 있지만, 환경에 따른 새로운 시각으로 고민해서 해결해야할 부분이 너무나 많습니다.

– 국내 기술적 교류가 너무나 부족합니다.

Page 49: [Kgc2013] 모바일 엔진 개발기

결롞 • 자체 엔진 괜찮습니다!

– 모바일 특성 상 “Game Specific”하게 만들기에는 자체엔진이 더 유리한 면이 있습니다.

• 도전 과제

– (경량화된) 포스트 프로세싱 (Bloom, DOF 등)

– 가벼우면서 좋은 퀄리티에 대한 고민!

Page 50: [Kgc2013] 모바일 엔진 개발기

Q & A

무엇이든 물어보세요?

Page 51: [Kgc2013] 모바일 엔진 개발기

게임으로 만나기를…

[Thanks to 김포프, 대마왕J]

Page 52: [Kgc2013] 모바일 엔진 개발기

참고자료 I. [KGC12] 멀티플렛폼 Full 3D MMORPG

II. [NDC10] 가성비 좋은 렌더링 테크닉 10선

III. [GDC12] Bring AAA graphics to mobile platforms

IV. [Siggraph11] Fast mobile shaders or rather Mobile! Fast!

V. [Siggraph12] Unity: iOS and Android - Cross-Platform Challenges and Solutions

VI. OpenGL ES Programming Guide for iOS