1. 程式人生 > >【遊戲渲染】Unity&Shader基礎篇-Cg語法,資料型別與關鍵字

【遊戲渲染】Unity&Shader基礎篇-Cg語法,資料型別與關鍵字

1.2、Cg語法基礎

如C++、C#和Java等高階語言一樣,Cg語言也有自己的資料型別和關鍵字。掌握和理解這些關鍵字是寫好Cg程式的基礎。

1.2.1、Cg的資料型別與關鍵字

基本資料型別:Cg支援7種基本的資料型別

1、float,32位浮點資料,一個符號位。浮點資料型別被所有的圖形介面支援;

2、half,16位浮點資料;

3、int,32位整形資料

4,fixed,12位定點數,

5、bool,布林資料,被所有的圖形介面支援;

6、sampler*,紋理物件的控制代碼,分為sampler、sampler1D、sampler2D、sampler3D、samplerCUBE和samplerRECT。

內建的資料型別:基於基礎資料型別,如float3,表示float型別的三維向量;同理,bool2表示布林型別的二維向量。

注:向量最長不能超過四元,如float5  vector;//編譯錯誤

向量的賦值,float2 a=float(1.0,1.0);       //編譯通過

            float2 a=float(1.0f,1.0f);     //編譯錯誤

            float3 b=float(a,0.0);            //編譯通過

矩陣資料型別,float1X1 m1;                    //即float m1,一維矩陣

              float3X4 m34                    //3*4階矩陣

注:X是字元,不是乘號,最大的維數為4*4階

矩陣的初始化 float 2*2 m22={1.0,2.0,3.0,2.3};

float3 x和floatx[3]是不同的,前者為向量是內建的資料型別,而陣列則是一種資料結構,不是內建的資料型別。

型別轉換:Cg中的型別轉換有強制轉換和隱式轉換;如果是隱式轉換則資料型別從低精度向高精度轉換。如:

           float a=1.0;

           half b=2.0;

           float c=a+b;      //等價於float c=a+(float)b;

Cg語言中可以對常量資料加上型別字尾表示該資料型別的資料,如:

           float a=1.0h;     //1.0h為half型別常量資料

這樣的字尾型別有三種:

f:表示float;

h:表示half;

x:表示fixed;

Swizzle操作符:Cg語言中的其他操作符和高階CPU語言C++類似,包括關係操作符、邏輯操作符和位移操作符以及條件操作符。而Swizzle操作符是Cg語言中特有的,它可以將一個向量的成員取出組成一個新的向量。對於座標或者角度等其他多維向量,Swizzle操作符(.)後接x、y、z、w分別表示原始向量的第一個、第二個、第三個和第四個元素;同樣,對於顏色可以後接r、g、b和a來表示同樣的索引。

例如:

              float4(a,b,c,d).xwz  等價於 float(a,d,c)

              float4(a,b,c,d).xxy  等價於 float(a,a,b)

注:Swizzle操作符只對結構體和向量使用,不能對陣列使用。

輸入資料關鍵字:Cg中輸入資料流一般分為兩類

1、varying 引數:在Cg程式中通過語義進行繫結變數, Cg語言提供了一組語義詞,用以表示引數是由頂點的那些資料初始化的,一旦這個變數使用了語義詞進行繫結,那麼這個變數值被初始化的同時也意味著它有了特殊的含義,如表示位置、法線等含義。語義提供了一種使用隨頂點變化或隨片段變化而變化的值來初始化Cg程式引數的方法,這些資料都是從應用程式輸入到GPU的資料,如頂點位置、法向量、紋理座標資料等。

2、Uniform引數:Uniform是用來限制一個變數的初始值的來源,當宣告一個變數為Uniform型別的時候,表示這個變數的初始值來自於外部的其他環境。除了獲取初始值的這點之外,Uniform關鍵字宣告的變數和其他變數是完全一樣的。通常用Uniform來定義一些與三維渲染有關的離散資訊資料,並通常不會隨著圖元資訊的變化而變化,如材質對光的反射資訊。Uniform表示一個引數,通常使用uniform表示函式的形參,不能定義一個uniform表示的區域性變數。

Unity的內建Uniform輸入引數如下:

uniform float4 _Time, _SinTime, _CosTime; // 時間量

uniform float4 _ProjectionParams; // x = 1 or -1 (如果投影翻轉就是-1)

// y = 近平面; z = 遠平面; w = 1/遠平面

uniform float4 _ScreenParams; // x = width; y = height; z = 1 +1/width; w = 1 + 1/height

 uniform float3_WorldSpaceCameraPos;

uniform float4x4 _Object2World; //模型矩陣

uniform float4x4 _World2Object; // 模型矩陣的逆

uniform float4 _LightPositionRange; // xyz = pos, w = 1/range

uniform float4 _WorldSpaceLightPos0; // 光源的位置和方向

uniform float4x4 UNITY_MATRIX_MVP; // 模型檢視投影矩陣

uniform float4x4 UNITY_MATRIX_MV; // 模型檢視矩陣

uniform float4x4 UNITY_MATRIX_V; // 檢視矩陣

uniform float4x4 UNITY_MATRIX_P; // 投影矩陣

uniform float4x4 UNITY_MATRIX_VP; // 檢視投影矩陣

uniform float4x4 UNITY_MATRIX_T_MV; // 模型檢視矩陣的轉置矩陣

uniform float4x4 UNITY_MATRIX_IT_MV; // 模型檢視矩陣的逆矩陣的轉置矩陣

uniform float4x4 UNITY_MATRIX_TEXTURE0; // 貼圖紋理矩陣

uniform float4x4 UNITY_MATRIX_TEXTURE1; //貼圖紋理矩陣

uniform float4x4 UNITY_MATRIX_TEXTURE2; //貼圖紋理矩陣

uniform float4x4 UNITY_MATRIX_TEXTURE3; //貼圖紋理矩陣

uniform float4 UNITY_LIGHTMODEL_AMBIENT; // 環境色

這些變數在Unity中可以直接使用,本章第三節中將會展現如何在Unity中使用這些內建的Uniform變數。

1.2.2、輸入輸出和語義

    輸入輸出:在第一節中我們瞭解到對於程圖形渲染管線,可程式設計控制的部分只有兩個,頂點著色器和片段著色器。對於程式設計控制這兩個部分,首要的任務就是要怎麼給它們傳引數。Cg語言的引數傳遞同樣也有“值傳遞”和“引用傳遞”之分。因為GPU不支援指標,所以Cg語言採用瞭如下的方式來修辭引數傳遞:

1、in:修辭一個形參只是用於輸入,進入函式體時被初始化,且該形參值的改變不會影響實參值,傳遞方式為值傳遞。

2、out:修辭一個形參只是用於輸出,進入函式體時沒有被初始化,一般為函式的返回值。

3、inout:修辭一個形參即用於輸入也用於輸出,這是典型的引用傳遞。

語義:表示圖元資料的含義(頂點的位置、法向量或者紋理資訊),也表明這些圖元資料存放的硬體資源。因為頂點著色器的輸出即是片段著色器的輸入,所以頂點著色器的輸出必須和片段著色器的輸入語義是一致的。語義是頂點程式和片段程式之間輸入\輸出資料和暫存器之間的橋樑,因此語義只對這兩個處理階段有意義,並且只在入口函式才有效,在內部函式無效。語義概念的提出和圖形流水線工作機制大有關係。從前面所講的GPU處理流程中可以看出,一個階段處理資料,然後傳輸給下一個階段,那麼每個階段之間的介面是如何確定的呢?例如:頂點處理器的輸入資料是處於模型空間的頂點資料(位置、法向量),輸出的是投影座標和光照顏色;片段處理器要將光照顏色做為輸入,問題是“片段處理器怎麼知道光照顏色值的存放位置”。在高階語言中(C/C++),資料從介面的一端流向另一端,是因為提供了資料存放的記憶體位置(通常是指標資訊);由於Cg 語言並不支援指標機制,且圖形硬體處理過程中,資料通常暫存在暫存器中,故而在Cg 語言中,通過引入語義繫結(binding semantics)機制,指定資料存放的位置,實際上就是將輸入\輸出資料和暫存器做一個對映關係(在OpenGL Cg profiles 中是這樣的,但在DirectX-based Cgprofiles 中則並沒有這種對映關係)。根據輸入語義,圖形處理器從某個暫存器取資料;然後再將處理好的資料,根據輸出語義,放到指定的暫存器。

語義詞和語義繫結:Unity的頂點著色器(程式)中常用的語言詞有如下:

1、POSITION\SV_POSITION :模型座標的位置,

2、TANGENT:正交於表面法線的向量

3、NORMAL:表面法線向量,需要進行歸一化

4、TEXCOORDi:第i組紋理座標(也即UV座標,座標範圍在0~1之間),i是0~7中的一個數字

5、COLOR:顏色

6、PSIZE:點的大小

7、BLENDINDICES:通用屬性,可以用它和TANGENT來替換TEXCOORDi

注:SV_POSTION和POSTION的唯一區別是用在頂點著色器中作為輸出語義時,SV_POSTION表示的頂點位置會被固定,不能被改變。如果作為片段著色器的輸入語義就是一樣的,都可以被改變。

頂點著色器的輸出語義詞有:

1、COLOR:顏色

2、FOG:輸入霧座標

3、PSIZE

4、 POSITION

5、TEXCOORD0-TEXCOORD7

片段著色器的輸入語義即為頂點著色器的輸出語義。

片段著色器的輸出語義如下:

1、COLOR:顏色

2、DEPTH:片段的深度

語言繫結的三種方法:

1、繫結語義放在函式的引數列表的引數聲明後面中:

1 2 3 4 5 6 7 8 9 [const][in|out|inout|uniform][ :][=] void vert(float4 obj_position:POSITION, float4 obj_normal:NORMAL, out float4 outPos:POSITION, uniform float4 uColor:COLOR { ... }

其中,const作為可選項,const修飾符同C和C++語言裡的一樣,表示這個變數的值是不能改變的;in、out、inout作為可選項,說明資料的呼叫方式;

uniform也是可選項,表示變數的值的初始化是來自外部應用程式;type是必選項,宣告資料的型別;identifier是必選項,形參變數名:一個冒號“:”加上一個繫結語義,是可選項;最後是初始化引數,是可選項。

引數1、2、5繫結到輸入語義;引數3、4繫結到輸出語義;儘管引數1和3的繫結語義詞一樣,但前者是輸入語義,後者是輸出語義,所以這兩個引數資料所對應儲存的硬體位置是不一樣的。

2、繫結語義可以放在結構體的成員變數後面:
1 2 3 4 5 6 7 Struct<struct-tag> { [:binding-semantic>]; };。
JavaScript基礎上(變數,資料型別,操作符,流程控制)

一.JavaScript 1.JavaScript的書寫位置 -(1) 內嵌式js寫法 在head裡寫<script></script> -(2)行內式js寫法—不推薦使用,不利於html和js的分離 <!-- &

Redis:基礎——五種資料型別及分別對應的命令詳解

Redis支援五種資料型別:string(字串),hash(雜湊),list(列表),set(集合)及zset(sorted set:有序集合)。 String(字串) string 是 redis 最基本的型別。 特徵:一個 key 對應一個 value。   &nb

Python基礎(一)資料型別變數

注:本文的Python學習系列是筆者在學習廖雪峰老師的Python教程所記錄下的學習筆記,如果想了解更多Python系列的學習資料可以看看 廖雪峰 Python教程 人生苦短,我用Python! 這是我最早認識Python這門語言時聽到對它的一句概括。 從字面上

編輯器Unity視窗對焦切換和啟動遊戲

前言 做編輯器的時候有時會需要改變視窗的對焦。現在總結一下常用的切換視窗方法。還有就是編輯器模式下啟動遊戲。 效果 切換視窗對焦 啟動和暫停 思路 視窗類名應該和視窗名差不多,到UnityEditor的文件裡面去搜索關鍵字,看看有沒有有用的資訊 找不

shiro許可權框架——基礎

shiro是什麼 Apache Shiro是一個強大且易用的Java安全框架,有身份驗證、授權、密碼學和會話管理。使用Shiro的易於理解的API,您可以快速、輕鬆地獲得任何應用程式,從最小的移動應用程式到最大的網路和企業應用程式。 shiro的作用 Shiro 開發團隊稱為“應用程式的四

遊戲策劃遊戲架構設計策劃基礎》學習收穫要點-------遊戲規則設計

規則體系: (遊戲中相關規則不只下列這些規則) 世界相關規則 世界環境物品發生什麼樣的情況,會對玩家產生怎麼樣的影響 角色相關規則 角色在怎麼樣的情況下做什麼 角色等級設計(升級途徑,代價,獎勵) 角色物品欄(空間大小,物品型別,物品耐久屬性,物品有效時間等等)

MaterialPropertyDrawerunity Shader Material 面板美化

Description Base class to derive custom material property drawers from. Use this to create custom UI drawers for your material prope

Unity&Shader高階-渲染路徑(Rendering Paths)

一、前言 在Unity的Camera中常常會看到一個Rendering Paths的選項,裡面有5個選項,其中兩個比較重要的選項分別是“Deferred Shading”和“Forward Rende