UV座標のOverrideを理解する

背景

f:id:SiunCyclone:20200508230243p:plain

上の画像で,左上にあるテクスチャのUV空間を,GradientNoiseでOverrideした場合,右下のようなテクスチャが得られる.
この時Overrideは具体的にどのような処理を行っているのか理解できなかったので調べた.

UVの基本

f:id:SiunCyclone:20200508231210p:plain

  1. まず,UV空間は左下を(0,0)右上を(1,1)として定義されている.
    f:id:SiunCyclone:20200509000053p:plain

  2. 次にこのUV空間をX軸方向成分,Y軸方向成分のみ取り出すと以下のような1次元配列となる.
    f:id:SiunCyclone:20200509000115p:plain

  3. この1次元配列をUVに繋げた場合,0は(0,0),0.1は(0.1,0.1),1は(1,1)のようにして渡される(注1) f:id:SiunCyclone:20200509000415p:plain

  4. UV座標の(0,0),(0.1,0.1),・・・(1,1)が意味するのは画像のピンクの直線部分である f:id:SiunCyclone:20200509000826p:plain

  5. 対応関係を示すと以下のようになる f:id:SiunCyclone:20200509001150p:plain

本題

以上を踏まえると最初の画像が読み解けるようになる f:id:SiunCyclone:20200509002730p:plain  
   

注1

シェーダコードを実際にみて確かめた
上:今回のように値が1つの場合
f:id:SiunCyclone:20200509001350p:plain 下:デフォルト f:id:SiunCyclone:20200509001358p:plain なおvec = (1,2,3)があった場合
vec.xx = (1, 1)
vec.xy = (1, 2)
vec.zz = (3, 3)
となる

Archエラーメモ

背景

archを久々に入れようと思ったらエラーが出た

2019年12月27日にパッケージの圧縮形式がxz (.pkg.tar.xz)からzstd (.pkg.tar.zst)に変わった

Arch Linux - News: Now using Zstandard instead of xz for package compression

1. keyringが古い

* エラーメッセージ
error: krb5: signature from "Levente Polyak (anthraxx) <levente@leventepolyak.net>" is unknown trust
* 解決策
sudo pacman -S archlinux-keyring

2. libarchiveが古い(2018以降アップデートしてないとか)

* エラーメッセージ
error: could not open file /var/cache/pacman/pkg/archlinux-keyring-20200108-1-any.pkg.tar.zst: Unrecognized archive format
* 解決策
1. pacman-staticをダウンロードする
  curl https://pkgbuild.com/~eschwartz/repo/x86_64-extracted/pacman-static -o pacman-static
2. pacman-staticに実行権限を与える
chmod +x pacman-static
3. pacman-staticを使ってlibarchiveを更新する
sudo ./pacman-static -S libarchive

Unityで[SerializeField]を使った時に出る未初期化の警告を消す

問題

Unity(2019.3.0f1)で[SerializeFiled]を使用してインスペクタから値を設定した場合

warning CS0649: ... is never assigned to, ...

の警告が出る

(一時的な)解決方法

Assets/csc.rspファイルを作る(C# Compiler Response File)
中身は

/nowarn:0649

もしくは

-nowarn:0649

すべてのコンパイル オプションは、-option および /option という 2 つの形で使用できます。 C# コンパイラ オプション | Microsoft Docs

根本的な解決はUnityが対応するまで待つしかない

一連の経緯

  1. Monoコンパイラのバグで今まで警告がでてなかった
  2. UnityがMonoからRoslynを使うようになった
  3. 警告が出るようになった
  4. Roslynにプログラマブルに警告抑える機能が追加される
    DiagnosticSuppressor APIを実装したので警告消すのは可能になった
    今まではなかった
    Programmatic suppression of warnings · Issue #30172 · dotnet/roslyn · GitHub
  5. Unity対応中(イマココ)

    This can be fixed using DiagnosticSuppressor API in Roslyn. However, this requires that Unity updates Roslyn to a newer version that supports DiagnosticSuppressor and that proper support for using Roslyn analyzers is added to Unity. The fix of this issue is therefore postponed.

https://forum.unity.com/threads/feature-request-use-new-diagnosticsuppressor-api-to-suppress-cs0649-on-serializefield.697514/
Unity Issue Tracker - [SerializedField] fields produce &quot;Field is never assigned to...&quot; warning

その他の方法

csc.rsp以外にも解決方法はあるものの自分は採用しなかったメモ

1. #pragmaを使う

#pragma warning disable 0649
// your code
#pragma warning restore 0649

これかcsc.rspで迷った

#pragmaの場合
一時的な対応: 全部の[SerializeField]を#pragmaで囲う
Unity対応後: #pragma書いたとこ全部消す

csc.rspの場合
一時的な対応: csc.rspファイル書くだけ
Unity対応後: csc.rspファイル消すだけ

csc.rspは他の部分の0649警告も全て消してしまうという欠点はあるけど,上記の手軽さから使うことにした

2. 初期値を書く

初期値を書く場合
一時的な対応: 全部の[SerializeField]部分に初期値を書く
Unity対応後: 特に何もしなくていい

採用しない理由
[SerializeField]を使う場合,プログラマーはその値がインスペクタで設定されることを想定している.
つまり初期値として,インスペクタの値が入っていることを想定している.
にもかかわらずコード上で,初期値としてnullや0を与えるというのは「インスペクタの値を初期値と想定する」というプログラマーの意図に反する.

初期値を使う時というのは,例えばインスペクタで値を設定することを主としているが, 「インスペクタで設定しない時はこの値で実行するつもり」,という意図があるときだけである.

最初からインスペクタでしか設定するつもりがないのならば,初期値は使わないほうがよい(その方が意図が明確になる)

(補足)
しかし,例えばUnityの公式サンプルでは初期値を与えて警告を消していたりする.
2D Tools evolved | Unity
これはサンプルという性質上,Unity対応後にcsc.rspを消す方が手間なので理解できる.

3. publicにする

論外
[SerializeField] privateは「エディタ上では変更されることを想定しているが,実行時は外部から変更されない」ということを意図する時に使う.
publicにしたら実行時も外部から変更できてしまうのでコードの文脈が変わる.

Unityでダウングレードすると起きるパッケージエラーの直し方

具体例

2020.1.0a9から2019.3.0b9にダウングレードするとパッケージエラーが起きる f:id:SiunCyclone:20191104144715p:plain:h150

原因

パッケージのバージョンが合ってない

Library/PackageCache
  • プロジェクトを2020.1.0a9で作った時 f:id:SiunCyclone:20191104143312p:plain

  • プロジェクトを2019.3.0b9で作った時 f:id:SiunCyclone:20191104142900p:plain

  • プロジェクトを2020.1.0a9で作り,2019.3.0b9にダウングレードした時 f:id:SiunCyclone:20191104143552p:plain

解決法

Package/manifest.jsonを,2020.1.0a9から2019.3.0b9のものへ手動で書き換える

デフォルトのPackage/manifest.json
  • 2020.1.0a9 f:id:SiunCyclone:20191104141802p:plain

  • 2019.3.0b9 f:id:SiunCyclone:20191104141755p:plain

(デフォルトで2019.3.0b9の方がパッケージのバージョンが新しくなっている)

ダウングレードしただけではmanifest.jsonは勝手に書き換わらない.

ShaderGraphでテクスチャからディスプレイスメントマッピングをするときは,Sampler Texture 2D LODを使う

したかった事

スクリプト内でノイズテクスチャを生成し,それを元にShaderGraphでディスプレイスメントマッピングをする

はまった問題

Sampler Texture 2Dノードが繋がっていると,PBR MasterのPositionに繋げられない f:id:SiunCyclone:20190919231700p:plain

原因と解決策

原因:Sampler Texture 2Dノードがフラグメントシェーダ内で使用されるノードなため,頂点出力には使えない

解決策:Sampler Texture 2D LODをかわりに使う(こっちは頂点シェーダ内で使える)

f:id:SiunCyclone:20190919232802p:plain

参考

https://forum.unity.com/threads/shadergraph-cant-offset-vertex-position-by-texture-lookup.545541/

blogs.unity3d.com

ERROR You have missing MonoBehaviours on your gameobjects!が出たときの原因

f:id:SiunCyclone:20181216192408p:plain

上記のエラーが出る時は、PhotonのRPCで同期したGameObjectのコンポーネントに、Missingなスクリプトが張り付いている可能性がある。

f:id:SiunCyclone:20181216192414p:plain

これを削除すればエラーは消える。