在游戲的開發過程中,程序員不太會自己去寫shader,因為寫起來很麻煩,而且只有Unity會報錯,編譯器也沒有什么提示。
通常是拿別人的shader改一改,當然,程序員還是要能看懂和會一點shader
Unity坐標系轉換
1: transform.localToWorldMatrix 局部轉世界的矩陣;
2: transfrom.worldToLocalMatrix 世界坐標轉局部坐標矩陣;
MultiplyPoint, MultiplyPoint3x4 MultiplayVector 來進行坐標變換;
4: shader中 左乘_World2Object矩陣來實現世界坐標轉局部坐標變換;
5: shader中左乘_Object2World矩陣來實現局部轉世界的轉換;
6: UNITY_MATRIX_MV 基本變換矩陣 x 攝像機矩陣;
7: UNITY_MATRIX_MVP 基本變換矩陣x攝像機矩陣x投影矩陣;
8: UNITY_MATRIX_V 攝像機矩陣;
9: UNITY_MATRIX_P 投影矩陣;
10: UNITY_MATRIX_VP攝像機矩陣x投影矩陣;
11: UNITY_MATRIX_T_MV (基本變換矩陣 x 攝像機矩陣) 轉置矩陣;
12: UNITY_MATRIX_IT_MV(基本變換矩陣 x 攝像機矩陣) 的逆轉置矩陣;
13: UNITY_MATRIX_TEXTURE0 紋理變化矩陣;
GPU管道流水線
1: 主要的運算在GPU上計算,CPU插入指令;
2: 大致流程:
頂點着色器和片元着色器
1: 控制靈活,但不能參與光照計算;
2: 在着色器中插入Cg代碼段,編寫在CGPROGRAM 與 ENDCG之間;
3: 編譯指令: #pragma控制 着色器代碼編譯。每一個Shader都有入口函數
#pragma vertex name 將名稱為name的函數編譯為頂點着色器;
#pragma fragment name 將名稱為name的函數編譯為片元着色器;
4: 參數和返回值有語義修飾
常用語義修飾
1:POSITION : 位置
2:TANGENT : 切線
3: NORMAL: 法線
4: TEXCOORD0: 第一套紋理
5: TEXCOORD1: 第二套紋理
6: TEXCOORD2: 第三套紋理
7: TEXCOORD3: 第四套紋理
8: COLOR: 顏色
Shader實例
1.創建好Unity工程目錄
2.創建一個Cube物體
3.在resources文件夾下創建一個shaders文件夾
4.進入shaders,create---->Shader---->Standard Surface Shader---->重命名MyShader
5.打開MyShader
Shader "Custom/MyShader" { // 綁定到編輯器上去, shader程序里面可以使用; 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 { Pass { CGPROGRAM // 插入我們的Cg代碼段開始標志 // 指定哪段代碼是頂點shader,把my_vertex作為頂點shader的入口 #pragma vertex my_vertex // : 語義說明,怎么獲得上一個工位的參數---->語義bind,告訴上一個工位我需要position參數,那么上一個工位就會給我們傳這個參數,這里就可以使用 float4 my_vertex(float4 v : POSITION) : POSITION { return mul(UNITY_MATRIX_MVP, v); } // 指定哪段代碼是片元着色shader #pragma fragment my_frag fixed4 my_frag() : COLOR{ return fixed4(1.0, 0, 0, 1.0); } ENDCG // 插入我們的Cg代碼段結束標志 } } FallBack "Diffuse" }
6.在shaders文件夾下創建一個材質Material,命名為MyShader
7.在材質球的右上角的shader選項選擇Custom---->MyShader
8.把材質球拖進Cube的材質屬性里面
注意:
每個Shader有輸入和輸出,盒子有對應幾個函數,函數有輸入參數外加返回值的輸出。