本日はShader勉強枠です。 前回UnityのレファレンスからDiffuse SimpleShaderを見ていきました。
今回から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はテクスチャを扱う記述がなくそのままではテクスチャを使用できません。
ShaderLabの書き方を復習します。
Shader "MyShader" { Properties { C#におけるPublicクラスのように、ここに記述されたプロパティはUnityのマテリアルで扱うことができます。 } SubShader { 実際の処理が記述されます。 } }
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" {} }
になります。
このようにすることで
Unity側でテクスチャを扱えるようになります。
_MainTex("マテリアルでの表示名",2D)= "white"{}
と記述することでテクスチャを持たせることができるようです。
早速マテリアルの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を使用する処理を行っています。
これによってテクスチャが使用できました。
これをきれいにしたものが次になります。
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が完成しました。