5.計算機圖形學之 Shader 2.0 結構與語義
阿新 • • 發佈:2018-12-19
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 已經定義好的 頂點獲取資訊,無需在本類中再次定義)