1. 程式人生 > >Unity Shader 自定義SurfaceShader

Unity Shader 自定義SurfaceShader

這裡只做記錄用,不進行詳細的講解。

Shader "Custom/SurfaceShader" {
	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
	}
	SubShader {

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

		//SurfaceOutputStandard 結構體定義在這個cginc檔案內
		#include "UnityPBSLighting.cginc"
		
		//-----------------------------重要內容
		#pragma surface surf PBSLighting vertex:vert finalcolor:final fullforwardshadows

		#pragma target 3.0

		sampler2D _MainTex;

		//自定義
		struct Input {
			float4 vertColor;
			float2 uv_MainTex;
		};

		half _Glossiness;
		half _Metallic;
		fixed4 _Color;

		//自定義的定點處理方法
		void vert(inout appdata_full v,out Input o)
		{
			//這句話必須要有,用來對o進行初始化
			UNITY_INITIALIZE_OUTPUT(Input,o);
			o.vertColor = v.color;
		}

		UNITY_INSTANCING_CBUFFER_START(Props)
		
		UNITY_INSTANCING_CBUFFER_END
		
		//自定義的啥啥啥
		void surf (Input IN, inout SurfaceOutputStandard o) {

		}

		//自定義的光照方法
		inline half4 LightingPBSLighting (SurfaceOutputStandard s, half3 viewDir, fixed atten)
		{
			return float4(1,1,0,0);
		}

		//自定義的最終處理方法
		void final(Input IN, SurfaceOutputStandard o,inout fixed4 color)
		{
			
		}

		ENDCG
	}
	FallBack "Diffuse"
}


如果要看SurfaceShader的詳細講解,可以看這個帖子:

不同的是,馮同學的這篇帖子時間比較久了,用的是SurfaceOutput,unity有了物理渲染以後,就成了SurfaceOutputStandard,舊版的這個結構體是定義在Lighting.cginc檔案裡,新版的是定義在UnityPBSLighting.cginc檔案中。所以,如果使用了自定義的光照方法,但是又要使用SurfaceOutputStandard結構體,就需要對這個檔案設定引用。當然也可以自定義一個結構體。

還有關於馮同學說的四個方法兩個結構體,並不準確,與UnlitShader 一樣 vertex方法的傳入引數也可以自定義。

SurfaceShader在編譯時,還是轉換成了UnlitShader,前者與後者的對應關係為:

vertex <=> vertex

(surf+lighting+finalcolor)<=> fragment

可以通過轉換後的程式碼去驗證一下。