Help us understand the problem. What is going on with this article?

【Unity】テクスチャ情報から頂点イジるシェーダーを作ってみる【頂点テクスチャフェッチ(VTF)】

More than 1 year has passed since last update.

テクスチャを読み込んで、頂点座標をイジるシンプルなシェーダーのサンプルを作ってみました!

テクスチャ情報から頂点を制御したい!と考えている方の参考になあれば幸いです。

頂点テクスチャフェッチ(VTF)とは?

VTFについて、丁寧にまとめられていた記事がありましたので引用します。

頂点テクスチャフェッチは、その英語表記の頭文字を取って VTF などと呼ばれることもあります。近年のコンシューマゲームなどでも割と活躍している技術の一つで、その応用範囲はかなり広いと言っていいと思います。

頂点テクスチャフェッチとは、簡潔に言うなら[ 頂点シェーダ内でテクスチャを参照すること ]を指します。
頂点テクスチャフェッチ(VTF

早速、サンプルを紹介します!

シェーダーの完成形

ご紹介するサンプルは貼り付けたテクスチャのRGBの”R”値によって、y座標の頂点が変わるシェーダーになります。
スクリーンショット 2019-02-19 22.56.09.png

上図はわかりやすく白黒のテクスチャを貼り付けたオブジェクトです。白い部分が盛り上がっているのを、ご確認いただけると思います。

ソース

ソースは以下の通りです。

vtfSample.shader
Shader "Unlit/vtfSample"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Tex2Dlod ("Tex2DlodSample", 2D) = "white" {}

    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100
        Cull off

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float2 texcoord : TEXCOORD1;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float2 texcoord : TEXCOORD1;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            sampler2D _Tex2Dlod;
            float4    _Tex2Dlod_ST;

            v2f vert (appdata v)
            {
                v2f o;

                float d = tex2Dlod(_Tex2Dlod, float4(v.texcoord.xy,0,0)).r;
                v.vertex.y += d;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                UNITY_APPLY_FOG(i.fogCoord, col);
                return col;
            }
            ENDCG
        }
    }
}

Unityにて、頂点シェーダーで参照したいテクスチャをTex2DlodSampleにアタッチ、フラグメントシェーダーで参照したいテクスチャをTextureにアタッチすればOKです。

頂点シェーダーでテクスチャを読み込みときは、tex2Dlodを使いますのでご注意ください!

注意点:テクスチャの設定でWrap ModeをClampにしよう!

ただ、このままですと、こんな風に崩れてしまう可能性があります。
cu31WJvQ.jpg

原因はテクスチャのWrap ModeがRepeatになっているため、端っこが白黒になってしまっているからです。

テクスチャのWrap ModeをClampにすれば万事解決です!
スクリーンショット_2019-02-20_17_50_46.png

 最後に

いかがだったでしょうか?

今回は超シンプルなシェーダーになっていますが、ここから様々な表現ができると思います。

ぜひ色々いじってみてください!

スペシャルサンクス

このシェーダー作るのに、うまくいかなくて悪戦苦闘していたのですが、伊藤さん@warapuriに質問したところ、無事に解決できました。

この場をかりて感謝御礼申し上げますm(_ _)m

参考記事

guru_taka
ぐるたかです。0→1を作る人に憧れ、2018.10からプログラミングを学び、今はとある会社で、webサービスを開発中。家ではARアプリやwebサービス、拡張機能など色々と個人開発してます。前まではUnityに夢中でしたが、最近はNuxtにハマっています。代表作はおっぱい関数ジェネレーターと塗り絵AR。
https://gurutaka-log.com/
admin-guild
「Webサービスの運営に必要なあらゆる知見」を共有できる場として作られた、運営者のためのコミュニティです。
https://admin-guild.slack.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away