知識0からのUnityShader勉強

知識0からのUnityShader勉強

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

【UnityShader】溶けるような表現をする #21

前回の成果

風に揺られているような表現ができた。

soramamenatan.hatenablog.com

今回やること

溶けるようなシェーダーを制作します。

nn-hokuson.hatenablog.com

事前準備

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

f:id:soramamenatan:20190909104042p:plain

そして、DissolveTexに下記のテクスチャをアタッチしてください。

f:id:soramamenatan:20190909104147j:plain

【Unityシェーダ入門】Dissolve(溶けるような)シェーダをつくる - おもちゃラボ:より引用

ソースコード

Shader "Custom/dissolve" {
    Properties {
        _Color("Color", Color) = (1, 1, 1, 1)
        _MainTex("MainTex", 2D) = "white" {}
        _DissolveTex("DissolveTex", 2D) = "white" {}
        _Glossiness("Glossiness", Range(0, 1)) = 0.5
        _Metallic("Metallic", Range(0, 1)) = 0.0
        _Threshold("Threshold", Range(0, 1)) = 0.0
    }

    SubShader {
        Tags { "RenderType" = "Opaque"}
        LOD 200

        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows
        #pragma target 3.0

        sampler2D _MainTex;
        sampler2D _DissolveTex;

        struct Input {
            float2 uv_MainTex;
        };

        half _Glossiness;
        half _Metallic;
        half _Threshold;
        fixed4 _Color;

        void surf(Input IN, inout SurfaceOutputStandard o) {
            fixed4 dissolveTex = tex2D(_DissolveTex, IN.uv_MainTex);
            half gray = dissolveTex.r * 0.3f + dissolveTex.g * 0.59f + dissolveTex.b * 0.11f;
            if (gray <= _Threshold) {
                discard;
            }
            fixed4 mainTex = tex2D(_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = mainTex.rgb;
            o.Alpha = mainTex.a;
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
        }
        ENDCG
    }
    Fallback "Diffuse"
}

この部分から、

half gray = dissolveTex.r * 0.3f + dissolveTex.g * 0.59f + dissolveTex.b * 0.11f;

グレースケールを使用しているのがわかります。

discard

ピクセルレンダリングしないことです。

今回の場合は、ここで

half gray = dissolveTex.r * 0.3f + dissolveTex.g * 0.59f + dissolveTex.b * 0.11f;
if (gray <= _Threshold) {
    discard;
}

_DisolveTexをグレースケールにして、_Threshold以下になったらレンダリングしないことで、溶けるような表現をしています。

MetallicとSmoothness

Metallicはオブジェクトの表面がどの程度、金属のようかを表現するものです。

soramamenatan.hatenablog.com

Smoothnessはオブジェクトの表面がどの程度、滑らかかを表現するものです。

soramamenatan.hatenablog.com

結果

f:id:soramamenatan:20190909193904g:plain

模様のように変化するようになりました。

ソースコードにコメントを付与

Shader "Custom/dissolve" {
    // プロパティ
    Properties {
        // 色
        _Color("Color", Color) = (1, 1, 1, 1)
        // メインテクスチャ
        _MainTex("MainTex", 2D) = "white" {}
        // 溶ける模様テクスチャ
        _DissolveTex("DissolveTex", 2D) = "white" {}
        // 滑らかさ
        _Glossiness("Glossiness", Range(0, 1)) = 0.5
        // 金属度
        _Metallic("Metallic", Range(0, 1)) = 0.0
        // しきい値
        _Threshold("Threshold", Range(0, 1)) = 0.0
    }

    // Shaderの中身を記述
    SubShader {
        // 一般的なShaderを使用
        Tags { "RenderType" = "Opaque"}
        // しきい値
        LOD 200

        // cg言語記述
        CGPROGRAM
        // フォワードレンダリング
        #pragma surface surf Standard fullforwardshadows
        // Shader Model
        #pragma target 3.0

        // メインテクスチャ
        sampler2D _MainTex;
        // 溶ける模様テクスチャ
        sampler2D _DissolveTex;

        // Input構造体
        struct Input {
            float2 uv_MainTex;
        };

        // 滑らかさ
        half _Glossiness;
        // 金属度
        half _Metallic;
        // しきい値
        half _Threshold;
        // 色
        fixed4 _Color;

        void surf(Input IN, inout SurfaceOutputStandard o) {
            fixed4 dissolveTex = tex2D(_DissolveTex, IN.uv_MainTex);
            // グレースケール
            half gray = dissolveTex.r * 0.3f + dissolveTex.g * 0.59f + dissolveTex.b * 0.11f;
            // しきい値以下の場合、レンダリングしない
            if (gray <= _Threshold) {
                discard;
            }
            fixed4 mainTex = tex2D(_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = mainTex.rgb;
            o.Alpha = mainTex.a;
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
        }
        // Shaderの記述終了
        ENDCG
    }
    // SubShaderが失敗した時に呼ばれる
    Fallback "Diffuse"
}

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

制作したオブジェクトに以下のScriptをアタッチ。

using UnityEngine;

public class Dissolve : MonoBehaviour {
    private float _threshold;

    void Update() {
        _threshold += 0.01f;
        var renderer = GetComponent<Renderer>();
        _threshold = Mathf.Clamp(_threshold, 0, 3);
        renderer.material.SetFloat("_Threshold", _threshold);
    }
}

Materialをコピペして、それぞれにTextureをアタッチ。

f:id:soramamenatan:20190909194833j:plainf:id:soramamenatan:20190909194835j:plain

【Unityシェーダ入門】Dissolve(溶けるような)シェーダをつくる - おもちゃラボ:より引用

f:id:soramamenatan:20190909203135g:plain

こんな感じになれば成功です。