🌈

そろそろShaderをやるパート17 ジオメトリーシェーダーでポリゴンの大きさを変える

2020/11/23に公開3

そろそろShaderをやります

そろそろShaderをやります。そろそろShaderをやりたいからです。
パート100までダラダラ頑張ります。10年かかってもいいのでやります。
100記事分くらい学べば私レベルの初心者でもまあまあ理解できるかなと思っています。

という感じでやってます。

※初心者がメモレベルで記録するので
 技術記事としてはお力になれないかもしれません。

下準備

下記参考
そろそろShaderをやるパート1 Unite 2017の動画を見る(基礎知識~フラグメントシェーダーで色を変える)

デモ

各ポリゴンの中心を原点としてスケールを変更しています。

Shaderサンプル

Shader "Custom/GeometryScalable"
{
    Properties
    {
        _Color ("Color", Color) = (1, 1, 1, 1)
        _ScaleFactor ("Scale Factor", Range(0,1.0)) = 0.5
    }
    SubShader
    {
        Tags
        {
            "RenderType"="Opaque"
        }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma geometry geom
            #pragma fragment frag

            #include "UnityCG.cginc"

            fixed4 _Color;
            float _ScaleFactor;

            //頂点シェーダーに渡ってくる頂点データ
            struct appdata
            {
                float4 vertex : POSITION;
            };

            //ジオメトリシェーダーからフラグメントシェーダーに渡すデータ
            struct g2f
            {
                float4 vertex : SV_POSITION;
            };

            //頂点シェーダー
            appdata vert(appdata v)
            {
                return v;
            }

            //ジオメトリシェーダー
            //引数のinputは文字通り頂点シェーダーからの入力
            //streamは参照渡しで次の処理に値を受け渡ししている TriangleStream<>で三角面を出力する
            [maxvertexcount(3)] //出力する頂点の最大数 正直よくわからない
            void geom(triangle appdata input[3], inout TriangleStream<g2f> stream)
            {
                //1枚のポリゴンの中心
                float3 center = (input[0].vertex + input[1].vertex + input[2].vertex) / 3;

                [unroll] //繰り返す処理を畳み込んで最適化してる?
                for (int i = 0; i < 3; i++)
                {
                    appdata v = input[i];
                    g2f o;
                    //中心を起点にスケールを変える
                    v.vertex.xyz = (v.vertex.xyz - center) * (1.0 - _ScaleFactor) + center;
                    o.vertex = UnityObjectToClipPos(v.vertex);
                    stream.Append(o);
                }
            }

            //フラグメントシェーダー
            fixed4 frag(g2f i) : SV_Target
            {
                return _Color;
            }
            ENDCG
        }
    }
}

v.vertex.xyz = (v.vertex.xyz - center) * (1.0 - _ScaleFactor) + center;
上記箇所でポリゴンの中心を原点としてスケールを変更してます。
この式を図解すると下記のようになります。

【参考リンク】:ベクトルの加法と減法

なぜcenterを引いて、計算後にまたcenter足すとポリゴンを中心とした動きになるのか
図解して考えてようやく理解できました。

参考リンク

ジオメトリシェーダ入門
Graphics Pipeline
Direct3D 10 Shader4.0 ループと最適化
Geometry Shader:Terrain with grass
【Unity】Geometry Shader(ジオメトリシェーダー)の超入門サンプル【初心者向け】

Discussion

catnosecatnose

トピックが「unity」ではなく「untiy」になってしまっています!笑

KENTOKENTO

それ気付いたんですけど、直し方わからなくて問合せ送っちゃいました!
どうすれば直せますか?