HLSL
高階著色器語(yǔ)言(High Level Shader Language赌蔑,簡(jiǎn)稱HLSL),由微軟擁有及開(kāi)發(fā)的一種語(yǔ)言前塔,HLSL 獨(dú)立的工作在 Windows 平臺(tái)上挪蹭,只能供微軟的Direct3D使用。 HLSL是微軟抗衡GLSL的產(chǎn)品,同時(shí)不能與OpenGL標(biāo)準(zhǔn)兼容子寓。
GLSL
OpenGL著色語(yǔ)言(OpenGL Shading Language)是用來(lái)在OpenGL中著色編程的語(yǔ)言暗挑,也即開(kāi)發(fā)人員寫的短小的自定義程序,他們是在圖形卡的GPU (Graphic Processor Unit圖形處理單元)上執(zhí)行的斜友,代替了固定的渲染管線的一部分炸裆,使渲染管線中不同層次具有可編程性。
CG
GPU語(yǔ)言
由于GPU采用不同于CPU的運(yùn)行運(yùn)算結(jié)構(gòu)鲜屏,因此需要一種適用于GPU的編程語(yǔ)言烹看。
1、微軟基于Direct3D圖形庫(kù)的HLSL(High Level Shading Language)
2洛史、OpenGL ARB定義基于OpenGL圖形庫(kù)的GLSL(OpenGL Shading Language)
3听系、NVIDIA(英偉達(dá))與微軟合作研發(fā)的Cg(C for Graphics).
Cg能夠同時(shí)兼容Direct3D和OpenGL圖形接口。
Unity所有的渲染都需要shader來(lái)完成虹菲,內(nèi)置的著色器超過(guò)80個(gè)靠胜,可以輕松利用其內(nèi)置的著色器來(lái)完成各種畫(huà)面效果,并且還提供了自定義shader,方便擴(kuò)展毕源。Unity使用shaderLab開(kāi)發(fā)語(yǔ)言來(lái)組織shader內(nèi)容浪漠,并會(huì)針對(duì)不同的平臺(tái)進(jìn)行編譯,類似微軟的FX文件或者NAIDIA的CgFX.
Shader霎褐,可以分為VertexShader 和PixelShader/FragmentShader兩部分,簡(jiǎn)稱VS,PS址愿。學(xué)名頂點(diǎn)著色器和像素著色器。一旦你使用了VS和PS,則渲染過(guò)程會(huì)將VB(頂點(diǎn)緩沖)的數(shù)據(jù)按照IB索引(頂點(diǎn)索引緩沖)將每個(gè)頂點(diǎn)結(jié)構(gòu)值分量傳入VS冻璃,VS進(jìn)行相應(yīng)的計(jì)算和頂點(diǎn)變化响谓,并將VS返回的結(jié)果再交由PS進(jìn)行像素著色,輸出相應(yīng)的圖像。概念上來(lái)說(shuō) FragmentShader會(huì)比PixelShader大很多..
這兩個(gè)東西由于DX用PixelShader的緣故省艳,其實(shí)是一個(gè)東西
Unity中可以編寫3種不同的著色器:表面著色器(Surface Shader)娘纷、頂點(diǎn)和片段著色器(Vertex and Fragment Shaders)和固定功能管線著色器(Fixed Function Shaders).
Unity5.0,內(nèi)建了基于物理渲染的StandardShader,同時(shí)還引入了完全延遲著色(FullDeferredRendering)和烘焙反射探頭(Baked Reflection Probes)用于以真實(shí)環(huán)境為基礎(chǔ)的鏡面高光
物理著色:PBS (physically Based Shading):新的工業(yè)標(biāo)準(zhǔn),用于電影產(chǎn)品
遵從了Conservation of Energy(能量守恒定律)跋炕,只有這樣才能夠正真讓場(chǎng)景里面的光源依據(jù)能量傳遞的方式赖晶,產(chǎn)生一種自然和諧的光照效果。
Standard Surface Shader (Instanced):標(biāo)準(zhǔn)表面材質(zhì)(實(shí)例化)
Unlit Shader:未點(diǎn)燃的材質(zhì)
Image Effect Shader:圖像效果材質(zhì)
Compute Shader:計(jì)算著色器
Shader Variant Collection:著色器變量集合
內(nèi)建Shader介紹
4.X版本提供超過(guò)80個(gè)內(nèi)建Shader辐烂、包括頂點(diǎn)光照效果到高光遏插、發(fā)現(xiàn)、反射等游戲常用的材質(zhì)效果纠修。
內(nèi)建Shader分類:
普通(Normal):用于不透明對(duì)象
透明(Transparent):用于半透明和全透明對(duì)象
透明鏤空效果(TransparentCutOut):用于完全透明和完全不透明部分組成(不含半透明部分)的對(duì)象胳嘲,像柵欄一樣。
自發(fā)光(Self-llluminated shader Family):用于能反射環(huán)境立方體貼圖的不透明對(duì)象
反射(Reflective Shader Family):用于能反射環(huán)境立方體貼圖的不透明對(duì)象
每個(gè)類別下包含若干復(fù)雜性各異的shader
以光照效果計(jì)算開(kāi)銷從低到高排序:
Unlit : 僅使用紋理扣草,不受光照影響
VertexLit:頂點(diǎn)光照
Diffuse:漫發(fā)射
Specular: 在漫反射基礎(chǔ)上增加高光計(jì)算
Nomal Mapped : 法線貼圖了牛,增加了一張法線貼圖和幾個(gè)著色器指令吁系。
Nomal Mapped Specular : 帶高光法線貼圖
Parallax Nomal Mapped : 視差法線貼圖,增加了視差貼圖計(jì)算開(kāi)銷
Parallax Nomal Mapped :帶高光視差法線貼圖
5.X版本新增加了一種基于物理著色的內(nèi)建著色器白魂,即StandardShader(標(biāo)準(zhǔn)著色器)
物理著色:PBS (physically Based Shading):新的工業(yè)標(biāo)準(zhǔn)汽纤,用于電影產(chǎn)品
遵從了Conservation of Energy(能量守恒定律),只有這樣才能夠正真讓場(chǎng)景里面的光源依據(jù)能量傳遞的方式福荸,產(chǎn)生一種自然和諧的光照效果蕴坪。
StandardShader是基于物理的著色器,也就是說(shuō)不管你選擇什么樣的貼圖都會(huì)與光照產(chǎn)生反應(yīng)敬锐,這些貼圖可以是同一張圖片背传,Unity會(huì)使用必要的資源進(jìn)行計(jì)算。
原理:
遵從了Conservation of Energy(能量守恒定律)台夺,只有這樣才能夠正真讓場(chǎng)景里面的光源依據(jù)能量傳遞的方式径玖,產(chǎn)生一種自然和諧的光照效果。
表面反射的光線不會(huì)比它們收到的更多
光滑的表面會(huì)有更強(qiáng)的反射
醋糟的表面反射會(huì)更弱一些
高光強(qiáng)度會(huì)隨著漫反射的強(qiáng)度而改變
所有的表面從某一特定角度看上去會(huì)有或多或少的高光
所有的表面在掠射角會(huì)有更多的反射
編寫自己的Shader(詳細(xì)解答Shader的各種屬性及用法)
Shader "Custom/firstsharder" {//這里是Shader的名字
Properties {//著色器屬性
_Color ("Color", Color) = (1,1,1,1)
//在輸入貼圖時(shí)候,必須要寫一個(gè)什么都不含的{}
//需要打開(kāi)特定選項(xiàng)時(shí)可以把其寫在這對(duì)花括號(hào)內(nèi).
//如果需要同時(shí)打開(kāi)多個(gè)選項(xiàng),可以使用空白分隔
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
SubShader {
//表面著色器可以被若干的標(biāo)簽(tags)所修飾
//硬件將通過(guò)判定這些標(biāo)簽來(lái)決定什么時(shí)候調(diào)用該著色器
//標(biāo)簽 可選
Tags
{
"Queue" = "Opaque"http://渲染順序
//Background--最早被調(diào)用的渲染,用來(lái)渲染天空盒或者背景
//Geometry--默認(rèn)值颤介,用來(lái)渲染非透明物體(普通情況下梳星,場(chǎng)景中的絕大多數(shù)物體應(yīng)該是非透明的)
//AlphaTest--用來(lái)渲染經(jīng)過(guò)Alpha Test的像素,單獨(dú)為AlphaTest設(shè)定一個(gè)Queue是出于對(duì)效率的考慮
//Overlay--用來(lái)渲染疊加的效果,是渲染的最后階段(比如鏡頭光暈等特效)
//Transparent--以從后往前的順序渲染透明物體
//預(yù)設(shè)的隊(duì)列本質(zhì)就是定義的整數(shù)(有點(diǎn)像枚舉值)
//Background=1000,Geometry=2000,AlphaTest=2450
//Transparent=3000,最后Overlay=4000
"RenderType" = "Transparent" //著色器替換功能 "Transparent" 渲染透明物體調(diào)用 "Opaqu"渲染非透明的物體
"DisableBatching" = "True"http://是否進(jìn)行合批
"ForceNoShadowCasting" = "True"http://是否不投射陰影
"IgnoreProjector" = "True"http://受不受projector的影響,通常用于透明物體,如果為true,此著色器的對(duì)象將不受Projectors的影響
"CanUseSpriteAltas" = "False"http://是否用于圖片的Shader,通常用于UI,`CanUseSpriteAtlas`如果著色器用于Sprite則將標(biāo)簽設(shè)置為“ False”
"PreviewType" = "Plane"http://用作Shader面板預(yù)覽的類型
}
//預(yù)設(shè)的隊(duì)列本質(zhì)就是定義的整數(shù)(有點(diǎn)像枚舉值)
//Background=1000,Geometry=2000,AlphaTest=2450
//Transparent=3000,最后Overlay=4000
//如何自定義列表
Tags{ "Queue"="Transparent+100" }//通過(guò)調(diào)用Queue值滚朵,確保渲染的先后順序
//Unity的內(nèi)建Diffuse著色器的設(shè)定值冤灾,這個(gè)數(shù)值決定了我們能用什么樣的Shader
//這個(gè)數(shù)值可以在unity中的質(zhì)量設(shè)定中設(shè)定
//Render設(shè)置 可選
//Cull off/back/front //選擇渲染哪個(gè)面
Cull off//默認(rèn)渲染正面,設(shè)置Cull off意思是關(guān)閉裁剪辕近, 那就是正反兩面都渲染
Cull back//只渲染背面
Cull front//只渲染前面
//ZTest Always/Less Greater/LEqual/Gequal/Equal/NotEqual //深度測(cè)試 默認(rèn)使用小于等于
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韵吨,達(dá)到性能提升
//關(guān)于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 通道的時(shí)候名稱必須大寫
Tags
{
"LightMode"="ForwardBase"http://定義該P(yáng)ass通道在unity渲染流水中的角色
//"RequireOptions"="SoftVegetation"http://用于滿足某些條件時(shí)才渲染該P(yáng)ass通道
}//可以在每個(gè)Pass通道里面進(jìn)行定義
//Shader字體:也就是將輸入轉(zhuǎn)變成輸出的代碼部分
CGPROGRAM//開(kāi)始CG語(yǔ)言的編寫
// Physically based Standard lighting model, and enable shadows on all light types
//surface:申明的是一個(gè)表面著色器
//surf:著色器代碼的方法的名字,下方的代碼有這個(gè)函數(shù)
//Standard:標(biāo)準(zhǔn)
//fullforwardshadows:光照模型
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
//在CG中移宅,sampler2D就是和texture所綁定的一個(gè)數(shù)據(jù)容器接口
//其實(shí)就是內(nèi)存存儲(chǔ)的RGB通道归粉,sampler2D:就是GLSL中的2D貼圖的類型
//其他類型:sampler1D,sampler3D,samplerCube
// 圖片
sampler2D _MainTex;
// 用來(lái)獲取MainTex的UV信息
struct Input {
float2 uv_MainTex;//float2:浮點(diǎn)數(shù)的float后面緊跟一個(gè)數(shù)字2
vec2 coordinate;//float和vec都可以在之后加入一個(gè)2到4的數(shù)字,來(lái)表示被打包在一起的2到4個(gè)同類型數(shù)
float4 color;
};
half _Glossiness;//half指的是半精度浮點(diǎn)數(shù),精度最低漏峰,運(yùn)算性能相對(duì)比高精度浮點(diǎn)數(shù)高一些
half _Metallic;
// 顏色屬性
fixed4 _Color;
// SurfaceOutputStandard 表面著色器輸出一個(gè)標(biāo)準(zhǔn)的結(jié)構(gòu)體
//著色器的工作核心糠悼,著色器就是給定了輸入,然后給出輸出進(jìn)行著色的代碼芽狗,第一個(gè)參數(shù)是Input結(jié)果绢掰,第二個(gè)參數(shù)是一個(gè)inout的SurfaceOutput結(jié)構(gòu)
void surf (Input IN, inout SurfaceOutputStandard o) {
// Albedo comes from a texture tinted by color
// 獲取圖片 * 我們選定的顏色
//fixed4:定點(diǎn)書(shū):整形數(shù)據(jù)類型,作用就是把所有數(shù)進(jìn)行轉(zhuǎn)換童擎,得到相應(yīng)類型的整形表達(dá)
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
// 輸出的像素的顏色 = 圖像的顏色(RGB)
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
// 輸出的顏色效果(金屬方面) = 設(shè)定的金屬值
o.Metallic = _Metallic;
// 輸出的光滑粗糙程度 = 設(shè)置的光滑粗燥程度
o.Smoothness = _Glossiness;
// 輸出的透明通道 = 圖像的透明通道
o.Alpha = c.a;
}
}
ENDCG//結(jié)束CG語(yǔ)言的編寫
}
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語(yǔ)言基礎(chǔ)知識(shí):
內(nèi)置元類型
Float : 32bit浮點(diǎn)類型
Half: 16bit浮點(diǎn)
Int : 32bit整形
Fixed : 12bit定點(diǎn)
Bool : 布爾值
Sampler:紋理對(duì)象的句柄
String:不是每個(gè)都支持
cg提供內(nèi)置的向量數(shù)據(jù)類型(build-in vector data types)
float1、float4攻晒,
bool2, bool3顾复,
float1x1
float2x3
類型轉(zhuǎn)換跟C是一樣的,用強(qiáng)制轉(zhuǎn)化鲁捏。
類型定義的時(shí)候可以在常量后跟后綴芯砸,如2.0f,1.0h,3x假丧。目前值有f双揪,h,x(fixed)三種包帚。
支持類型
1渔期、數(shù)組
float a[10];
float4 b[10];
int length = a.length; //獲取長(zhǎng)度,上面兩個(gè)返回都是10
float b[2][3] = { { }, { } };
int length1 = b.length; // length1 = 2;
int length2 = b[0].length; // length = 3;
2渴邦、結(jié)構(gòu)
以struct開(kāi)始疯趟,緊跟名字,內(nèi)容用{}谋梭;包住信峻。不要忘記最后的分號(hào)。
結(jié)構(gòu)中可以帶function瓮床,是C++中的用法盹舞。
結(jié)構(gòu)不支持繼承。
3隘庄、特定關(guān)鍵字
in , out , inout,
uniform (被修飾的變量從外部傳入), const ,
4矾策、輸入語(yǔ)義關(guān)鍵字
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峭沦、入口函數(shù)
通過(guò)觀察程序的輸入輸出語(yǔ)義綁定贾虽,就可以區(qū)分入口函數(shù)對(duì)應(yīng)到頂點(diǎn)程序還是片段程序。
6吼鱼、內(nèi)置函數(shù)庫(kù)
reflect 求發(fā)射向量
refract 求折射向量
mul 矩陣相乘
normalize 歸一化
CG語(yǔ)言的學(xué)習(xí)資料:
http://blog.csdn.net/liu_lin_xm?viewmode=contents
https://developer.nvidia.com/cg-toolkit