知識0からのUnityShader勉強

知識0からのUnityShader勉強

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

【UnityShader】様々な形 #57

前回の成果

お絵かきシェーダーで繰り返しを表現した。

soramamenatan.hatenablog.com


今回やること

今回は図形を描画していきます。

karanokan.info


事前準備

Scene上にPlaneを配置し、今回制作するマテリアルをアタッチします。

f:id:soramamenatan:20200614183639p:plain


ソースコード

Shader "Unlit/Figure" {
    Properties {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

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

            struct v2f {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v) {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

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

様々な図形を紹介するので、テンプレート的なものを置いておきます。
基本的にはフラグメントシェーダーを変更していきます。


ソースコード

// 円
// uv : uv値
// r : 半径
float circle(float2 uv, float r) {
    return length(uv) - r;
}

fixed4 frag (v2f i) : SV_Target {
    fixed2 uv = i.uv - fixed2(0.5,0.5);
    fixed4 col = step(0.4, circle(uv, 0.05));
    return col;
}

結果

f:id:soramamenatan:20200614184313p:plain


楕円

ソースコード

// 楕円
// uv : uv値
// r : 縦横の長さ
float ellipse(float2 uv, float2 r) {
    return length(uv / r);
}

fixed4 frag (v2f i) : SV_Target {
    fixed2 uv = i.uv - fixed2(0.5,0.5);
    fixed4 col = step(0.4, ellipse(uv, float2(1, 0.5)));
    return col;
}

結果

f:id:soramamenatan:20200614185150p:plain


四角形

ソースコード

// 四角形
// uv : uv値
// r : 縦横の長さ
float square(float2 uv, float2 r) {
    return max(abs(uv.x) - r.x, abs(uv.y) - r.y);
}

fixed4 frag (v2f i) : SV_Target {
    fixed2 uv = i.uv - fixed2(0.5,0.5);
    fixed4 col = step(0.4, square(uv, float2(0.01, 0.01)));
    return col;
}

結果

f:id:soramamenatan:20200614190003p:plain


ひし形

ソースコード

// ひし形
// uv : uv値
// r : 縦横の長さ
float rhombus(float2 uv, float2 r) {
    return abs(uv.x) + abs(uv.y) - r;
}

fixed4 frag (v2f i) : SV_Target {
    fixed2 uv = i.uv - fixed2(0.5,0.5);
    fixed4 col = step(0.4, rhombus(uv, float2(0.01, 0.01)));
    return col;
}

結果

f:id:soramamenatan:20200614190237p:plain


多角形

ソースコード

// 多角形
// uv : uv値
// r : 縦横の長さ
// sideNum : 辺の数
float polygon(float2 uv, float2 r, int sideNum) {
    float atan = atan2(uv.x, uv.y);
    float rad = 2 * PI / sideNum;
    return cos(floor(0.5 + atan / rad) * rad - atan) * length(uv) - r;
}

fixed4 frag (v2f i) : SV_Target {
    fixed2 uv = i.uv - fixed2(0.5,0.5);
    fixed4 col = step(0.4, polygon(uv, float2(0.005, 0.005), 5));
    return col;
}

結果

f:id:soramamenatan:20200614191123p:plain


ハート

ソースコード

// ハート
// uv : uv値
// r : 縦横の長さ
float heart(float2 uv, float2 r) {
    uv.x = 1.2 * uv.x + sign(uv.x) * uv.y * 0.55;
    return length(uv) - r;
}

fixed4 frag (v2f i) : SV_Target {
    fixed2 uv = i.uv - fixed2(0.5,0.5);
    fixed4 col = step(0.4, heart(uv, float2(0.001,0.001)));
    return col;
}

結果

f:id:soramamenatan:20200614195914p:plain

最後に全部まとめたソースコードを置いておきます。

ソースコード

Shader "Unlit/Figure" {
    Properties {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

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

            struct v2f {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            static const float PI = 3.14159265;

            v2f vert (appdata v) {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            // 円
            // uv : uv値
            // r : 半径
            float circle(float2 uv, float r) {
                return length(uv) - r;
            }

            // 楕円
            // uv : uv値
            // r : 縦横の長さ
            float ellipse(float2 uv, float2 r) {
                return length(uv / r);
            }

            // 四角形
            // uv : uv値
            // r : 縦横の長さ
            float square(float2 uv, float2 r) {
                return max(abs(uv.x) - r.x, abs(uv.y) - r.y);
            }

            // ひし形
            // uv : uv値
            // r : 縦横の長さ
            float rhombus(float2 uv, float2 r) {
                return abs(uv.x) + abs(uv.y) - r;
            }

            // 多角形
            // uv : uv値
            // r : 縦横の長さ
            // sideNum : 辺の数
            float polygon(float2 uv, float2 r, int sideNum) {
                float atan = atan2(uv.x, uv.y);
                float rad = 2 * PI / sideNum;
                return cos(floor(0.5 + atan / rad) * rad - atan) * length(uv) - r;
            }

            // ハート
            // uv : uv値
            // r : 縦横の長さ
            float heart(float2 uv, float2 r) {
                uv.x = 1.2 * uv.x + sign(uv.x) * uv.y * 0.55;
                return length(uv) - r;
            }

            fixed4 frag (v2f i) : SV_Target {
                fixed2 uv = i.uv - fixed2(0.5,0.5);
                fixed4 col = step(0.4, heart(uv, float2(0.001,0.001)));
                return col;
            }
            ENDCG
        }
    }
}

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