夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

UnityでShaderを勉強する その④ テクスチャを扱うShaderを書く

本日はShader勉強枠です。 前回UnityのレファレンスからDiffuse SimpleShaderを見ていきました。

redhologerbera.hatenablog.com

今回からDiffuse SimpleShaderを編集し、学んでいきます。

〇Diffuse SimpleShader

  Shader "Example/Diffuse Simple" {
      SubShader {
        Tags { "RenderType" = "Opaque" }
        CGPROGRAM
        #pragma surface surf Lambert
        struct Input {
            float4 color : COLOR;
        };
        void surf (Input IN, inout SurfaceOutput o) {
            o.Albedo = 1;
        }
        ENDCG
      }
      Fallback "Diffuse"
    }

〇テクスチャを扱う

 Unityではオブジェクトに写真やイラストなどのテクスチャを表示させる場合マテリアルにアタッチすることで実現しています。

 マテリアルはShaderに基づきプロパティを表示しているので、Diffuse Simple Shaderはテクスチャを扱う記述がなくそのままではテクスチャを使用できません。

 f:id:Holomoto-Sumire:20200409100713j:plain

 ShaderLabの書き方を復習します。

Shader "MyShader" {
    Properties {
   C#におけるPublicクラスのように、ここに記述されたプロパティはUnityのマテリアルで扱うことができます。
    }
    SubShader {
  実際の処理が記述されます。
    }
}

redhologerbera.hatenablog.com

 Properties構造体に記述することでUnityのマテリアルで扱うことができます。

       Shader "Example/Diffuse Simple" {
      Properties {
        _MainTex ("Texture", 2D) = "white" {}
      }
      SubShader {
        Tags { "RenderType" = "Opaque" }
        CGPROGRAM
        #pragma surface surf Lambert
        struct Input {
            float4 color : COLOR;
        };
        void surf (Input IN, inout SurfaceOutput o) {
            o.Albedo = 1;
        }
        ENDCG
      }
      Fallback "Diffuse"
    }

とDiffuse SimpleShaderを書き換えました。

追加した部分は

 Properties {
        _MainTex ("Texture", 2D) = "white" {}
      }

になります。

このようにすることで

f:id:Holomoto-Sumire:20200409101408j:plain

Unity側でテクスチャを扱えるようになります。

 _MainTex("マテリアルでの表示名",2D)= "white"{}

と記述することでテクスチャを持たせることができるようです。

f:id:Holomoto-Sumire:20200409101740j:plain

 早速マテリアルのTextureに画像を設定しましたが、Cubeに反映されません。

 それもそのはずで、受け皿を作ったものの処理を記述していないためです。

 UnityC#でいうと

public class NewBehaviourScript : MonoBehaviour
{
 public Texture texture; 
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

のような状態です。

処理を記述します。

Shader "Example/Diffuse Simple" {
    Properties{
       _MainTex("Texture", 2D) = "white" {}
    }

    SubShader{
      Tags { "RenderType" = "Opaque" }
      CGPROGRAM
      #pragma surface surf Lambert
      struct Input {
          float4 color : COLOR;
          float2 uv_MainTex;
      };
    sampler2D _MainTex;
      void surf(Input IN, inout SurfaceOutput o) {
          o.Albedo = 1;
          o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
      }
      ENDCG
    }
        Fallback "Diffuse"

追加した部分は次になります。

 struct Input {
          float4 color : COLOR;
          float2 uv_MainTex;
      };

Input構造体では使用するテクスチャ情報を記述します。 _MainTexをuvとして使用することを記述します。

sampler2D _MainTex 

プロパティで受け取ったデータをシェーダ内で扱うための定義です。 テクスチャの場合は、sampler2Dです。

   void surf(Input IN, inout SurfaceOutput o) {
          o.Albedo = 1;
          o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
      }

最後に処理をしています。

ここではAlbedoにテクスチャのRGBを使用する処理を行っています。

これによってテクスチャが使用できました。

f:id:Holomoto-Sumire:20200409102954j:plain

 これをきれいにしたものが次になります。

  Shader "Example/Diffuse Texture" {
      Properties {
        _MainTex ("Texture", 2D) = "white" {}
      }
      SubShader {
        Tags { "RenderType" = "Opaque" }
        CGPROGRAM
        #pragma surface surf Lambert
        struct Input {
            float2 uv_MainTex;
        };
        sampler2D _MainTex;
        void surf (Input IN, inout SurfaceOutput o) {
            o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
        }
        ENDCG
      } 
      Fallback "Diffuse"
    }

ColorはTextureのRGBで処理されることになったのでオミットしています。

以上でテクスチャを扱うShaderが完成しました。