Upload
egohim
View
1.821
Download
2
Embed Size (px)
DESCRIPTION
Unity performanceoptimzation
Citation preview
Optimizing Graphics Performance
• 그래픽 퍼포먼스가 낮아지는 이유는 ?• 그려지는갯수 ? ( 화면상픽셀 * 드로우 횟수 )• 쉐이더 연산 ?• 버텍스 개수 ?• Draw calls?
Draw calls
• 많은 수의 오브젝트들은 CPU 의 부하를 주고 , 많은 수의 triangle 들은 GPU 의 부하를 가져다 준다 .
• 더해서 게임 코드를 위해서 또한 CPU 가 필요 .• 오늘날에 그래픽 처리 장치는 초당 500 개의 draw call 들 정도면
적당하다 .• 각각의 픽셀 조명은 메쉬를 한번더 그리게 되므로 , 절대 많은 수의 픽셀
조명을 사용하지 말것 !
Combining
• 씬내에 많은 수의 오브젝트들 – bad.• 근접해 있는 오브젝트들간에 combine – good.• “ 너무 많은 combine” – bad again.
Good Combining
• Combined objects are close to each other and use the same meterial
• Combine 의 쉬운 예시로써는 집에 있는 방들 배치 같은 경우• Often requires using texture sheets!• 오브젝트 크기와 포인트 /SPOT 라이트 크기가 같은 경우
Bad Combining
• 서로간에 멀리떨어진 오브젝트의 경우 절대 하지 말것 .• If light shines only on part of object, whole object needs to
be drawn.• 만약 조명이 오브젝트의 부분에만 드리워지면 전체 오브젝트는
그려져야만 함 .• If camera sees only a tiny corner of object,• 만약 카메라가 오브젝트 코너에 작은 영역만을 보는 경우• Whole object needs to be drawn.• 전체 오브젝트가 그려질 필요가 있는경우
Combining Demo• No combine
Combining Demo• Combine all
Combining Demo• Combineclose
Lights are for?
• 동적라이팅과 정적라이트맵을 합치는것 .• 라이트 맵은 월드상에 고정적 빛 요소를 모두 제거 해준다 .• 빠르고 비주얼도 좋다 .• 그럼 동적 빛은 언제 써야할까 ? 로켓 , 횟불 , 동적 그림자등 ..• Culling masks!
Raycasting
• 레이캐스팅은 느려지며 각 프레임 별로 레이 캐스트 남용하지 말것 .• 컬링 마스크를 사용함으로써 레이캐스팅을 미리 방지 할 수 있다 .• 3 프레임당 한번씩만 레이캐스팅을 하는것은 어떨까 ?• 컬링 마스크 = GUI : Layername 부여 .
Finding objects
• FindObjectsOfType, FindGameObjectWithTag, GameObjec-t.Find
• Avoid doing it too much. It’s convenient but those calls can quickly add up.
• Use static variable• 모든 활성화된 컴포넌트들을 static ArrayList 와 OnEnable/OnDis-
able 을 사용해서 저장 할 것 .
Only Update nearby objects
• Don’t run scripts at all, when far away.• Function Update() { if(far away) return; } does NOT coun-
t.Use enabled = false;• Use triggers for finding out when player is close by or use
coroutine that updates every seconds.• 오브젝트가 근접했는지를 알아내기 위하여 Trigger 를 사용 또는
매초마다 코 - 루틴 사용
Math
• Add, substract, multiply: a couple cycles.• Divide : 30-40 cycles.• Square root, sin, cos:60-100cycles
• Sqrt, Normalize• In inner loops avoid Sqrt and Normalize. They are faily ex-
pensive. (Normalize internally uses Sqrt)• Normalize = vec / sqrt(vec.x^2 + vec.y^2 + vec.z^2); use
sqrMagnitude instead.• If(distance > dif.magnitude) Bad!• If(distance*distance > dif.sqrMagnitude)
Total Boids Demo• Slow- 1.9FPS
Total Boids Demo• Slow - code
• // Slow• var neighbors = GameObject.FindGameObjectsWithTag("Vehicle");
• // Slow• var avgVelocity = Vector3.zero;• for (var i=0;i<neighbors.Length;i++)• {• avgVelocity += neighbors[i].GetComponent(VehicleTags).velocity;• }
• function ApplySeparation () {• // Slow• var neighbors = GameObject.FindGameObjectsWithTag("Vehicle");
• // Slow• var separate = Vector3.zero;• for(var i=0; i<neighbors.Length; i++) {• var posDiff = transform.position - neighbors[i].transform.position;• separate += posDiff.normalized * (1.0 / (posDiff.sqrMagnitude + 0.5));• }• separate.Normalize();• separate *= separateForce;
• steeringForce += separate;• }
Total Boids Demo1.Built-in array – 13.1FPS
Total Boids Demo• function ApplySeparation () {• /// OPTIMIZATION• /// Use builtin array containing the vehicles instead of FindWithTag• var separate = Vector3.zero;• for(var i=0; i<allVehicles.Length; i++) {• var posDiff = transform.position - allVehicles[i].transform.position;• separate += posDiff.normalized * (1.0 / (posDiff.sqrMagnitude + 0.5));• }• separate.Normalize();• separate *= separateForce;
• steeringForce += separate;• }
1.Built-in array – 13.1FPS
Total Boids Demo1.Built-in array - 13.1FPS2.CachePosition – 33.5FPS
Total Boids Demo• static function UpdateCachedPositions ()• {• if (cachedPosition == null)• cachedPosition = new Vector3[allVehicles.length];
• for (var i=0;i<cachedPosition.length;i++)• {• cachedPosition[i] = allVehicles[i].transform.position;• }• }
• function ApplySeparation () {• var separate = Vector3.zero;• /// Optimizations• /// * Cache position of our selves (no transform.position)• /// * Cache position of other in an array updated once per frame (no transform.position)• var position = transform.position;• for(var i=0; i<allVehicles.Length; i++) {• var posDiff = position - cachedPosition[i];• separate += posDiff.normalized * (1.0 / (posDiff.sqrMagnitude + 0.5));• }• …• }
1.Built-in array - 13.1FPS2.CachePosition – 33.5FPS
Total Boids Demo1.Built-in array – 13.1FPS2.CachePosition – 33.5FPS3.Magnitude optimazation – 46.5FPS
Total Boids Demo• function ApplySeparation () {
• var separate = Vector3.zero;
• /// OPTIMIZATION• /// * Don't use Sqrt in innner loops• var position = transform.position;• for(var i=0; i<cachedPosition.Length; i++) {• // Don't use Sqrt in innner loops• // Save 1 division, 1 sqr root• var posDiff = position - cachedPosition[i];• separate += posDiff / (posDiff.sqrMagnitude + 0.5);• }• …• }
1.Built-in array – 13.1FPS2.CachePosition – 33.5FPS3.Magnitude optimazation – 46.5FPS
Total Boids Demo1.Built-in array - 13.1FPS2.CachePosition – 33.5FPS3.Magnitude optimazation – 46.5FPS4.Precompute optimazation – 64.3FPS
Total Boids Demo• static function UpdateCachedPositions ()• {• if (cachedPosition == null)• cachedPosition = new Vector3[allVehicles.length];
• avgVelocity = Vector3.zero;• for (var i=0;i<cachedPosition.length;i++)• {• cachedPosition[i] = allVehicles[i].transform.position;• avgVelocity += allVehicles[i].velocity;• }• avgVelocity /= allVehicles.Length;• }
• function ApplyAlignment () {• /// Optimizations• /// Precompute average velocity once per frame, no need to go through array• var align = avgVelocity - velocity;• align.Normalize();• align *= alignmentForce;
• steeringForce += align;• }
1.Built-in array - 13.1FPS2.CachePosition – 33.5FPS3.Magnitude optimazation – 46.5FPS4.Precompute optimazation – 64.3FPS