HLSL
高階著色器語言(High Level Shader Language,簡稱HLSL),由微軟擁有及開發的一種語言,HLSL 獨立的工作在 Windows 平臺上,只能供微軟的Direct3D使用。 HLSL是微軟抗衡GLSL的產品,同時不能與OpenGL標準兼容。
GLSL
OpenGL著色語言(OpenGL Shading Language)是用來在OpenGL中著色編程的語言,也即開發人員寫的短小的自定義程序,他們是在圖形卡的GPU (Graphic Processor Unit圖形處理單元)上執行的,代替了固定的渲染管線的一部分,使渲染管線中不同層次具有可編程性。
CG
GPU語言
由于GPU采用不同于CPU的運行運算結構,因此需要一種適用于GPU的編程語言。
1、微軟基于Direct3D圖形庫的HLSL(High Level Shading Language)
2、OpenGL ARB定義基于OpenGL圖形庫的GLSL(OpenGL Shading Language)
3、NVIDIA(英偉達)與微軟合作研發的Cg(C for Graphics).
Cg能夠同時兼容Direct3D和OpenGL圖形接口。
Unity所有的渲染都需要shader來完成,內置的著色器超過80個,可以輕松利用其內置的著色器來完成各種畫面效果,并且還提供了自定義shader,方便擴展。Unity使用shaderLab開發語言來組織shader內容,并會針對不同的平臺進行編譯,類似微軟的FX文件或者NAIDIA的CgFX.
Shader,可以分為VertexShader 和PixelShader/FragmentShader兩部分,簡稱VS,PS。學名頂點著色器和像素著色器。一旦你使用了VS和PS,則渲染過程會將VB(頂點緩沖)的數據按照IB索引(頂點索引緩沖)將每個頂點結構值分量傳入VS,VS進行相應的計算和頂點變化,并將VS返回的結果再交由PS進行像素著色,輸出相應的圖像。概念上來說 FragmentShader會比PixelShader大很多..
這兩個東西由于DX用PixelShader的緣故,其實是一個東西
Unity中可以編寫3種不同的著色器:表面著色器(Surface Shader)、頂點和片段著色器(Vertex and Fragment Shaders)和固定功能管線著色器(Fixed Function Shaders).
Unity5.0,內建了基于物理渲染的StandardShader,同時還引入了完全延遲著色(FullDeferredRendering)和烘焙反射探頭(Baked Reflection Probes)用于以真實環境為基礎的鏡面高光
物理著色:PBS (physically Based Shading):新的工業標準,用于電影產品
遵從了Conservation of Energy(能量守恒定律),只有這樣才能夠正真讓場景里面的光源依據能量傳遞的方式,產生一種自然和諧的光照效果。
Standard Surface Shader (Instanced):標準表面材質(實例化)
Unlit Shader:未點燃的材質
Image Effect Shader:圖像效果材質
Compute Shader:計算著色器
Shader Variant Collection:著色器變量集合
內建Shader介紹
4.X版本提供超過80個內建Shader、包括頂點光照效果到高光、發現、反射等游戲常用的材質效果。
內建Shader分類:
普通(Normal):用于不透明對象
透明(Transparent):用于半透明和全透明對象
透明鏤空效果(TransparentCutOut):用于完全透明和完全不透明部分組成(不含半透明部分)的對象,像柵欄一樣。
自發光(Self-llluminated shader Family):用于能反射環境立方體貼圖的不透明對象
反射(Reflective Shader Family):用于能反射環境立方體貼圖的不透明對象
每個類別下包含若干復雜性各異的shader
以光照效果計算開銷從低到高排序:
Unlit : 僅使用紋理,不受光照影響
VertexLit:頂點光照
Diffuse:漫發射
Specular: 在漫反射基礎上增加高光計算
Nomal Mapped : 法線貼圖,增加了一張法線貼圖和幾個著色器指令。
Nomal Mapped Specular : 帶高光法線貼圖
Parallax Nomal Mapped : 視差法線貼圖,增加了視差貼圖計算開銷
Parallax Nomal Mapped :帶高光視差法線貼圖
5.X版本新增加了一種基于物理著色的內建著色器,即StandardShader(標準著色器)
物理著色:PBS (physically Based Shading):新的工業標準,用于電影產品
遵從了Conservation of Energy(能量守恒定律),只有這樣才能夠正真讓場景里面的光源依據能量傳遞的方式,產生一種自然和諧的光照效果。
StandardShader是基于物理的著色器,也就是說不管你選擇什么樣的貼圖都會與光照產生反應,這些貼圖可以是同一張圖片,Unity會使用必要的資源進行計算。
原理:
遵從了Conservation of Energy(能量守恒定律),只有這樣才能夠正真讓場景里面的光源依據能量傳遞的方式,產生一種自然和諧的光照效果。
表面反射的光線不會比它們收到的更多
光滑的表面會有更強的反射
醋糟的表面反射會更弱一些
高光強度會隨著漫反射的強度而改變
所有的表面從某一特定角度看上去會有或多或少的高光
所有的表面在掠射角會有更多的反射
編寫自己的Shader(詳細解答Shader的各種屬性及用法)
Shader "Custom/firstsharder" {//這里是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 {
//表面著色器可以被若干的標簽(tags)所修飾
//硬件將通過判定這些標簽來決定什么時候調用該著色器
//標簽 可選
Tags
{
"Queue" = "Opaque"http://渲染順序
//Background--最早被調用的渲染,用來渲染天空盒或者背景
//Geometry--默認值,用來渲染非透明物體(普通情況下,場景中的絕大多數物體應該是非透明的)
//AlphaTest--用來渲染經過Alpha Test的像素,單獨為AlphaTest設定一個Queue是出于對效率的考慮
//Overlay--用來渲染疊加的效果,是渲染的最后階段(比如鏡頭光暈等特效)
//Transparent--以從后往前的順序渲染透明物體
//預設的隊列本質就是定義的整數(有點像枚舉值)
//Background=1000,Geometry=2000,AlphaTest=2450
//Transparent=3000,最后Overlay=4000
"RenderType" = "Transparent" //著色器替換功能 "Transparent" 渲染透明物體調用 "Opaqu"渲染非透明的物體
"DisableBatching" = "True"http://是否進行合批
"ForceNoShadowCasting" = "True"http://是否不投射陰影
"IgnoreProjector" = "True"http://受不受projector的影響,通常用于透明物體,如果為true,此著色器的對象將不受Projectors的影響
"CanUseSpriteAltas" = "False"http://是否用于圖片的Shader,通常用于UI,`CanUseSpriteAtlas`如果著色器用于Sprite則將標簽設置為“ False”
"PreviewType" = "Plane"http://用作Shader面板預覽的類型
}
//預設的隊列本質就是定義的整數(有點像枚舉值)
//Background=1000,Geometry=2000,AlphaTest=2450
//Transparent=3000,最后Overlay=4000
//如何自定義列表
Tags{ "Queue"="Transparent+100" }//通過調用Queue值,確保渲染的先后順序
//Unity的內建Diffuse著色器的設定值,這個數值決定了我們能用什么樣的Shader
//這個數值可以在unity中的質量設定中設定
//Render設置 可選
//Cull off/back/front //選擇渲染哪個面
Cull off//默認渲染正面,設置Cull off意思是關閉裁剪, 那就是正反兩面都渲染
Cull back//只渲染背面
Cull front//只渲染前面
//ZTest Always/Less Greater/LEqual/Gequal/Equal/NotEqual //深度測試 默認使用小于等于
ZTest Always //總是
ZTest Less Greater//小于
ZTest LEqual//小于等于
ZTest Gequal//大于等于
ZTest Equal//等于
ZTest NotEqual//不等于
//Zwrite off/on //深度寫入
Zwrite off
Zwrite on
//Blend SrcFactor DstFactor //混合
LOD 200//不同情況下使用不同的LOD,達到性能提升
//關于VertexLit及其系列 = 100
//Decal, Reflective VertexLit = 150
//Diffuse = 200
//Diffuse Detail, Reflective Bumped Unlit, Reflective Bumped VertexLit = 250
//Bumped, Specular = 300
//Bumped Specular = 400
//Parallax = 500
//Parallax Specular = 600
Pass
{
Name "PassName"http://Pass 通道名稱 可以在其他地方Use 該pass通道Name, Use 通道的時候名稱必須大寫
Tags
{
"LightMode"="ForwardBase"http://定義該Pass通道在unity渲染流水中的角色
//"RequireOptions"="SoftVegetation"http://用于滿足某些條件時才渲染該Pass通道
}//可以在每個Pass通道里面進行定義
//Shader字體:也就是將輸入轉變成輸出的代碼部分
CGPROGRAM//開始CG語言的編寫
// Physically based Standard lighting model, and enable shadows on all light types
//surface:申明的是一個表面著色器
//surf:著色器代碼的方法的名字,下方的代碼有這個函數
//Standard:標準
//fullforwardshadows:光照模型
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
//在CG中,sampler2D就是和texture所綁定的一個數據容器接口
//其實就是內存存儲的RGB通道,sampler2D:就是GLSL中的2D貼圖的類型
//其他類型:sampler1D,sampler3D,samplerCube
// 圖片
sampler2D _MainTex;
// 用來獲取MainTex的UV信息
struct Input {
float2 uv_MainTex;//float2:浮點數的float后面緊跟一個數字2
vec2 coordinate;//float和vec都可以在之后加入一個2到4的數字,來表示被打包在一起的2到4個同類型數
float4 color;
};
half _Glossiness;//half指的是半精度浮點數,精度最低,運算性能相對比高精度浮點數高一些
half _Metallic;
// 顏色屬性
fixed4 _Color;
// SurfaceOutputStandard 表面著色器輸出一個標準的結構體
//著色器的工作核心,著色器就是給定了輸入,然后給出輸出進行著色的代碼,第一個參數是Input結果,第二個參數是一個inout的SurfaceOutput結構
void surf (Input IN, inout SurfaceOutputStandard o) {
// Albedo comes from a texture tinted by color
// 獲取圖片 * 我們選定的顏色
//fixed4:定點書:整形數據類型,作用就是把所有數進行轉換,得到相應類型的整形表達
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
// 輸出的像素的顏色 = 圖像的顏色(RGB)
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
// 輸出的顏色效果(金屬方面) = 設定的金屬值
o.Metallic = _Metallic;
// 輸出的光滑粗糙程度 = 設置的光滑粗燥程度
o.Smoothness = _Glossiness;
// 輸出的透明通道 = 圖像的透明通道
o.Alpha = c.a;
}
}
ENDCG//結束CG語言的編寫
}
FallBack "Diffuse"
}
參考
https://docs.unity3d.com/Manual/SL-SurfaceShaderExamples.html
https://onevcat.com/2013/08/shader-tutorial-2/
http://www.tuicool.com/articles/JvYJ3em
http://www.itnose.net/detail/6143450.html
CG語言基礎知識:
內置元類型
Float : 32bit浮點類型
Half: 16bit浮點
Int : 32bit整形
Fixed : 12bit定點
Bool : 布爾值
Sampler:紋理對象的句柄
String:不是每個都支持
cg提供內置的向量數據類型(build-in vector data types)
float1、float4,
bool2, bool3,
float1x1
float2x3
類型轉換跟C是一樣的,用強制轉化。
類型定義的時候可以在常量后跟后綴,如2.0f,1.0h,3x。目前值有f,h,x(fixed)三種。
支持類型
1、數組
float a[10];
float4 b[10];
int length = a.length; //獲取長度,上面兩個返回都是10
float b[2][3] = { { }, { } };
int length1 = b.length; // length1 = 2;
int length2 = b[0].length; // length = 3;
2、結構
以struct開始,緊跟名字,內容用{};包住。不要忘記最后的分號。
結構中可以帶function,是C++中的用法。
結構不支持繼承。
3、特定關鍵字
in , out , inout,
uniform (被修飾的變量從外部傳入), const ,
4、輸入語義關鍵字
Vertex Shader的輸入:
POSITION, NORMAL, BINORMAL, BLENDINDICES, BLENDWEIGHT, TANGENT, PSIZE, TEXCOORD0 ~ TEXCOORD7
如:in float4 modelPos: POSITION
Vertex Shader的輸出, 也就是Pixel Shader的輸入
POSITION, PSIZE, FOG,COLOR0 ~ COLOR1, TEXCOORD1 ~ TEXCOORD7
Pixel Shader的輸出:
COLOR
5、入口函數
通過觀察程序的輸入輸出語義綁定,就可以區分入口函數對應到頂點程序還是片段程序。
6、內置函數庫
reflect 求發射向量
refract 求折射向量
mul 矩陣相乘
normalize 歸一化
CG語言的學習資料:
http://blog.csdn.net/liu_lin_xm?viewmode=contents
https://developer.nvidia.com/cg-toolkit