【UnityShader】Shaderのローカル座標 #15
前回の成果
リングを移動させることができた。
今回やること
前回行なった、一番最初のただの円を描画するだけのものです。
これを修正していこうと思います。
何を修正するの?
ただの円なので修正する箇所はないように思えます。
問題点はこの部分です。
distance(fixed3(0, 0, 0), IN.worldPos);
このソースコードは、原点とPlaneのワールド座標で比較してしまっているので、Positionを動かしてしまうと
このように円がズレてしまいます。
今回はそのズレを修正していきたいと思います。
ソースコード
Shader "Custom/moveRingFix" { Properties { _Color ("Color" , Color) = (1, 1 , 1 , 1) } SubShader { Tags { "RenderType" = "Opaque" } LOD 200 CGPROGRAM #pragma surface surf Standard #pragma target 3.0 struct Input { float3 worldPos; }; fixed4 _Color; void surf (Input IN, inout SurfaceOutputStandard o) { float3 localPos = IN.worldPos - mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz; float dist = distance(fixed3(0, 0, 0), localPos); float radius = 2.0f; if (radius < dist ) { o.Albedo = _Color; } else { o.Albedo = fixed4(1, 1, 1, 1); } } ENDCG } FallBack "Diffuse" }
float dist = distance(fixed3(0, 0, 0), IN.worldPos);
この部分を
float3 localPos = IN.worldPos - mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz; float dist = distance(fixed3(0, 0, 0), localPos);
このように修正しました。
不明な点は
- unity_ObjectToWorld
- mul
- なぜワールド座標から引いているのか
この3点なので、説明していきます。
unity_ObjectToWorld
現在のモデルの行列のことです。
他の行列変換についても紹介します。
名称 | 用途 |
---|---|
UNITY_MATRIX_MVP | 現在のモデル×ビュー×プロジェクション行列 |
UINTY_MATRIX_MV | 現在のモデル×ビュー行列 |
UNITY__MATRIX_V | 現在のビュー行列 |
UNITY_MATRIX_P | 現在のプロジェクション行列 |
UNITY_MATRIX_VP | 現在のビュー×プロジェクション行列 |
UNITY_MATRIX_T_MV | モデル×ビュー行列の変換 |
UNITY_MATRIX_IT_MV | モデル×ビュー行列の逆変換 |
unity_ObjectToWorld | 現在のモデル行列 |
unity_WorldToObject | 現在のワールド行列の逆変換 |
mul
行列の乗算になります。
// 今回の場合 // xに行列 // yにベクトル mul(x, y)
なぜワールド座標から引いているのか
これが今回の本題になります。
色々怪しい箇所があると思うので、何かあったらご指摘よろしくお願いします。
結論から先に言うと、Planeのワールド座標をローカル座標に変えるためです。
ローカル座標は、
子のワールド座標 - 親のワールド座標
で求めることができます。
では、なぜローカル座標が
IN.worldPos - mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz
この式で求められるかを説明していこうと思います。
ローカル座標の求め方
Unityは、列オーダーとなっています。
なので、ベクトルは縦ベクトル(列ベクトル)となり、
で表すことができます。
今回はfloat4(0, 0, 0, 1)ですので、
となります。
次に行列です。
列オーダーの場合には、MVP行列ではなくPVM行列となります。
MVPとはモデル・ビュー・プロジェクションの略で、説明は省かさせていただきます。
MVP行列ですと、
※TはPositionです
になるのですが、今回はPVM行列ですので
となります。
この2つのことから、
と置き換えることができます。
この行列の積は、
なので、
となります。
このベクトルからxyz成分を取れば、親のワールド座標を取ることができ、ローカル座標を求めることができます。
参考サイト様集
ローカル座標の求め方
行列の考え方
Unityにおけるベクトルのオーダー
結果
Positionを移動させても、円がズレなくなりました。
今回は以上となります。
次回はノイズを制作していきます。