投稿者 tel | 2018年7月31日

法線やUVを確認するシェーダ

Unityでメッシュの法線とかUVとか頂点カラーを確認するためのシェーダを書いた。頂点カラー使ってないのにメッシュに含まれてる場合に確認するために使う。

別々のシェーダをいちいちつけ直すのが面倒なのでマテリアルのプロパティから変更する。

法線表示

UV表示

広告
投稿者 tel | 2018年6月28日

UnityのTRANSFORM_TEXマクロ

シェーダでタイリングなどを計算するためのマクロとしてTRANSFORM_TEXをつかう。
以下のようにUVスクロールするためにUVを計算してからTRANSFORM_TEXをつかったところタイリングが効かなくなった。

o.texcoord = TRANSFORM_TEX(v.texcoord + _Time.yy, _MainTex);


TRANSFORM_TEXはUnity.cgincに定義されている。

// Transforms 2D UV by scale/bias property
#define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)

これをそのまま適用するとGLSLでは以下のように展開される。
先に_Time.yyと_MainTex_ST.xyが乗算されてしまっている。

xlv_TEXCOORD0 = ((_glesMultiTexCoord0.xy + (_Time.yy * _MainTex_ST.xy)) + _MainTex_ST.zw);

ようするにちゃんと括弧を付けてあげないといけない。

o.texcoord = TRANSFORM_TEX((v.texcoord + _Time.yy), _MainTex);


GLSLに展開されるとちゃんと加算が先にされている。

xlv_TEXCOORD0 = (((_glesMultiTexCoord0.xy + _Time.yy) * _MainTex_ST.xy) + _MainTex_ST.zw);
投稿者 tel | 2018年5月6日

C#のオーバーロード

C#とC++でオーバーロードされた関数の呼び出し解決が異なっていたのでメモ。

C#だと以下のコードのコンパイルが通る。引数がないほうが呼び出される。

class Program
{
    static void Test()
    {
    }

    static void Test(int a = 1)
    {
    }
 
    static void Main(string[] args)
    {
        Test();
    }
}

C++だと関数呼び出しが曖昧なのでコンパイルエラーになる。

void Test()
{
}

void Test(int a = 1)
{
}

int main()
{
    Test();
}

Unityでシェーダ名を取得するとUnlit/Textureのようにシェーダファイルに書かれた名前が返ってくる。

ただ以下の場合ではシェーダ名が返ってこない。

  • 初回起動時などLibraryディレクトリが作成されていない
  • プロジェクトに含まれているカスタムシェーダを使用している
  • マテリアルが生成された状態のモデルがプロジェクトに追加されている
  • OnPostprocessModelでモデルのマテリアルからシェーダを参照する

この状態でマテリアルについているシェーダのShader.nameをOnPostprocessModelで取得するとファイル名になる。

void OnPostprocessModel(GameObject g)
{
    foreach (var r in g.GetComponentsInChildren<Renderer>())
    {
        foreach (var m in r.sharedMaterials)
        {
            Debug.Log(m.shader.name);
        }
    }
}

Reimportしたときはシェーダ名が取れる。

この挙動で困るのはfbxのインポート時にシェーダの張替えやマテリアルのプロパティの設定を自動化する場合、シェーダが張り替えられているかどうかを判定するのにShader.nameを参照している意図しない動作をしてしまう。

挙動が確認できるプロジェクト
https://github.com/sapphire-al2o3/FirstImportTest/

 

投稿者 tel | 2018年4月3日

Unity最適化メモ

Object.nameにアクセスするとGC Allocが発生する(Unity 5.6.5p1)

プロファイラで確認すると400KB程度のGC Allocが発生している。

Deep ProfileでみるとObject.get_nameでGC Allocが発生していることがわかる。

一時変数に入れて比較すれば1回分のメモリ確保で済む。

string objectName = this.name;
for (int i = 0; i < 10000; i++)
{
    if (objectName == "")
    {
    }
}

投稿者 tel | 2018年3月31日

サンシャイン水族館

サンシャイン水族館に行ってきた。入場料2200円。

続きを読む…

UnityのParticleSystemでAuto Random Seedのチェックを外してRandom Seedに適当な値をいれて再生するとパーティクルの見た目を再生するごとに同じにできる。

Unity5.4とUnity5.5以上ではParticleSystemのRandom Seedに同じ値を入れても再生されるパーティクルの見た目が変わっている。

1を入れて再生したときの見た目が各バージョンによって以下のようになる。

Unity5.5と5.6ではまったく同じ見た目になっているので5.5でおそらくなんらかの変更が入っている。Unity5.4のプロジェクトをバージョンアップしたときに変換してくれないようなので困った。

投稿者 tel | 2018年1月7日

2018年

あけましておめでとうございます。

幸せになりたいです。

投稿者 tel | 2017年12月31日

PVRTC圧縮テクスチャの端がにじむ

iOS用にテクスチャをPVRTC圧縮すると端がにじむ場合がある。これはPVRTCが4×4ブロックの上下左右を補間しているのが原因らしい。例えば一番左上のブロックは右と下のブロックに加えて反対側の左下と右上のブロックを参照している(みたい)。
ETCだと各ブロックの補間がないためこのようなことは起こらない。

上の図はUnity上で16×16のサイズで各圧縮をしたテクスチャを表示してみた結果。PVRTCは一番下の白のラインが赤くにじんでいる。

対処方法

  • RGBA16にする。
    ファイルサイズが大きくなるがしょうがない。
  • テクスチャの端を使わないようにする。
    マテリアルのオフセットやモデルのUVを調整して画像の端が入らないようにする。
  • iPhone5以前を切り捨てる。
    ETC2を使おう。

特にいい方法はない。

投稿者 tel | 2017年11月29日

C#でintをEnumにキャストする

C#で整数値を列挙体にキャストする。

int n = 0;
EnumTest enumTest = (EnumTest)Enum.ToObject(typeof(EnumTest), n);

上記だとボックス化が解除されてメモリアロケートが発生するので以下のように普通にキャストする。

int n = 0;
EnumTest enumTest = (EnumTest)n;

型があらかじめ分かっているならたぶんEnum.ToObject使う必要がない。

Older Posts »

カテゴリー