めーぷるのおもちゃばこ

- アイドルになりたいエンジニア女子の制作日記 -

【Unity】サーフェスシェーダでポリゴンの裏表両面にテクスチャを貼る

Unityでプレーンの両面に別のテクスチャを貼りたいときに、検索してみるとUnlitシェーダーを使ったものが多くでてきたのですが、

影もおとしたい!ってなったときのためにサーフェスシェーダで両面に別テクスチャを貼る方法をご紹介します。




f:id:maplesyrup-cs6:20190122221653p:plain
裏と表で違うテクスチャを貼る
 

いま流行りのあいつらです。1つのプレーンの裏表で別のテクスチャを貼ったうえで、さらに画像の透過部分をカットしています。

シェーダーをつくる

Unityのプロジェクトウィンドウで右クリックし、Create→Shader→Standard Surface Shaderを選択します。
名前はreversibleとかにしておきましょう。
以下のコードを書き込みます。

Shader "Custom/reversible" {

    Properties{
        _Color("Color", Color) = (1,1,1,1)
        _MainTex("Albedo (RGB)", 2D) = "white" {}
        _Glossiness("Smoothness", Range(0,1)) = 0.5
        _Metallic("Metallic", Range(0,1)) = 0.0
        _Alpha("Alpha",Range(0,1.0)) = 1.0
        _BackMainTex("Albedo (RGB)", 2D) = "white" {}
        Cutoff("Cutoff", Range(0,1)) = 0.5
    }

 

    SubShader{
        Tags { "RenderType"="Transparent" "Queue"="Transparent"}
        Blend SrcAlpha OneMinusSrcAlpha
        LOD 200
        Cull Front

        CGPROGRAM


    #pragma surface surf Standard alpha:fade

 
    struct Input {

        float2 uv_MainTex;   
        float3 worldNormal;INTERNAL_DATA

    };


    half _Glossiness;

    half _Metallic;

    fixed4 _Color;

    uniform float _Alpha;

    sampler2D _MainTex;


    void surf(Input IN, inout SurfaceOutputStandard o) {

        fixed4 mainTex = tex2D(_MainTex, IN.uv_MainTex)*_Color;

        o.Albedo = mainTex.rgb;

        o.Normal =float3(0,0,-1);

        o.Alpha = mainTex.a*_Alpha;

    }

ENDCG

  
    Cull Back

    CGPROGRAM

    #pragma surface surf Standard alpha:fade
    #pragma target 3.0

    struct Input {

        float2 uv_MainTex;

    };


    half _Glossiness;

    half _Metallic;

    fixed4 _Color;

    uniform float _Alpha;

    sampler2D _BackMainTex;

 
    void surf(Input IN, inout SurfaceOutputStandard o) {

        fixed4 backmainTex = tex2D(_BackMainTex, IN.uv_MainTex)*_Color;

        o.Albedo = backmainTex.rgb;

        o.Alpha = backmainTex.a*_Alpha;

    }

ENDCG

}
FallBack "Transparent/Cutout/Diffuse"
}


コードが書けたら、Unityのプロジェクトウィンドウで右クリックし、Create→Materialで新規マテリアルを作成します。
ヒエラルキーウィンドウでCreate→3D Object→PlaneでPlaneを作成し、先ほど作ったマテリアルをドラッグアンドドロップでPlaneにつけます。
ヒエラルキーのマテリアルのところでテクスチャが二つ設定できるので裏と表のテクスチャをそれぞれ設定してください。

f:id:maplesyrup-cs6:20190124001631p:plain
テクスチャの設定
これで裏表に別々のテクスチャが貼られました。透過部分がある画像は切り抜かれていると思います。
f:id:maplesyrup-cs6:20190124000159g:plain
完成図

解説

まず、SubShader{}の中で

Cull Front

を指定することで、表面は描画せずに裏面のみを描画します。
Cullはカリングといってポリゴンのどちら側を「描画しない」か制御することを言います。
この場合、Front面をCull(描画しないを)するので、裏面が描画されます。
また、裏面の描画なのですが、Planeの法線は反対向きになっているので、

o.Normal =float3(0,0,-1);

で法線を反対にしてあげます。これを書かないと法線が反対のままなのでライティングが反映されません。

次に、表面の描画です。

Cull Back

を指定することで「裏面を描画しない」をするので、表面のみが描画されます。


そして表と裏のテクスチャをインスペクタから設定できるように、Properties{}の中で、

_MainTex("Albedo (RGB)", 2D) = "white" {}

_BackMainTex("Albedo (RGB)", 2D) = "white" {}

の二つを記載しています。


また、画像の透明部分に対応できるようにTransparentの設定をしています。これで画像が切り抜かれます。

Tags { "RenderType"="Transparent" "Queue"="Transparent"}
Blend SrcAlpha OneMinusSrcAlpha


最後のFallBackで

FallBack "Transparent/Cutout/Diffuse"

を指定してあげることで、透過で切り抜かれた形に影が映ります。

f:id:maplesyrup-cs6:20190124011723p:plain
切り抜かれた影

この部分を、

FallBack "Diffuse"

にすると影が画像の形のままになってしまうので注意です。

f:id:maplesyrup-cs6:20190124011943p:plain
そのままの影


以上です!流行りはすぐ廃れますが私はこのニンジン結構好きです。
f:id:maplesyrup-cs6:20190124000159g:plain