知識0からのUnityShader勉強

知識0からのUnityShader勉強

UnityのShaderをメインとして、0から学んでいくブログです。

【UnityShader】Geometry Shader 基礎【1】 #74

前回の成果

uGUIを用いて波紋を出した。

soramamenatan.hatenablog.com


今回やること

Geometry Shaderの基礎を理解します。


事前準備

Scene上にSphereを配置します。
そして、今回制作するMaterialをアタッチしてください。

f:id:soramamenatan:20201010143025p:plainf:id:soramamenatan:20201010143028p:plain


ソースコード

Shader "Unlit/GeometrySimple" {
    Properties {
        _Color ("Color", Color) = (1, 1, 1, 1)
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 100

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

            #include "UnityCG.cginc"

            fixed4 _Color;

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

            struct g2f {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            appdata vert (appdata v) {
                return v;
            }

            [maxvertexcount(3)]
            void geom (triangle appdata input[3], inout TriangleStream<g2f> stream) {
                [unroll]
                for (int i = 0; i < 3; i++) {
                    appdata v = input[i];
                    g2f o;
                    o.vertex = UnityObjectToClipPos(v.vertex);
                    o.uv = v.uv;
                    stream.Append(o);
                }
                stream.RestartStrip();
            }

            fixed4 frag (g2f i) : SV_Target {
                fixed4 col = _Color;
                return col;
            }
            ENDCG
        }
    }
    FallBack "Unlit/Color"
}

vertとfragの他に、geomがあります。


Geometry Shaderとは

ジオメトリシェーダー(英: Geometry Shader, GS)はピクセルシェーダーに渡されるオブジェクト内の頂点の集合を加工するために使用される。
ジオメトリシェーダーにより、実行時に頂点数を増減させたり、プリミティブの種類を変更したりすることが可能となる。
OpenGLではプリミティブシェーダーとも呼ばれる。

ジオメトリシェーダーはポイント、ライン、トライアングルといった既存のプリミティブから新しいプリミティブを生成できる。

ジオメトリシェーダーは頂点シェーダーの後に実行され、プリミティブ全体または隣接したプリミティブの情報を持つプリミティブを入力する。

例えばトライアングルを処理するとき、3つの頂点がジオメトリシェーダーの入力となる。

ジオメトリシェーダーはラスタライズされるプリミティブを出力でき、そのフラグメントは最終的にピクセルシェーダーに渡される。

またプリミティブを出力せずにキャンセルすることもできる。

ジオメトリシェーダーのよくある使い方としては、ポイントスプライトの生成、ジオメトリテセレーション、シャドウボリュームの切り出し、キューブマップあるいはテクスチャ配列へのシングルパスレンダリングなどがある。

シェーダー - Wikipedia:より引用

簡単にまとめると、
メッシュの頂点数や頂点の増減、増やした頂点の位置や回転を制御出来るシェーダーになります。

呼び出される順番は、Vertex Shaderの後、Fragment Shaderの前となります。

f:id:soramamenatan:20201010143910j:plain

Graphics Pipeline - Win32 apps | Microsoft Docs:より引用


Macの方用

Windowsの方は飛ばして頂いて構いません。

デフォルトのUnityの設定ですと、Geometry Shaderは動きません。
なぜなら、Mac(iOS)はデフォルトで使用されているグラフィックスAPIがMetalというものになります。
このMetalはGeometry Shaderをサポートしていないため、動かなくなってしまっています。

docs.unity3d.com

ですので、使用するグラフィックスAPIをMetalからOpenGLCoreに変更します。
ただし、Geometry ShaderのためだけにMetalを変更するのはあまり良くないです。
Metalは、APIの呼び出しによるCPUオーバーヘッドが低いことや、GPU制御といったことを行ってくれるため実際に活用する際はCompute Shaderに変換する等の対策を行ったほうが良いです。


OpenGLCoreへの変更

今回はGeometry Shaderのみのプログラムのため、グラフィックスAPIをOpenGLCoreへと変更します。

まず、FileからBuild Settings...を選択します。 f:id:soramamenatan:20201010145339p:plain

次に、Player Settings...を選択します。

f:id:soramamenatan:20201010145342p:plain

Project Settingsが開くので、Playerが選択されていることを確認します。
確認できたら、Other Settingsを選択します。

f:id:soramamenatan:20201010145347p:plain

Renderingの項目に、Auto Graphics API for Macがあります。
このチェックボックスを外してください。

f:id:soramamenatan:20201010145351p:plain

外すと、Graphics APIs for Macという項目が出てきます。
そこには、

  • Metal
  • OpenGLCore

の順で並んでいるので、並び順を逆にします。

f:id:soramamenatan:20201010145355p:plain

並び順を逆にすると、Changing editor graphics deviceというポップアップが出てきます。
Restart Editorを選択するとUnityが再起動されて、グラフィックスAPIが変更されます。

f:id:soramamenatan:20201010145358p:plain


グラフィックスAPIがOpenGLCoreに変更されると、Materialをアタッチしたオブジェクトが白く変化します。
これはGeometry Shaderが反映されたためになります。

グラフィックスAPIがMetal

f:id:soramamenatan:20201010150104p:plain

グラフィックスAPIがOpenGLCore

f:id:soramamenatan:20201010150110p:plain

今回は以上となります。
ここまでご視聴ありがとうございました。

参考サイト様

kiliware.hateblo.jp

styly.cc