Unity Shader學習筆記-1

本篇文章是對Unity Shader入門精要的學習筆記,插圖大部分來自馮樂樂女神的githubgit

若是有什麼說的不正確的請批評指正github

渲染流水線

流水線機制,拆分小段,前面的工序不用等後面的工序,流水線機制在計算機世界中常用,好比:TCP緩存

image-20200506201708690

流程圖

渲染管線函數

應用階段(開發者控制)、幾何階段(決定圖元)、光柵化階段(決定像素)性能

Shader做用

頂點着色器:實現頂點的空間變換,座標變換(模型空間轉換到齊次裁減空間)、逐頂點光照、計算頂點顏色學習

曲面細分着色器:細分圖元,圖元就是:點、線、面等渲染所需的幾何信息測試

幾何着色器:執行逐個圖元的着色操做,或者用於產生更多的圖元spa

片元着色器:逐片元的着色操做,修改顏色、深度緩衝、進行混合插件

屏幕映射

image-20200419105949276

三角形遍歷

​ 三角形設置:由定點信息計算出邊的信息3d

​ 三角形遍歷:計算是否在三角形內,使用與三條邊叉乘的方法判斷在邊的左邊或者右邊,遍歷3條邊的方式按照順時針或者逆時針,對應點在

​ 計算三角形內的數據:

​ 計算顏色:插值計算

兩大渲染測試

決定是否丟棄片元

  • 模板測試
    • 一般用於限制渲染的區域
    • 使用一個比較函數比較參考值和實際值
    • 高級用法:渲染陰影、輪廓渲染
  • 深度測試
    • 與深度緩衝區的深度值進行比較大於時捨棄該片元
    • 若是一個片元沒有經過深度測試那麼它就沒權力修改深度緩衝區
  • 二者的區別:除功能外,模板狀態設置更新即便捨棄了該片元也會更新模板緩衝區的值
    • image-20200419112316936
  • early-z的方法:提早進行深度測試,能夠幫助決定是否繪製片元,減小GPU開銷
    • image-20200419112924601

混合

合併顏色,顏色緩衝區,此次獲得的結果和存儲的結果進行合併

image-20200419112630907

CPU、GPU、圖形接口和驅動的關係

CPU和GPU之間的通訊

  • 數據加載到顯存(顯卡的內存,圖像緩衝、深度緩衝)

  • 設置渲染狀態

  • 調用DrawCall

    image-20200419113502454

CPU和GPU並行工做的祕密:命令緩衝區

  • 一個命令隊列,cpu給命令、gpu拿命令

  • drawcall就是一種命令,GPU的渲染速度很快,性能瓶頸主要是在CPU傳遞命令這方面

    • 減小drawcall的方法有不少,其中Batching批處理是很經常使用的方法,思路就是把小的drawcall合併成大的drawcall,適用於靜態的物體

      image-20200419114525719

顯示流暢的方法

  • Double Buffering:避免咱們看到正在渲染的片元
    • Front Buffer
      • 實際顯示的圖像
    • Back Buffer
      • 在後面渲染的圖像
    • 後置緩衝區渲染完成後交換兩緩衝區的值

着色器語言

用於編寫着色器的語言,主要是頂點着色器和片元着色器須要編寫

  • HLSL DirectX
    • 微軟控制的着色器編譯,各硬件編譯的結果相同
  • CG NVIDIA
    • 和HLSL很像,根據平臺的不一樣編譯成相應的中間語言
  • GLSL OpenGL
    • 依賴硬件來編譯,用顯卡驅動來編譯,各驅動的編譯結果根據硬件變化
  • 它們編譯成中間語言IL給顯卡驅動識別(這也是某種跨平臺的意思吧-。-)
  • ShaderLab unity的簡化語言,少了不少的配置流程,大部分流程是unity本身作

ShaderLab

Shader選用

摘取樂樂女神的指導

image-20200419121533003

通常用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;
			...
	}
}

頂點片元着色器 Unlit Shader

結構

命個名和shader在面板中的目錄

Shader "Custom/MyShader"    //名字

Properties

屬性,會出如今材質面板中

Properties{
	Name("display name",PropertyType) = DefaultValue
	//.......
}

Name:屬性的名字

display name:顯示的名字

PropertyType:類型

ps:shader裏改過了Property在C#腳本里並不能得到更改後的信息,只能得到預設的信息,GPU像CPU傳數據使用Compute Shader

數據類型

image-20200419120351348

2D、Cube、3D是三種紋理類型,默認值是一個字符串+{},字符串是內置的紋理名稱

SubShader

unity掃描全部的SubShader塊找到可以在目標平臺上運行的SubShader,若是找不到就使用Fallback提供的Unity Shader

SubShader
{
	[Tags]//標籤
	[RenderSetup]//狀態
	
	Pass{
	}//完整的渲染流程
	//Other Pass
}

顯卡狀態,在Pass裏寫的,剔除、深度、混合

image-20200419121013508

怎麼樣以及什麼時候渲染該對象,渲染隊列最重要

image-20200419121145597

Pass

表示渲染流程,一個Pass表示經過管線一次,能夠寫頂點着色器和片元着色器

image-20200419121242075

UsePass可使用其餘Unity Shader的Pass,以提高複用性(用法:指明路徑,而且Pass要有Name)

image-20200419121423098

LightMode在有光照信息時讀取光源的信息使用,主要是肯定光源位置等

一個簡單的Shader
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信息

image-20200419193635194

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來覆蓋深度緩衝區,不過官方說吃性能

庫文件

image-20200419182140630

image-20200419182149720

image-20200419182201995

調試

一、假彩色圖像,把數據做爲顏色輸出到屏幕上而後用取色器查看的數值調試法。

沒辦法,渲染管線裏的數據不是想拿就拿的,讓你隨便拿了管線不至關於開了個洞,像素都漏了

二、幀緩衝區調試,Frame Debugger

三、VS插件ShaderLab補全,體驗通常,甚至不想開

注意點

GPU結構決定它不擅長處理選擇、循環等結構的程序,分支下的代碼、分支的層數要儘量少由於他會下降GPU的並行處理操做,條件變量最好是常數

3D數學

太多了,很差寫,基礎知識看看樂樂老師的書吧0.0

空間

各類空間關係一開始搞不太懂也沒事,後面能夠在實踐中慢慢理解

這塊樂樂老師的書上講的牛的點變換推導很詳細

模型空間:也叫對象空間、局部空間

世界空間:絕對位置,一個Transform沒有父節點他的位置就是絕對位置

觀察空間:攝像機空間,模型空間的特例

  • 攝像機右手系
    • image-20200419162537284
    • 觀察變換:投影變換

裁剪空間:clip space 裁剪矩陣,有一個視錐體決定攝像機能夠看到的空間

  • 投影矩陣的本質就是對xyz份量進行不一樣程度的縮放

屏幕空間

  • 降維2d座標
  • 進行齊次除法
  • 透視出發轉化到NDC歸一化的設備座標

image-20200419164146168

unity座標旋向性

image-20200419164204739

相關文章
相關標籤/搜索