블로그 이미지
자신의 단점을 메꾸는 것을 단(鍛)이라 하고 자신의 강점을 갈고 닦는 것을 련(鍊)이라 하여, 두가지를 합친 것을 단련이라고 부른다. 붕대마음

카테고리

전체목록 (666)
참고사이트 (8)
Goal (4)
Travel (10)
My Life (104)
Game (35)
Game Review (7)
Game Plan (0)
Books (5)
English (1)
Optimizing (12)
Study (218)
유용한 것들_etc (44)
유용한 것들_func (20)
Unity (48)
Unreal (87)
작업장 (54)
RenderMonkey (6)
정리요망 (1)
따라잡기 시리즈 (0)
링크용 (0)
Total343,311
Today3
Yesterday91

'Unity'에 해당되는 글 17건

  1. 2017.03.04 animation 최적화
  2. 2017.02.26 sending message header failed
  3. 2017.01.18 Unity 5.5 AssetBundle.LoadAssetAsync
  4. 2017.01.13 유니티에서의 메모리 관리.
  5. 2016.09.08 shader tip with Intel
  6. 2016.09.03 unity bug with tegra k1
  7. 2016.04.12 Unity Tags

케릭터에 붙어있는 애니메이션이 많을수록 케릭터 로딩이 느려진다.

한 스테이지에 케릭터가 10개가 나온다고 가정하고, 각 케릭터가 가져야 할

애니메이션 갯수가 영웅일 경우 20개, 적군일 경우 10라고 할 경우,

애니메이션 용량이 3메가라 가정해서 영웅 5명의 애니메이션은

 5*20*3 = 300메가....헐...

적군 5명은 5*10*3 = 150메가....헐....

이건 좀 말이안되는듯..내가제대로 계산한거 맞음??? 후덜덜.....


그래서 애니메이션 최적화를 시도해보자!

이미 이 주제에 대해서는 많은 분들이 좋은 팁을 알려주셨으니 참고하면 되고

내가 할 이야기는 scale에 관한 내용이다.


최적화를 할 타겟 파일을 보자.

5메가가 넘는 엄청난 녀석이다.

엄청나게 많은 애니메이션을 하겠지 뭐....

유니티에서 애니메이션 창을 열어 왜 이렇게 용량이 큰지 살펴보다보니 우선 당연히 

플레이 타임이 긴 애니메이션임....그래그래..그건 이해가 되는데 세번째 사진을 보면

position이나 rotation은 이해가 가지만 scale?? 이건 값도 없는데 왜 들어가 있지..

그냥 1인걸 보증하기 위해서인가..??

유니티의 퍼포먼스 및 최적화 꿀팁에 보면 이렇게 나와있기도 하고....

그래서 과감히 scale을 삭제삭제..

용량이 5.21에서 1.49로 거의 70%가 줄었다.....

머지...? 너무 많이 준거아냐...난.그냥...2~30%만 줄어도 감사요~! 할려고 했는데.....

물론 scale 말고도 필요없어보이는걸 좀 제거하긴 했지만....


애니메이션 테스트를 진행해 보니 역시나 잘 나온다.

그래서 과감히 결정.

빠른 로딩을 위해 모든 애니메이션에서는 scale을 제거하고

특정 타임때 필요한 scale animation은 추가 script나 shader에서 지원.


AnimationCurve에 propertyName으로 체크하긴 했는데 모르는 이름도 있어서

적당히 대충했다. Nub이나 Editor 이런건 뭐지.. 필요없을 거 같은데...


2017.03.12 추가 테스트

아래 AnimationUtility.SetEditorCurve makes clip file size bigger?  에서 아래와 같은 글을 읽었다.

이 아저씨 말로는 짜투리정보는 에디터에서만 그런거고 실제로  빌드하면 알아서 다 제거해 준다고 한다.

그리고 inspector에 실제 애니메이션 메모리 크기가 보인다고 한다.

그런데 난 왜 안보이지? 보이지 않아서 추가 테스트를 해봤다.


최적화 전 : 68개의 파일, 총 66메가.

최적화 후(scale, editor 관련 제거) : 68개의 파일, 총 51.9메가

이렇게만 보면 꽤나 많이 절약된 걸로 보인다. 

이제 이걸로 번들을 뽑아보았다.

최적화 전 번들파일은 4.7메가, 최적화 후 번들파일은 4.4메가였다.

물론 이 번들파일에는 애니메이션 이외에도 여러가지가 들기는 하지만

0.3메가가 줄어들었다는건 어느정도 의미가 있다고 생각한다.


그리고 인스펙터는 아니지만 프로파일러에서는 애니메이션 클립의 메모리가 보인다.

최적화 전 : 670kb


최적화 후 : 329.4kb


프로파일러상에서도 용량이 줄었다.

그렇다면 내가 수행한 애니메이션 최적화가 효과가 있다는거 아닐까?


추가 용량을 줄일려면 유니티 메뉴얼 "FBX 임포터 관련 문서"를 참조해서 Rotation Error와 Position Errror

줄이는 것도 한 방법이다. 


애니메이션을 임포트할때, 모델을 IK노드는 FK안으로 구워지므로 유니티에서는

IK노드가 전혀 필요가 없다.

하지만 모델에 이 IK노드가 남아있다면 이 노드들이 애니메이션에 영향을 안 주더라도 

CPU오버헤드를 유발시킨다.

유니티나 모델링 툴에서 IK노드를 지울 수 있다.

이상적으로는, IK와 FK 하이라키를 모델링 하는 동안에는 따라 나누어 관리해야 나중에 지우기 쉽다.


버전을 올리고 나서 기존에 AnimationClipCurveData API 쓰던걸 버전문제 때문에 EditorCurveBinding으로 

바꾸는 작업을 했는데 용량이 더 커진다.

GetCurveBindings와 GetObjectReferenceCurveBindings 둘다 사용해 봤는데 마찬가지.

뭔가 내가 제대로 못하고 있는건지...

결과물이 마음에 들지 않기때문에 폐기 관련 경고는 그냥 무시하기로....


Reference Link

- 영웅의 군단의 테크니컬 아트

- 애니메이션 커브의 사용

- 애니메이션 퍼포먼스 및 최적화

AnimationUtility.SetEditorCurve makes clip file size bigger?

- 유니티 메뉴얼 FBX 임포터

- unity doc, modeling characters for optimal performance

- Unity3D Performance Optimization Codes

- unity doc, mesh importing

-

'Optimizing > Unity' 카테고리의 다른 글

Dynamic Batching이 효율적일까?  (0) 2017.03.31
유니티 텍스처  (0) 2017.03.22
animation 최적화  (0) 2017.03.04
유니티에서의 메모리 관리.  (0) 2017.01.13
Unity sound setting  (0) 2017.01.10
gc.markdependencies  (0) 2016.09.07
Posted by 붕대마음

댓글을 달아 주세요

이전에 asyncload 관련 버그 때문에 멘탈이 쪼개지고 나서 열시미 고쳤는데(고친 방법은 이 링크)

이번에 5.55.1p3 버전에서 고쳐졌다고 해서 잽싸게 설치해 봤는데 잘 된다. 흐흐흐.

그동안 맘고생한게 다 헛수고였던게야..

그런데 갑자기 이런 경고(sending message header failed)가 무한으로 뜬다.

play상태든 아니든 계~~속 뜬다.

나의 경우 이 때는 프로파일러를 띄워서 active를 edtior로 바꿔주면 더 이상 뜨지 않았다.

기존은 android target으로 되어 있엇다.

무튼 기존 async 버그가 고쳐져서 기분좋음.ㅎㅎㅎ


Reference Link

- Unity 5.5 Assetbundle.LoadAssetAsync 문제

-

Posted by 붕대마음
TAG Unity

댓글을 달아 주세요

5.5로 업그레이드 후 에셋번들 로드시 높은 확률로 굳어버린다.

뻗는것도 아니고, 에러도 아니고 말 그대로 굳어버린다.

포럼에도 이런 현상을 겪었다는 글이 올라오고 있는데 일주일 정도 삽질을 거듭한 결과

어느정도? 수정이 되었다.

100프로 확신할 수 없는 건 이렇게 고치는게 맞는지 보증이 없기 때문이지만

현재 pc 에셋번들 버전과 모바일 버전에서 굳는현상이 나오지 않았다.

현재 수정한 내용을 간추려 말하자면 기존에는 로드 요청이 들어오면 유니티가 알아서 처리하게

냅두었는데 지금은 번들 로드인 www와 내부 파일 로드인 LoadAssetAsync를 내부 락을 걸어

www가 로드중일 때는 LoadAssetAsync을 피했고, 내부 파일 로드 내에서도

LoadAssetAsync를 순차적으로 처리 해 주었다.

빨리 빌드를 전달해야 하는 상황 + 몸 컨디션 최악의 상황이라서 코드를 좀 더럽게 짜긴 했지만

우선은 돌아가니까 패스... 컨디션이 좀 좋아지면 다시 리펙토링하면서 정리를 해야겠다.



유닛히에서 수정되었다고 해서 5.5.1p3 로 올린 후 테스트 해 본 결과 잘 되서 위에서 락 걸었던 코드는 제거..

이제 이런버그는 안나왔으면 좋겠다.

Reference Link

http://answers.unity3d.com/questions/1285734/assetbundleloadassetasync-case-freezing-in-unity55.html

Posted by 붕대마음

댓글을 달아 주세요

유니티에서 사용하는 메모리는 3가지 종류의 영역이 있다.


code영역

유니티 엔진과 라이브러리, 게임코드가 컴파일 되어서 디바이스의 메모리 코드 영역에 로딩되게 된다.

크게 최적화 할 필요가 없음. 코드 파일 용량이라고  해 봤자 어차피 얼마 안된다.


Managed Heap 영역

Mono(.Net Framework의 오픈소스버전)가 관리하는 영역.

instantiated object, variable, new 키워드로 할당한 메모리, 들이 거주하게 되는 영역.

Managed인 이유는 Mono Framework이 이 영역의 메모리를 할당하거나 해제하면서 관리하기 때문.


유니티 레퍼 참고 

- 자동 메모리 관리

오브젝트나 string 또는 배열이 생성될 때, 이를 저장하기 위해 요구되는 메모리는

Heap이라고 불리는 중앙 풀에서 할당되어진다.

아이템을 더 이상 사용하지 않을 떄, 한번 차지했던 메모리를 되찾아서

다른곳에 사용될 수 있다.

과거에는 프로그래머들이 힙 메모리의 블럭을 할당하고 해제하기 위해

명시적으로 함수를 호출하였다.

요즘은, 유니티의 Mono엔진과 같은 런타임 시스템이 자동으로 메모리를 관리해 준다.

자동 메모리 관리는 명시적으로 할당/해제를 하는 코딩적 노력이 적고

메모리 누수(할당하고 해제하지 않은 경우)가 발생할 가능성이 많이 감소시켜준다.


GC에게 먹이를 주지 않는 몇가지 방법을 보자.

1. string의 조합대신 mono 라이브러리가 제공하는 system.text.stringbuilder를 사용하자.

2. string의 업데이트를 최대한 줄이자.

   void Update() { string scoreText = "score : " + score.Tostring();}

   위 코드는 매번 string을 업데이트 시킨다.

   void Update() { if(score != oldscore) string scoreText = "score : " + score.Tostring();}

   위 코드는 실제 값이 다를경우만 업데이트 시킨다.

3. 함수가 배열값을 반환할 때 문제가 발생할 수 있다.

float[] RandomList(int val)

{

   var result = new float[val];

   for(int i=0; i<val; i++)

        result[i] = Random.value;

   

   return result;

}   

위의 함수는 새 배열을 만들어 값을 채울 때 무척 우아하고 편하다.

하지만 반복적으로 호출되면 매번 새로운 메모리가 할당된다.

배열이 무척 커질 수 있기 때문에 사용가능한 힙 공간이 빠르게 소모되어

GC 빈도가 높아 질 수 있다.

이를 피하는 방법은 배열의 레퍼런스를 사용하는 것이다.

배열을 함수의 인자로 전달하면 함수 내에서 배열을 수정할 수 있고

함수의 리턴 후에 결과값도 남는다. 아래에 알맞게 수정한 결과물을 참고하자.

void RandomList(float[] valArray)

{

  for(int i=0; i<valArray.Length; i++)

     valArray[i] = Random.value;

}

위 함수는 기존 함수보다 우아하지는 않지만(초기 할당이 호출하는 쪽에서 필요함)

함수 호출이 될 때마다 새로운 가비지가 생성되는 것은 없다.


4. 오브젝트 풀링 시스템을 사용하자.

5. 값만 저장하는 데이터 타입은 class보다는 구조체를 사용하자. 

   struct는 stack에 생성되기 때문에 GC에 들어가지 않는다.



GC의 호출로 인해 프레임이 떨어지는 것을 최소화 히기 위한 방법

- Object Recycling 기법 : 다시 써야 한다면 Destroy보다는 Active을 on off 시키자.

- GC를 막거나 컨트롤 할 수는 없지만 미리 GC를 호출할 수는 있다.

  좋은 타이밍에 GC를 호출해 주면 플레이 타임에 프레임 하락을 유발하는 일이 적어진다.

- 작은 Heap과 빠르고 빈번한 GC를 할 건지 큰 Heap과 느리지만 빈번하지 않은 GC를 할건지 

  자신의 프로젝트에 맞게 선택.



Native Heap 영역

유니티 엔진이 OS에서 메모리를 할당받아 texture, sound, effect, level data등을 저장하는 영역.

유니티 엔진이 Mono가 메모리를 관리하는 것 처럼 현재 scene에서 필요 없게 된

리소스가 차지하는 메모리 영역을 해제하는 작업을 수행하기도 하지만 manual하게 할당된

리소스에 대해서는 유니티가 관리를 하지 못하므로 부주의 하다면 심각한 메모리 부족사태에 이를 수 있다.


일반적으로 Scene을 로드할 때 Scene에 포함된 Asset들은 같이 메모리 상에 로드되고

Scene이 끝나서 다음 Scene으로 넘어갈 경우 이전 Scene의 리소스중 다음 Scene에 사용되지 않는 것은

메모리상에서 자동 해제 되는데 DontDestroyOnLoad일 경우는 지워지지 않는다.

그러므로 DontDestroyOnLoad로 지정한 GameObject와 그 하위 오브젝트가 무거운 asset을 

가지고 있거랑 링크하고 있지 않도록 해야 한다.


또 다른 경우는 script 내에서 scene object를 참조하고 있는 경우이다.

대부분 script의 참조는 scene이 전환됨에 따라 같이 파괴되지만

Scene이 전환되더라도 남아있는 GameObject가 있고 해당 GameObject가 Script를 가지고 있는데

이 Script 내에서 다른 Asset(ex: sound, texture...)에 대한 참조를 유지하고 있는 경우

리소스가 메모리상에 남아 메모리 자원부족에 이르게 할 위험이 있다.

singleton인스턴스가 자원에 대한 참조를 가지고 있는 경우도 마찬가지 문제가 발생할 수 있다.



GC.Collect() 

사용하지 않는(또는 레퍼런스가 없는)메모리 구역을 해제한다.


Resources.UnloadUnusedAssets()

이 함수는 Resource.Load()를 통하여 할당된 에셋을 해제한다.



Reference

- 유니티의 메모리 관리 

- Managing Memory in Unity3D

-

'Optimizing > Unity' 카테고리의 다른 글

Dynamic Batching이 효율적일까?  (0) 2017.03.31
유니티 텍스처  (0) 2017.03.22
animation 최적화  (0) 2017.03.04
유니티에서의 메모리 관리.  (0) 2017.01.13
Unity sound setting  (0) 2017.01.10
gc.markdependencies  (0) 2016.09.07
Posted by 붕대마음

댓글을 달아 주세요

이전에 포스팅한 테그라에서의 유니티 버그는 대략 마무리 되었고

이번에는 듀얼 os를 지원하는 태블릿들 테스트중..

그런데 특정 셰이더 쓰는 애들은 mask가 안된다.

머징 이생퀴들은... 에러도 딱히 안났는디...크흠크흠..

구글신이 말하길.. Intel은 Half Float 지원안한단다...


아래 내용을 조금 해석해 보자면...

half float 이나 float 자료형은 몇가지 응용프로그램 영역에서 인기있는 유형이다.

half float 타입을 저장유형으로 간주하기 때문에 종종 데이터를 half type으로 저장하더라도,

계산은 이러한 유형의 값에서 수행되지 않는다.

일반적으로 어느 계산을 하기전에 32비트 float 타입으로 값을 변환시킨다.


half float 타입의 지원은 단지 32비트 float으로, 또는 32비트 float에서의 변환으로 제한된다.

half float 타입을 사용해서 얻을 수 있는 이점은 아래와 같다.

. 저장공간 절약

. bandwidth과 chche 메모리의 소비 감소

. 많은 프로그램에서의 충분한 정확도와 정밀도 


예를 들어 아래의 코드를 보자.

float4 frag(v2f IN) : COLOR 

{

half4 mask = tex2D (_MaskTex, IN.uv_MainTex);

clip(mask.r-0.5);

half4 c = tex2D (_MainTex, IN.uv_MainTex);

return c;

}

원래는 아무 문제가 없는 코드다.

pvrtc, mali, adreno, tegra 와 pc에서 잘 실행된다.


하지만 인텔칩셋에선 clip이 제대로 결과값이 제대로 나오지 않는다.

그렇다고 float4 하기에는 다른 칩셋들에게 미안하고...

결론은 아래와 같이 상위로 빼서 처리를 했다.

fixed4 c;

float4 frag(v2f IN) : COLOR 

{

fixed4 mask = tex2D (_MaskTex, IN.uv_MainTex);

clip(mask.r-0.5);

fixed4 tex = tex2D (_MainTex, IN.uv_MainTex);

c.rgb = tex.rgb;

return c;

}



Reference Link

- Overview: Intrinsics to Convert Half Float Types

-


'Unity > Unity Study' 카테고리의 다른 글

Optimizing Shader Load Time  (0) 2017.01.16
특정 android mobile chipset에서 half 문제  (0) 2016.09.21
shader tip with Intel  (0) 2016.09.08
unity bug with tegra k1  (0) 2016.09.03
unity material parameter 변경  (0) 2016.05.12
ngui uitexture shader update  (0) 2016.05.03
Posted by 붕대마음

댓글을 달아 주세요

미루고 미루었던 비주류 제품들 빌드 테스트를 하기 시작함.

1. tegra

2. 듀얼 os 테블릿 pc 제품들. (뭔가 칩셋이 제각각임)


기본적으로 이전에 언렬에서 겪었던 말리칩의 float 정밀도 문제이후

웬만하면 모든 칩셋에서 테스트를 해볼려고 노력중이다.


그래서 이번에 마침 테스트패드로 가지고 있던 샤오미 미패드1과 2로 테스트.

미패드1은 tegra k1, 미패드2는 Intel HD Graphics이다.


tegra k1으로 테스트를 하는데 전투를 시작하면 백프로 뻗음.

뭘까? 이전 빌드때도 뻗어서 그때는 유니티 내장셰이더를 쓰지 않고

자체 셰이더를 썻더니되서 혹시 이번에도 그런 문젠가 해서

셰이더를 문제없이 출력되는 셰이더를 넣고 해봄. 뻗음.....


왜 뻗는지 몰라서 패치받는 절차도 귀찮고 해서 로그인에 

뻗는 원인이 된 game object를 하나 배치해서 봤더니 뻗지않음.


머지??? 왜 로비에서는 괜찮은데 전투에서만 괜찮을까....

이런저런 가설로 삽질을 하다가 구글이 이렇게 가르쳐줌.

NVIDIA Tegra K1에서 두개이상의 Sprite Render를 사용하면 뻗는다......

ㅡㅡ;....로그인 때는 테스트한다고 하나만 붙여놔서 안뻗은 거였군...

그래서 해당 오브젝트 제작 담당자한테 말해서 Sprite Render를 

그냥 mesh render로 하고 quad를 사용하게 바꿔주도록 요청하였다.

그리고 나서는 잘 돌아간다.. 굿굿.


그렇구만.. 참고로 나의 유니티 버전은 5.4.Op2이다.


다음주 부터는 adreno, mali, tegra 이외의 android 기기들을 테스트 해봐야겠다.


Referenfe Link

[ANDROID] XIAOMI DEVICES CRASH WHEN USING MORE THAN ONE SPRITE ON UNITY 5

'Unity > Unity Study' 카테고리의 다른 글

특정 android mobile chipset에서 half 문제  (0) 2016.09.21
shader tip with Intel  (0) 2016.09.08
unity bug with tegra k1  (0) 2016.09.03
unity material parameter 변경  (0) 2016.05.12
ngui uitexture shader update  (0) 2016.05.03
SV_POSITION과 POSITION  (0) 2016.04.15
Posted by 붕대마음

댓글을 달아 주세요

Unity Tags

Unity/Unity Graphics / 2016.04.12 11:57

RenderType 관련 태그
ex) Tags { "RenderType"="Opaque"}
link : http://docs.unity3d.com/Documentation/Components/SL-ShaderReplacement.html

LightMode 관련 태그
ex) Tags { "LightMode" = "Vertex"} 
link : http://docs.unity3d.com/Documentation/Components/SL-PassTags.html 


유니티에 설정되어져 있는 built in tags에 커스텀 tag를 추가하여 Material.GetTag 함수로 

사용할 수 있다.


SubShader 

Tags { ... MyTag"="tagType1" } 

.....

위와 같은 식으로 셰이더 파일에서 설정 해 주고 아래와 같이 사용하면 된다.

Material m = myMaterial;

string shaderTag = m.GetTag("MyTag", false, "Nothing");

if(shaderTag == "Nothing")

    log("not found MyTag");

else

    log("found MyTag, Value is " +shaderTag);


참고

- ShaderLab: SubShader Tags

- Material.GetTag

-

'Unity > Unity Graphics' 카테고리의 다른 글

Depth and Normal Texture (Part 1)  (1) 2016.04.29
#pragma multi_compile  (0) 2016.04.23
Performance Tips when Writing Shaders  (0) 2016.04.15
TRANSFORM_TEX  (0) 2016.04.15
Unity Tags  (0) 2016.04.12
Built in shader variables  (0) 2015.10.30
Posted by 붕대마음

댓글을 달아 주세요

최근에 달린 댓글

최근에 받은 트랙백

글 보관함