本篇文章是對Unity Shader入門精要的學習筆記,插圖大部分來自馮樂樂女神的githubgit
若是有什麼說的不正確的請批評指正github
流水線機制,拆分小段,前面的工序不用等後面的工序,流水線機制在計算機世界中常用,好比:TCP緩存
渲染管線函數
應用階段(開發者控制)、幾何階段(決定圖元)、光柵化階段(決定像素)性能
頂點着色器:實現頂點的空間變換,座標變換(模型空間轉換到齊次裁減空間)、逐頂點光照、計算頂點顏色學習
曲面細分着色器:細分圖元,圖元就是:點、線、面等渲染所需的幾何信息測試
幾何着色器:執行逐個圖元的着色操做,或者用於產生更多的圖元spa
片元着色器:逐片元的着色操做,修改顏色、深度緩衝、進行混合插件
三角形設置:由定點信息計算出邊的信息3d
三角形遍歷:計算是否在三角形內,使用與三條邊叉乘的方法判斷在邊的左邊或者右邊,遍歷3條邊的方式按照順時針或者逆時針,對應點在
計算三角形內的數據:
計算顏色:插值計算
決定是否丟棄片元
合併顏色,顏色緩衝區,此次獲得的結果和存儲的結果進行合併
數據加載到顯存(顯卡的內存,圖像緩衝、深度緩衝)
設置渲染狀態
調用DrawCall
一個命令隊列,cpu給命令、gpu拿命令
drawcall就是一種命令,GPU的渲染速度很快,性能瓶頸主要是在CPU傳遞命令這方面
減小drawcall的方法有不少,其中Batching批處理是很經常使用的方法,思路就是把小的drawcall合併成大的drawcall,適用於靜態的物體
用於編寫着色器的語言,主要是頂點着色器和片元着色器須要編寫
摘取樂樂女神的指導
通常用CG/HLSL代碼寫: CG代碼和DX9的HLSL代碼幾乎同樣,要在CGPROGRAM中寫,CGPROGRAM要使用上面的Property的數據就要聲明和上面Property同樣名字同樣類型的變量,若是不想在多個Pass裏聲明,則能夠在Pass前的CGINCLUDE ... ENDCG之間聲明變量,這樣的Property是多Pass共用的
Properties{ _Color("Color Tint", Color) = (1, 1, 1, 1) } SubShader{ Pass{ ... fixed4 _Color; ... } }
命個名和shader在面板中的目錄
Shader "Custom/MyShader" //名字
Properties
屬性,會出如今材質面板中
Properties{ Name("display name",PropertyType) = DefaultValue //....... }
Name:屬性的名字
display name:顯示的名字
PropertyType:類型
ps:shader裏改過了Property在C#腳本里並不能得到更改後的信息,只能得到預設的信息,GPU像CPU傳數據使用Compute Shader
數據類型
2D、Cube、3D是三種紋理類型,默認值是一個字符串+{},字符串是內置的紋理名稱
SubShader
unity掃描全部的SubShader塊找到可以在目標平臺上運行的SubShader,若是找不到就使用Fallback提供的Unity Shader
SubShader { [Tags]//標籤 [RenderSetup]//狀態 Pass{ }//完整的渲染流程 //Other Pass }
顯卡狀態,在Pass裏寫的,剔除、深度、混合
怎麼樣以及什麼時候渲染該對象,渲染隊列最重要
Pass
表示渲染流程,一個Pass表示經過管線一次,能夠寫頂點着色器和片元着色器
UsePass可使用其餘Unity Shader的Pass,以提高複用性(用法:指明路徑,而且Pass要有Name)
LightMode在有光照信息時讀取光源的信息使用,主要是肯定光源位置等
Shader "Unlit/Chapter5SimpleShader" { SubShader { //選擇不聲明任何材質屬性 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag//編譯指令 //哪一個函數包括了頂點着色器的代碼 //哪一個函數包括了片元着色器的代碼 #include "UnityCG.cginc"//調庫,你的unity目錄\Editor\Data\CGIncludes struct a2v { float4 vertex :POSITION; float3 normal:NORMAL; float4 texcoord:TEXCOORD0; }; float4 vert(a2v v) :SV_POSITION{ return UnityObjectToClipPos(v.vertex); }//接受頂點座標(POSITION)返回了頂點在裁剪座標的位置(SV_POSITION) float4 frag() : SV_Target{ return fixed4(1.0,1.0,0.0,1.0); }//SV_Target告訴渲染器把用戶的輸出顏色存儲到一個渲染目標中,這裏是幀緩存 ENDCG } } }
POSITION、NORMAL、TEXTCOORD0等都稱爲語義semantic,在結構體裏的表示把提取到的信息當成一個什麼對待,輸出語義表示輸出的結果是做爲何對待
POSITION頂點位置,在模型空間,NORMAL頂點法向量,也是模型空間,TEXTCOORD0表示紋理座標,按理說紋理座標只要uv,2維就能夠了,可是有時好比天空盒的紋理須要用到3維的信息,一張紋理圖有時前兩維給一些信息,後兩維又給一張圖的uv信息
vert裏的輸出語義沒有也能夠,能夠選擇輸出結構體
struct a2v { float4 vertex : POSITION; float2 texcoord0 : TEXCOORD0; }; ... v2f vert(a2v i) { v2f o; o.pos = UnityObjectToClipPos(i.vertex); o.uv = i.texcoord0; return o; } ...
在frag裏的SV_Target表示屏幕上的像素(幀緩衝),還能夠輸出SV_Depth來覆蓋深度緩衝區,不過官方說吃性能
一、假彩色圖像,把數據做爲顏色輸出到屏幕上而後用取色器查看的數值調試法。
沒辦法,渲染管線裏的數據不是想拿就拿的,讓你隨便拿了管線不至關於開了個洞,像素都漏了
二、幀緩衝區調試,Frame Debugger
三、VS插件ShaderLab補全,體驗通常,甚至不想開
GPU結構決定它不擅長處理選擇、循環等結構的程序,分支下的代碼、分支的層數要儘量少由於他會下降GPU的並行處理操做,條件變量最好是常數
太多了,很差寫,基礎知識看看樂樂老師的書吧0.0
各類空間關係一開始搞不太懂也沒事,後面能夠在實踐中慢慢理解
這塊樂樂老師的書上講的牛的點變換推導很詳細
模型空間:也叫對象空間、局部空間
世界空間:絕對位置,一個Transform沒有父節點他的位置就是絕對位置
觀察空間:攝像機空間,模型空間的特例
裁剪空間:clip space 裁剪矩陣,有一個視錐體決定攝像機能夠看到的空間
屏幕空間
unity座標旋向性