1. 程式人生 > >5.計算機圖形學之 Shader 2.0 結構與語義

5.計算機圖形學之 Shader 2.0 結構與語義

Shader1.0 和 Shader2.0 的區別:

不同點: 2.0 可以實現程式設計 相同點: 渲染管線一樣

Shader 2.0 編寫詳解:

Shader "Hidden/NewImageEffectShader"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
	}
	SubShader
	{
		// No culling or depth
		Cull Off ZWrite Off ZTest Always

		Pass
		{
			CGPROGRAM
			#pragma vertex vert        //定義一個頂點著色器的 入口函式
#pragma fragment frag //定義一個片段著色器的 入口函式 #include "UnityCG.cginc" //引入一個cg庫 // 自定義 一個頂點獲取資訊 struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; // 定義一個返回頂點獲取資訊 struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; // 頂點著色器入口
v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); //mul(UNITY_MATRIX_MVP, v.vertex); 這是把頂點從模型空間轉換到裁剪空間,不用我們手動變換空間了,不過這在unity5.6中已經改為:UnityObjectToClipPos(v.vertex); 在UnityShaderUtilities.cginc裡,注意5.6以上版本才有這個檔案。官方實現如下: //Tranforms position from object to homogenous space
//inline float4 UnityObjectToClipPos(in float3 pos) //{ // More efficient than computing M*VP matrix product // return mul(UNITY_MATRIX_VP, mul(unity_ObjectToWorld, float4(pos, 1.0))); //} //可以看出也是先轉到世界空間,再乘以觀察和投影矩陣,只不過註釋那裡很清楚,更高效一些。 o.uv = v.uv; return o; } sampler2D _MainTex; // 片段著色器入口 fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.uv); // just invert the colors col.rgb = 1 - col.rgb; return col; } ENDCG } } }

pragma 關鍵字 vertex 關鍵字 fragment 關鍵字 vert 變數名 frag 變數名 include 關鍵字

頂點著色器的 入口函式:v2f vert (appdata v) appdata : 從 meshrender 裡面獲取來的 v2f : 頂點著色器的輸出值;片段著色器的輸入值。

片段著色器的 入口函式:fixed4 frag (v2f i) : SV_Target SV_Target:表示輸出到哪個相機上去。

語義: POSITION: 獲取模型頂點的資訊。 NORMAL: 獲取法線資訊。 TEXCOORD (n): 也稱UV,高精度的 從 頂點傳遞資訊 到 片段著色器。(float2,float3 or float4) COLOR: 表示低精度 從頂點傳遞資訊 到 片段著色器。(float4) TANGENT : 獲取切線資訊。 SV_POSITION: 表示 已經經過 mvp 矩陣 轉換到 螢幕座標的位置。 SV_TARGET: 輸出到 哪個 render target。

頂點著色器 從 fbx 獲取 資訊(Unity 預設定義好的幾個頂點著色器獲取資訊):

struct appdata_base 
{
 float4 vertex:POSITION;
float3 normal: NORMAL;
float4 texcoord:TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};

struct appdata_tan
{
float4 vertex:POSITION;
float4 tangent:TANGENT;
float3 normal: NORMAL;
float4 texcoord:TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};

struct appdata_full
{
float4 vertex:POSITION;
float4 tangent:TANGENT;
float3 normal: NORMAL;
float4 texcoord:TEXCOORD0;
float4 texcoord1:TEXCOORD1;
float4 texcoord2:TEXCOORD2;
float4 texcoord3:TEXCOORD3;
fixed4 color: COLOR;
UNITY_VERTEX_INPUT_INSTANCE_ID
};

v2f vert (appdata_base v)  // ( 這麼用的是Unity 已經定義好的 頂點獲取資訊,無需在本類中再次定義)