2013年9月27日 星期五

[SAI] 如何使用正式版

  在成功購買Sai之後,Systemax會寄給你一份認證資訊,其中包含

  • Softoware License Number
  • Certificate Download Password
  • Password Character Type

  再來到Systemax的Download Software License Certificate File網頁,輸入你的Softoware License Number跟Certificate Download Password,下面則是要輸入自己的System ID,System ID每台電腦皆不相同,可從Sai執行指令獲得(Others>System ID),輸入完成後即可下載認證檔案,放置到Sai的目錄中即可。


2013年9月10日 星期二

[UVLayout] 基本教學

  今天用起多年未開過的UVLayout發現幾乎快忘光了,所以就在這記錄一下UVLayout要怎麼使用吧~免的下次再打開又忘光光了。因為UVLayout這款軟體極度不人性化、介面極度簡陋的特色,記不記得熱鍵是操作此軟體的最重要重點...下面附上官方的文件,以及一些重點操作的說明(UVLayout 2.06):


基本操作
  • 3D視角操作:
    • 旋轉(水平)
      • 以高度軸為基準 - LMB + 滑鼠水平移動
      • 以攝影機軸為基準 - Ctrl + LMB + 滑鼠水平移動
        (若發生基準軸錯誤問題,用Ctrl操作之後會恢復正常)
    • 透視切換 - O
    • Focus View - Home
  • 3D視窗:
    • Texture顯示
      • 切換Texture - T
      • 變換Texture尺寸 - +/-
    • 選取Shells
      • 選取 - Shift + LMB
      • 範圍框選 - Shift + Drag LMB
      • 清除所有選取 - Shift + LMB空白位置
  • UV操作:
    • Drop UV(3D編輯視窗) - D
    • 復原UV Drop(UV視窗) - Shift + D
    • UV切分 - C
    • UV黏合 - W
    • 將Shell對齊到要黏合的另一個邊上 - M
    • Shell的編輯
      • 放大 - Space + RMB
      • 旋轉 - Space + LMB
      • 移動 - Space + CMB 
    • UV Vertex編輯
      • 移動 - Ctrrl + RMB
    • 對稱
      • 尋找對稱 
        1. Menu>Symmerty Find
        2. 左鍵選UV Border
        3. 中鍵選對稱的UV Border
        4. Enter結束
      • 交換對稱 - Shift + S
      • 對齊對稱的Shell - S(在Shell上)
    • COPY UVs
      • 可用於對稱UV或相同Shell的堆疊
        1. Menu>Copy UVs 開啟Copy UVs的功能
        2. 第一下LMB選擇來源Shell上的一邊
        3. 第二下以後可依序選擇其他Shells上對應的邊
        4. 按下Space執行

參考文章

2013年9月6日 星期五

[Unity][Mecanim] 角色處理注意事項


以下為作業上的一些紀錄。

角色輸出與輸入


  • 3ds Max的單位設置為 1 Unit = 1 Centimeters
    • 如此在不改變Asset的Scale Factor狀況下(在Asset的Import Settings中,預設為0.01),Max中的一公尺會與Unity的一公尺相等,這是最符合物理的單位設定,可避免物理運算出現奇怪的現象。
  • 讓角色在DCC Tool中面向Front View(從Front View看到的是角色的正面),如此匯入Unity後,角色的正面會與GameObject的Forward方向一致。
  • 輸出骨架模型FBX檔案時,雖然不會勾選Animation項目,但是其子項目Skins必須要是被勾選著的,否則不會帶出Skin資料(3dsMax 9)。
  • 非Biped-based角色(只由Bone/Dummy...組成的Rig)在輸出動作檔案時,需保留一個Skinned mesh一同輸出,否則會發生輸出的FBX檔沒有Root Node的狀況。
  • 骨架請勿帶有negative scale,因為目前的mechanim並不支援negative scale的blending。
  • 當你的角色的root node不是skeleton而是dummy之類的物件時,在Unity的FBX Import Settings需將Animation設置為Store in Nodes,原因尚未探究(參考
  • 物件的命名不要跟輸出的FBX檔名相同(不是Child的物件),否則會出現flagsCount >= mask.m_Count錯誤訊息,而Rig的Root Node若取名與檔名相同則會出現Look rotation viewing vector is zero錯誤訊息(參考)。
  • Twist bone的父物件必須為該部位的主要骨頭
Mechanim系統
  • 在進行FBX Import Setting的設定時,在Animation的部份要注意Root Transform的設定,勾選的項目將不會對角色產生實際的位移旋轉效果(成為假動作的狀態)。
  • 當角色的動作本身有做位移時,如果動作與動作間的Blending設定吃掉了部份的時間區段,將會喪失那個時間區段內的位移距離,可能會導致位移效果有誤差的狀況。

相關文章

[Unity] 效能上需要注意的事項


在此整理一些有關效能上需要注意的問題,主要資訊來源是Unity的Manual,其中可能有許多地方理解錯誤,請多包涵與指正。
  • Mesh

    • Mesh的渲染是由Renderer Component擔當,一個Renderer會消耗一次運算,當一個角色被拆分成N個Meshes,也就會有N次的運算,因此要儘可能的減少Mesh的數量。
    • GameObject上被Deactive的Renderer Component,依舊會佔用記憶體,只是不會被呈像出來。
    • Mesh的Hard Edge上的點,因為Vert的Normal不一致,所以會被視為多個Verts,而UV Border Edge上的Vert也是一樣,在渲染流程上會被視為多個點。在Unity中所顯示的Verts、Tris就是這個真實的數量(送給OpenGLES的點的數量),所以才會有與DCC Tool中所顯示的數據不同的現象。
參考資料


  • Compression Assets
    • Unity在匯入資源時,會自動進行壓縮,而你可以在Preference中取消這項設定讓編輯時可以省下壓縮的等待時間,但在建立遊戲時是一定會進行壓縮的,不受該項設定影響。
  • Mesh Import Settings
    • Mesh Compression可以減少檔案所佔容量,但不能減少運算時的記憶體消耗。
    • Mesh Optimization會優化點的順序增進GPU運算效能。
  • Textures
    • Normals、Tangents:
      若物件沒有使用到Normal map及Real-time Lighting的話,可以取消Normals。而物件沒有使用到Normal map的話,可以取消Tangents。
    • Anisotropic Filtering:
      是針對當Mesh的面與視角的夾角相當小時會獲得較好的貼圖品質(通常用於地板),但也會增加GPU的運算消耗,在Quality Settings中可以針對所有的貼圖進行設定。
    • 在Unity中貼圖必須為二的冪次方,非二的冪次方貼圖通常只用於GUI。
    • Unity沒有限制貼圖必須為正方形,然而在iOS平台有這項要求,因此製作貼圖時須遵守正方貼圖原則。
參考資料




  • Materials:
    • 在一個GameObject、Renderer上使用的Material是越少越好,最好只使用一個,每個Material都會增加一個Draw call。
  • Skinned Mesh:
    • Unity使用1、2、4根骨頭來計算控制一個頂點,因此在DCC Tool中進行綁定時,一個頂點的權重最多包含4根骨頭即可,在遊戲中實際使用幾根骨頭做運算是依據Quality Settings中的設定。
參考資料




  • Bones:
    • PC遊戲通常的骨頭數量是介議於15~60根間,而行動平台建低於30根。(Blade&Soul的玩家角色使用約130根左右,其中包含臉部、附加骨頭)若人物有使用IK,在匯入Unity後因已經過Bake程序,應把IK清除掉必免占用運算。
  • Animation Compression:
    • Keyframe Reduction
      在匯入時減少Keyframs數量,能夠減少檔案尺寸及記憶體消耗,而Compression只能減少檔案尺寸
  • Combine Children:
    • Combine Children這個Script可以進行combine meshes的動作,而要combine的物件得使用同一張圖,這個處理可以有效降低draw calls(將多個使用同一張貼圖同一個材質的Meshes合併為一個Mesh)。

//

Manual中有優化圖像效能的指引

CPU: optimizing Draw call count
GPU: optimizing Model geometry

http://docs.unity3d.com/Documentation/Manual/OptimizingGraphicsPerformance.html

[Unity] Scroll and Turbulence Shader (流動加擾動效果)

這是我的第二個Fragment Shader,在此作紀錄供參考。
參考文章


此Shader的表現效果:


Inputs
MainTex為一張transparent texture,OffsetTex則是一張noise texture,Shader會以OffsetTex擾動MainTex,擾動的程度由Distortion控制,速度則由TurbulenceSpd控制。另外MainTex本身也會做流動,流動速度由ScrollSpd控制。
Inputs
Fragment Shader (without normals)

 Properties 
 {
  _MainTex("_MainTex", 2D) = "black" {}
  _OffsetTex("_Offset", 2D) = "black" {}
  _Distortion("_Distortion", Float ) = 0.1
  _TurbulenceSpd("_TurbulenceSpd", Float) = -50  
  _ScrollSpd("_ScrollSpd", Float) = 30
 }
 
 SubShader 
 {
  Tags
  {
   "Queue"="Transparent"
   "IgnoreProjector"="True"
   "RenderType"="Transparent"
  }
  
  Cull Off
  ZWrite Off
  Blend SrcAlpha OneMinusSrcAlpha

  Pass {
   CGPROGRAM
   #pragma vertex vert
   #pragma fragment frag
   #include "UnityCG.cginc"
   
   struct appdata {
    fixed4 vertex : POSITION;
    fixed2 texcoord : TEXCOORD0;
   };
   
   struct v2f {
    fixed4 pos : SV_POSITION;
    fixed2 uv : TEXCOORD0;
    fixed2 uv2 : TEXCOORD1;
   };
   
   fixed4 _MainTex_ST;
   fixed4 _OffsetTex_ST;
   fixed _Distortion;
   fixed _TurbulenceSpd;
   fixed _ScrollSpd;
   
   v2f vert (appdata_base v) {
    v2f o;
    
    o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    
    // Offset _MainTex uv
    fixed mainTexOffset = _Time * _ScrollSpd;
    //o.uv.x = v.texcoord.x * _MainTex_ST.x + _MainTex_ST.z;
    //o.uv.y = v.texcoord.y * _MainTex_ST.y + _MainTex_ST.w + mainTexOffset;
    o.uv.x = v.texcoord.x;
    o.uv.y = v.texcoord.y + mainTexOffset;
    
    // Offset _OffsetTex uv
    fixed offsetTexOffset = _Time * _TurbulenceSpd;
    //o.uv2.x = v.texcoord.x * _OffsetTex_ST.x + _OffsetTex_ST.z + offsetTexOffset;
    //o.uv2.y = v.texcoord.y * _OffsetTex_ST.y + _OffsetTex_ST.w;
    o.uv2.x = v.texcoord.x + offsetTexOffset;
    o.uv2.y = v.texcoord.y;
    
    return o;
   }
   
   sampler2D _MainTex;
   sampler2D _OffsetTex;
   
   fixed4 frag(v2f i) : COLOR {
    // convert OffsetTex's color to luminance to distort MainTex's uv
    fixed4 offsetTexColor = tex2D(_OffsetTex, i.uv2);
    fixed lum = Luminance(offsetTexColor);
    fixed2 texCord = ( lum, lum );
    
    fixed4 mainTexColor = tex2D( _MainTex, i.uv + texCord * _Distortion );
    
    return mainTexColor;
   }
   
   ENDCG
  }
 }

  • tex2D返回的是color值(r, g, b, a)


Surface Shader ( Need Normals)

  CGPROGRAM
  #pragma surface surf NoLighting 
  #pragma target 2.0
  
  sampler2D _MainTex;
  sampler2D _OffsetTex;
  float _Distortion;
  float _Speed;
  float _MoveSpeed;

  struct EditorSurfaceOutput {
   half3 Albedo;
   half3 Normal;
   half3 Emission;
   half3 Gloss;
   half Specular;
   half Alpha;
  };
  
  fixed4 LightingNoLighting(EditorSurfaceOutput s, fixed3 lightDir, fixed atten)
     {
         fixed4 c;
         c.rgb = s.Albedo; 
         c.a = s.Alpha;
         return c;
     }
   
  struct Input {
   float2 uv_MainTex;
   float2 uv_OffsetTex;
  };

  void surf (Input IN, inout EditorSurfaceOutput o) {
   
   // pan OffsetTex
   fixed time = _Time * _Speed;
   fixed2 UV_PanY = fixed2( IN.uv_OffsetTex.x + time, IN.uv_OffsetTex.y );
   
   // pan MainTex
   fixed moveTime = _Time * _MoveSpeed;
   fixed2 UV_PanMove = fixed2( IN.uv_OffsetTex.x, IN.uv_OffsetTex.y + moveTime );
   
   fixed2 OffsetTex2D = tex2D( _OffsetTex, UV_PanY.xy );
   fixed2 distorted = OffsetTex2D * _Distortion;
   fixed2 Add1 = UV_PanMove + distorted;
   
   fixed4 MainTex2D = tex2D( _MainTex, Add1.xy );
   
   o.Albedo = MainTex2D;
   o.Alpha = MainTex2D.a;
  }
  ENDCG

2013年9月5日 星期四

[Unity] Read/Write Enabled

Unity匯入的Asset中,Texture與Model的Import Settings裡都會有Read/Write Enabled的選項,這個選項的作用是:
  • Texture:
    • Select this to enable access to the texture data from scripts (GetPixels, SetPixels and other Texture2D functions). Note however that a copy of the texture data will be made, doubling the amount of memory required for texture asset. Use only if absolutely necessary. This is only valid for uncompressed and DTX compressed textures, other types of compressed textures cannot be read from. Disabled by default.
    • 當有scripts會從Texture存取texture data時,會需要勾選Read/Write Enabled,但這個選項會使Unity需要一份額外的copy,增加記憶體的消耗。此選項預設是關閉的,也只適用於未壓縮或DXT貼圖格式的貼圖。
  • Model:
    • Enables the mesh to be written at runtime so you can modify the data; it makes a copy in memory. When this option is turned off, it saves memory since Unity can unload a copy of mesh data in the game. However, if you are scaling or instantiating meshes at runtime with a non-uniform scale, you may have to enable "Read/Write Enabled" in their import settings. The reason is that non-uniform scaling requires the mesh data to be kept in memory. Normally this is detected at build time, but when meshes are scaled or instantiated at runtime you need to set this manually. Otherwise they might not be rendered in game builds correctly.
    • 當你需要Runtime修改Model資料時,會需要開啟Read/Write Enabled,同樣會需要一份額外的記憶體消耗,而值得注意的是當Model在Runtime有被做非等比縮放時,也會需要開啟此選項。
    • 使用Mesh Combine...功能時需要開啟Read/Write Enabled。
參考資料
參考文章

2013年9月4日 星期三

[Unity][Mecanim] flagsCount >= mask.m_Count 錯誤訊息的解決方法



  在處理Mecanim的角色時,有時候會遇到上面的錯誤訊息,經過一番搜尋在Unity Answers上找到了錯誤的原因:


  FBX檔案內的物件命名跟FBX檔名命名相同。另外也發現如果Rig Root Node的命名跟FBX檔名相同的話會產生以下的錯誤:


  因此在DCC端處理物件的時候,要注意物件的命名都不可以跟FBX檔名重複,雖然child物件並不會造成這個問題,但還是應該嚴謹一點依照此原則做命名。


  而當要修正此問題時,似乎要把原有有問題的檔案先刪除之後再Import修正過的檔案才能正確運作,若是直接覆蓋錯誤訊息依然會存在。

2013年9月3日 星期二

[Unity] Collider的Physics效能比較

  最近專案在進行效能調校時,為了要減少Physics的效能消耗,查到了freshcut在Unity Community中發表的實驗數據

在只考量Physics效能的時候,Static的Collider無論是哪一類型的Collider消耗都是非常低的,但在dynamic的狀況下,三種Collider對效能的消耗量則有相當的差距:
Box Collider > Capsule Collider >> Sphere Collider
Box Collider稍稍大於Capsule Collider的消耗,而Sphere Collider的消耗則是明顯的少了很多,因此在許可的狀況之下應盡量使用Sphere Collider。

參考文章