ロケットリーグを見ていて、アニメーションのデカールとホイールがあることに気づきました。
。
上の画像の効果に似たものを実装したいと思います。
Unityシェーダーを作成してホイールエフェクトを作成するにはどうすればよいですか?
シェーダーについてよく知りませんが、標準のUnityシェーダーを編集してアニメーション効果を実行できますか?
ロケットリーグを見ていて、アニメーションのデカールとホイールがあることに気づきました。
。
上の画像の効果に似たものを実装したいと思います。
Unityシェーダーを作成してホイールエフェクトを作成するにはどうすればよいですか?
シェーダーについてよく知りませんが、標準のUnityシェーダーを編集してアニメーション効果を実行できますか?
回答:
これをいくつかの層に積み上げて、どのように組み合わされるかを確認できるようにします。
Unityで新しいシェーダーを作成することから始めCreate --> Shader --> Unlit
ます。[プロジェクト]ウィンドウの[アセット]メニューまたは右クリックコンテキストメニューを選択します。
上のブロックに_ScrollSpeeds
、テクスチャーが各方向に動く速度を制御するパラメーターを追加します。
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_ScrollSpeeds ("Scroll Speeds", vector) = (-5, -20, 0, 0)
}
これにより、マテリアルインスペクタに新しい4コンポーネントフロートプロパティが表示されます。これは、「Scroll Speeds」というわかりやすい名前で付けられています(スクリプトにpublic
またはSerialized
変数を追加するのと同じですMonoBehaviour
)。
次に、この変数を頂点シェーダーで使用o.uv
して、デフォルトのシェーダーに2行だけ追加することにより、テクスチャ座標()をシフトします。
sampler2D _MainTex;
float4 _MainTex_ST;
// Declare our new parameter here so it's visible to the CG shader
float4 _ScrollSpeeds;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
// Shift the uvs over time.
o.uv += _ScrollSpeeds * _Time.x;
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
それをクワッドで叩いて(ケニーによる素敵な無料のキリンの質感で)、あなたは次のようになります:
テクスチャをリング内で外側にスクロールするには、スパイダーウェブのように細分割されたメッシュを使用し、中心から外側に向かってUV V座標を増加させます。しかし、それはそれ自体でいくつかの鋸刃状のアーティファクトを与えます。代わりに、フラグメントごとのUVを計算する方法を示します。
これは、trig&length操作(基本的な計算よりもコストが高い)と、補間するだけではなく、フラグメントごとにtexcoordを計算するときにハードウェアでテクスチャデータを予測してキャッシュするのが効率的でないため、少しコストがかかります。頂点間。しかし、このような小さな特殊効果の場合、それは過度ではありません。
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
// Shift the UVs so (0, 0) is in the middle of the quad.
o.uv = v.uv - 0.5f;
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// Convert our texture coordinates to polar form:
float2 polar = float2(
atan2(i.uv.y, i.uv.x)/(2.0f * 3.141592653589f), // angle
length(i.uv) // radius
);
// Apply texture scale
polar *= _MainTex_ST.xy;
// Scroll the texture over time.
polar += _ScrollSpeeds.xy * _Time.x;
// Sample using the polar coordinates, instead of the original uvs.
// Here I multiply by MainTex
fixed4 col = tex2D(_MainTex, polar);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
それは私たちにこのようなものを与えます(ここで私はマテリアルのタイリングパラメーターを増やしたので、何が起こっているのかより明確になります-円の周りのタイルの単一の繰り返しだけを包むことは歪んで奇妙に見えます)
最後に、スクロールグラデーションでテクスチャに色を付けるには、2番目のテクスチャとしてグラデーションを追加し、それらを掛け合わせるだけです。
最初に、新しいテクスチャパラメータを上部に追加します。
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_TintTex("Tint Texture", 2D) = "white" {}
_ScrollSpeeds ("Scroll Speeds", vector) = (-5.0, -20.0, 0, 0)
}
そして、CGシェーダーがそれを見ることができるように、それをCGPROGRAMブロックで宣言します。
sampler2D _MainTex;
float4 _MainTex_ST;
// Declare our second texture sampler and its Scale/Translate values
sampler2D _TintTex;
float4 _TintTex_ST;
float4 _ScrollSpeeds;
次に、フラグメントシェーダーを更新して両方のテクスチャを使用します。
fixed4 frag(v2f i) : SV_Target
{
float2 polar = float2(
atan2(i.uv.y, i.uv.x) / (2.0f * 3.141592653589f), // angle
length(i.uv) // radius
);
// Copy the polar coordinates before we scale & shift them,
// so we can scale & shift the tint texture independently.
float2 tintUVs = polar * _TintTex_ST.xy;
tintUVs += _ScrollSpeeds.zw * _Time.x;
polar *= _MainTex_ST.xy;
polar += _ScrollSpeeds.xy * _Time.x;
fixed4 col = tex2D(_MainTex, polar);
// Tint the colour by our second texture.
col *= tex2D(_TintTex, tintUVs);
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
そして今、私たちのキリンは本当にトリッピーになります:
テクスチャとスクロールレートを少し芸術的に選択すると、質問で示したものと非常によく似た効果が得られます。
上記で示したバージョンの2つの小さなアーティファクトに気付くでしょう。
円の中心付近の顔は引き伸ばされた/細く/先のとがったものになり、外側に向かって移動すると、押しつぶされた/広くなります。
この歪みは、周囲に一定数の面があるために発生しますが、半径が大きくなると、それらがまたがっている円周は、高さが同じままで広くなります。
これを修正するには、テクスチャサンプルの垂直成分を再マップして対数曲線をたどります。そのため、テクスチャの繰り返しは、半径が大きくなるにつれて離れ、中心に近づくほど近くなります。(実際には、これは私たちにますます小さなキリンの無限の退行を与えます...)
クワッドの左中央に沿って1つまたは2つのぼやけたピクセルの行があります。
これは、GPUが2つの隣接するテクスチャサンプル座標を調べて、使用するフィルタリングを把握するために発生します。サンプルが近接している場合、テクスチャが大きく/近接して表示されていることがわかり、最も詳細なミップレベルが表示されます。サンプルが遠く離れている場合は、テクスチャを小さなズームまたは遠くで表示している必要があると推測し、きらめくエイリアシングアーティファクトが発生しないように、小さい/ブラーミップマップからサンプリングします。
問題はここです。極座標のラップアラウンドポイントである-180から180度です。そのため、実際には、繰り返されるテクスチャ空間の非常に類似したポイントからサンプリングしています。たとえそれらの数値座標によって、それらが離れているように見える場合でもです。したがって、これを修正するために独自のサンプリング勾配ベクトルを提供できます。
これらの修正を加えたバージョンは次のとおりです。
fixed4 frag(v2f i) : SV_Target
{
float2 polar = float2(
atan2(i.uv.y, i.uv.x) / (2.0f * 3.141592653589f), // angle
log(dot(i.uv, i.uv)) * 0.5f // log-radius
);
// Check how much our texture sampling point changes between
// neighbouring pixels to the sides (ddx) and above/below (ddy)
float4 gradient = float4(ddx(polar), ddy(polar));
// If our angle wraps around between adjacent samples,
// discard one full rotation from its value and keep the fraction.
gradient.xz = frac(gradient.xz + 1.5f) - 0.5f;
// Copy the polar coordinates before we scale & shift them,
// so we can scale & shift the tint texture independently.
float2 tintUVs = polar * _TintTex_ST.xy;
tintUVs += _ScrollSpeeds.zw * _Time.x;
polar *= _MainTex_ST.xy;
polar += _ScrollSpeeds.xy * _Time.x;
// Sample with our custom gradients.
fixed4 col = tex2Dgrad(_MainTex, polar,
_MainTex_ST.xy * gradient.xy,
_MainTex_ST.xy * gradient.zw
);
// Since our tint texture has its own scale,
// its gradients also need to be scaled to match.
col *= tex2Dgrad(_TintTex, tintUVs,
_TintTex_ST.xy * gradient.xy,
_TintTex_ST.xy * gradient.zw
);
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
_Time
、(頂点)シェーダーのテクスチャ座標に追加できる組み込み変数があり、スクロール効果を簡単に取得できます。六角形の効果も非常に簡単です。質問を編集して1つの効果のみを強調し、「Unityシェーダーでこれをどのように実装しますか?」と尋ねると、おそらく私たちがお手伝いできます。シェーダーがライティング/シャドウイングに応答する必要があるかどうかを指定してください。これは、シェーダーの記述方法に影響を与えるためです。