轉(zhuǎn)載注明出處:點擊打開鏈接
Shader(著色器)是一段能夠針對3D對象進(jìn)行操作塔粒、并被GPU所執(zhí)行的程序。Shader并不是一個統(tǒng)一的標(biāo)準(zhǔn)杠氢,不同的圖形接口的Shader并不相同。OpenGL的著色語言是GLSL, NVidia開發(fā)了Cg怜姿,而微軟的Direct3D使用高級著色器語言(HLSL)。而Unity的Shader 是將傳統(tǒng)的圖形接口的Shader(由 Cg / HLSL編寫)嵌入到獨有的描述性結(jié)構(gòu)中而形成的一種代碼生成框架疼燥,最終會自動生成各硬件平臺自己的Shader沧卢,從而實現(xiàn)跨平臺。
Shader程序結(jié)構(gòu)
屬性定義(Property Definition):定義Shader的輸入醉者,這些輸入可以在材質(zhì)編輯的時候指定
子著色器(SubShader):一個Shader可以有多個子著色器但狭。這些子著色器互不相干且只有一個會在最終的平臺運行。編寫多個的目的是解決兼容性問題撬即。Unity會自己選擇兼容終端平臺的Shader運行立磁。
回滾(Fallback):如果子著色器在終端平臺上都無法運行,那么使用Fallback指定的備用Shader剥槐,俗稱備胎唱歧。
Pass:一個Pass就是一次繪制。對于表面著色器粒竖,只能有一個Pass颅崩,所以不存在Pass節(jié)。頂點片段著色器可以有多個Pass蕊苗。多次Pass可以實現(xiàn)很多特殊效果沿后,例如當(dāng)人物被環(huán)境遮擋時還可以看到人物輪廓就可以用多Pass來實現(xiàn)。
Cg代碼:每個Pass中都可以包含自定義的Cg代碼朽砰,從CGPROGRAM開始到ENDCG結(jié)束尖滚。
Shader 輸入
Shader的輸入有兩個來源,一是通過屬性定義锅移,一是通過Shader.SetGlobalXXX方法全局設(shè)置熔掺。
屬性定義變量:屬性定義中的變量是Shader參數(shù)的主要設(shè)置方式。 它是隨材質(zhì)變化的非剃,每個使用該Shader的材質(zhì)都可以在Inspector或者腳本中設(shè)置這些參數(shù)置逻。這些參數(shù)除了在Shader的Properties段中定義外,還需要在Cg中聲明方可使用备绽。例如上面表面著色器的例子中我們定義了_MainTex這個類型為2D的屬性券坞,還需要在Cg中聲明 sampler2D _MainTex。
全局變量:Shader有一組SetGlobalXXX方法肺素,可以對Shader的在Cg中定義而沒有在屬性中定義的uniform變量進(jìn)行設(shè)置恨锚。這個設(shè)置是全局的,所有定義了該uniform的Shader都會受到影響倍靡。例如我們希望場景隨著時間變化而改變顏色猴伶,就可以給場景所使用到的Shader設(shè)置統(tǒng)一的全局顏色變量,然后在腳本中通過設(shè)置該顏色來改變場景的顏色。在角色釋放技能時場景變黑也可以使用這個方法他挎。
Unity shader 中允許定義的屬性類型有:
關(guān)鍵字
類型
對應(yīng)Cg類型
例
Float
浮點數(shù)
float
_MyFloat (“My float”, Float) = 0.5
Range
浮點數(shù) (在指定范圍內(nèi))
float
_MyRange (“My Range”, Range(0.01, 0.5)) = 0.1
Color
浮點四元組
float4
_MyColor (“Some Color”, Color) = (1,1,1,1)
Vector
浮點四元組
float4
_MyVector(“Some Vector”,Vector) = (1,1,1,1)
2D
2的階數(shù)大小的貼圖
sampler2D
_MyTexture (“Texture”, 2D) = “white” {}
Rect
非2的階數(shù)大小的貼圖
sampler2D
_MyRect(“My Rect”, Rect) = “white” {}
CUBE
CubeMap
samplerCUBE
_MyCubemap (“Cubemap”, CUBE) = “” {}
注:CubeMap 是6張有聯(lián)系的2D貼圖的組合主要用來做反射效果(比如天空盒和動態(tài)反射)
SubShader
SubShader中除了Pass筝尾,有兩個標(biāo)簽值得關(guān)注:LOD和Tags
LOD
LOD是 Level of Detail的簡寫,確切地說是Shader Level of Detail的簡寫办桨,因為Unity中還有一個模型的LOD概念筹淫,這是兩個不同的東西。我們這里只介紹Shader中LOD
Shader LOD 就是讓我們設(shè)置一個數(shù)值呢撞,這個數(shù)值決定了我們能用什么樣的Shader损姜。可以通過Shader.maximumLOD或者Shader.globalMaximumLOD 設(shè)定允許的最大LOD殊霞,當(dāng)設(shè)定的LOD小于SubShader所指定的LOD時摧阅,這個SubShader將不可用。通過LOD脓鹃,我們就可以為某個材質(zhì)寫一組SubShader逸尖,指定不同的LOD,LOD越大則渲染效果越好瘸右,當(dāng)然對硬件的要求也可能越高娇跟,然后根據(jù)不同的終端硬件配置來設(shè)置 globalMaximumLOD來達(dá)到兼顧性能的最佳顯示效果。
Unity內(nèi)建Shader定義了一組LOD的數(shù)值太颤,我們在實現(xiàn)自己的Shader的時候可以將其作為參考來設(shè)定自己的LOD數(shù)值
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
Tag
SubShader可以被若干的標(biāo)簽(tags)所修飾苞俘,而硬件將通過判定這些標(biāo)簽來決定什么時候調(diào)用該著色器。 比較常見的標(biāo)簽有:
Queue 這個標(biāo)簽很重要龄章,它定義了一個整數(shù)吃谣,決定了Shader的渲染的次序,數(shù)字越小就越早被渲染做裙,早渲染就意味著可能被后面渲染的東西覆蓋掉看不見岗憋。 預(yù)定義的Queue有:
名字
值
描述
Background
1000
最早被調(diào)用的渲染,用來渲染天空盒或者背景
Geometry
2000
這是默認(rèn)值锚贱,用來渲染非透明物體(普通情況下仔戈,場景中的絕大多數(shù)物體應(yīng)該是非透明的)
AlphaTest
2450
用來渲染經(jīng)過Alpha Test的像素,單獨為AlphaTest設(shè)定一個Queue是出于對效率的考慮
Transparent
3000
以從后往前的順序渲染透明物體
Overlay
4000
用來渲染疊加的效果拧廊,是渲染的最后階段(比如鏡頭光暈等特效)
RenderType “Opaque”或”Transparent”是兩個常用的RenderType监徘。如果輸出中都是非透明物體,那寫在Opaque里吧碾;如果想渲染透明或者半透明的像素凰盔,那應(yīng)該寫在Transparent中。這個Tag主要用ShaderReplacement倦春,一般情況下這Tag好像也沒什么作用蝗羊。
CommonState
SubShader中可以定義一組Render State,基本上就是一些渲染的開關(guān)選項输玷,他們對該SubShader的所有的Pass都有效,所以稱Common著榴。這些Render State也可以在每個Pass中分別定義,將在Pass中詳細(xì)介紹屁倔。
Pass
Render State
Render State主要就是控制渲染過程的一些開關(guān)選項,例如是否開啟alpha blending 暮胧,是否開啟depth testing锐借。 常用的Render State有:
Cull 用法:Cull Back | Front | Off 多邊形表面剔除開關(guān)。Back表示背面剔除往衷,F(xiàn)ront表示正面剔除钞翔,Off表示關(guān)閉表面剔除即雙面渲染。有時候如裙擺席舍,飄帶之類很薄的東西在建模時會做成一個面片布轿,這就需要設(shè)置Cull Off來雙面渲染,否則背面會是黑色来颤。
ZWrite 用法:ZWrite On | Off 控制當(dāng)前對象的像素是否寫入深度緩沖區(qū)(depth buffer)汰扭,默認(rèn)是開啟的。一般來說繪制不透明物體的話ZWrite開啟福铅,繪制透明或半透明物體則ZWrite關(guān)閉萝毛。 深度緩沖區(qū):當(dāng)圖形處理卡渲染物體的時候,每一個所生成的像素的深度(即 z 坐標(biāo))就保存在一個緩沖區(qū)中滑黔。這個緩沖區(qū)叫作 z 緩沖區(qū)或者深度緩沖區(qū)笆包,這個緩沖區(qū)通常組織成一個保存每個屏幕像素深度的 x-y 二維數(shù)組。如果場景中的另外一個物體也在同一個像素生成渲染結(jié)果略荡,那么圖形處理卡就會比較二者的深度庵佣,并且保留距離觀察者較近的物體。然后這個所保留的物體點深度保存到深度緩沖區(qū)中汛兜。最后巴粪,圖形卡就可以根據(jù)深度緩沖區(qū)正確地生成通常的深度感知效果:較近的物體遮擋較遠(yuǎn)的物體。 理解了深度緩沖區(qū)也就理解了為什么繪制透明或半透明物體需要關(guān)閉ZWrite, 如果不關(guān)閉序无,透明物體的depth也會被寫入深度緩沖區(qū)验毡,從而會剔除掉它后面的物體,后面的物體就不會被渲染帝嗡,看不見后面的物體還能叫透明嗎晶通?因此我們使用Alpha blending的時候需要設(shè)置ZWrite Off。
ZTest 用法:ZTest (Less | Greater | LEqual | GEqual | Equal | NotEqual | Always) 控制如何進(jìn)行深度測試哟玷,也就是上面說的圖形處理卡比較二者的深度的比較方法狮辽。默認(rèn)是LEqual一也。 值得一提的是使用Aplha blending的時候ZWrite需要關(guān)閉但是ZTest是要開啟的,因為如果透明物體前面還有不透明物體喉脖,透明物體還是應(yīng)該被遮擋剔除的椰苟。
Blend 混合∈鬟矗控制了每個Shader的輸出如何和屏幕上已有的顏色混合舆蝴。 用法: Blend Off: 關(guān)閉混合 Blend SrcFactor DstFactor:最終顏色 = Shader產(chǎn)生的顏色 × SrcFactor + 屏幕上原來的顏色 × DstFactor Blend SrcFactor DstFactor, SrcFactorA DstFactor:和上面一樣,只是Alpha通道使用后面兩個參數(shù)計算 常用的Blend模式有: Blend SrcAlpha OneMinusSrcAlpha // Alpha blending Blend One One // Additive Blend OneMinusDstColor One // Soft Additive Blend DstColor Zero // Multiplicative Blend DstColor SrcColor // 2x Multiplicative
Unity5開始下列固定功能的Shader命令被標(biāo)記為過時了题诵,這些命令的功能現(xiàn)在建議在Shader(Cg)中通過代碼來實現(xiàn)洁仗,這里列出是為了方便閱讀以前寫的Shader:
Lighting On | Off
Material { Material Block }
SeparateSpecular On | Off
Color Color-value
ColorMaterial AmbientAndDiffuse | Emission
Fog { Fog Block }
AlphaTest (Less | Greater | LEqual | GEqual | Equal | NotEqual | Always) CutoffValue
SetTexture textureProperty { combine options }
Surface Shader
Surface Shader 隱藏了很多光照處理的細(xì)節(jié),它的設(shè)計初衷是為了讓用戶僅僅使用一些指令(#pragma)就可以完成很多事情性锭,并且封裝了很多常用的光照模型和函數(shù)赠潦。相比底層的Vertex And Fragment Shader,Suface Shader的限制比較多草冈,它只能有一次Pass她奥。如果做一些常規(guī)的功能又需要光照,可以用Surface Shader寫怎棱,比較快速便捷哩俭。如果要寫比較高級的Shader還是建議使用Vertex Shader 和 Fragment Shader。 Surface Shader主要有兩部分組成拳恋,一個是#pragma后面的指令携茂,一個是surf函數(shù)。 pragma的語法是 #pragma surface surfaceFunction lightModel [optionalparams]
- surfaceFunction 通常就是名為surf的函數(shù), 函數(shù)名可以自己取 surf函數(shù)原型是:void surf (Input IN, inout SurfaceOutput o)
- lightModel是Unity內(nèi)置的光照模型诅岩,可以是Lambert讳苦,Blinn-Phong等。 - optionalparams: 包含很多指令
surf函數(shù)主要有一個Input結(jié)構(gòu)的輸入和SurfaceOutput結(jié)構(gòu)的輸出吩谦。
Input
Input 結(jié)構(gòu)需要在Shader中定義鸳谜。它可以包含如下字段, 如果你定義了這些字段就可以在surf函數(shù)中使用它們(好神奇的黑科技)
多個貼圖的uv坐標(biāo),名字必須符合格式uv+貼圖名式廷。例如 float2 uv_MainTex
float3 viewDir - 視圖方向( view direction)值咐扭。為了計算視差效果(Parallax effects),邊緣光照(rim lighting)等滑废,需要包含視圖方向( view direction)值蝗肪。
float4 with COLOR semantic - 每個頂點(per-vertex)顏色的插值。
float4 screenPos - 屏幕空間中的位置蠕趁。 為了反射效果薛闪,需要包含屏幕空間中的位置信息。比如在Dark Unity中所使用的 WetStreet著色器俺陋。
float3 worldPos - 世界空間中的位置豁延。
float3 worldRefl - 世界空間中的反射向量昙篙。如果表面著色器(surface shader)不寫入法線(o.Normal)參數(shù),將包含這個參數(shù)诱咏。 請參考這個例子:Reflect-Diffuse 著色器苔可。
float3 worldNormal - 世界空間中的法線向量(normal vector)。如果表面著色器(surface shader)不寫入法線(o.Normal)參數(shù)袋狞,將包含這個參數(shù)焚辅。
float3 worldRefl; INTERNAL_DATA - 世界空間中的反射向量。如果表面著色器(surface shader)不寫入法線(o.Normal)參數(shù)苟鸯,將包含這個參數(shù)法焰。
float3 worldNormal; INTERNAL_DATA -世界空間中的法線向量(normal vector)。如果表面著色器(surface shader)不寫入法線(o.Normal)參數(shù)倔毙,將包含這個參數(shù)。
SurfaceOutput
SurfaceOutput 描述了表面的特性(光照的顏色反射率乙濒、法線陕赃、散射、鏡面等)颁股,這個結(jié)構(gòu)是固定的么库,不需要在Shader中再定義。
struct SurfaceOutput { half3 Albedo; //反射率甘有,一般就是在光照之前的原始顏色 half3 Normal; //法線 half3 Emission; //自發(fā)光诉儒,用于增強(qiáng)物體自身的亮度,使之看起來好像可以自己發(fā)光 half Specular; //鏡面 half Gloss; //光澤 half Alpha; //透明 };
Unity5 由于引入了基于物理的光照模型亏掀,所以新增加了兩個Output
struct SurfaceOutputStandard { fixed3 Albedo; // base (diffuse or specular) color fixed3 Normal; // tangent space normal, if written half3 Emission; half Metallic; // 0=non-metal, 1=metal half Smoothness; // 0=rough, 1=smooth half Occlusion; // occlusion (default 1) fixed Alpha; // alpha for transparencies }; struct SurfaceOutputStandardSpecular { fixed3 Albedo; // diffuse color fixed3 Specular; // specular color fixed3 Normal; // tangent space normal, if written half3 Emission; half Smoothness; // 0=rough, 1=smooth half Occlusion; // occlusion (default 1) fixed Alpha; // alpha for transparencies };
Unity提供了一些基本的SurfaceShader的例子忱反,有助于我們理解輸入輸出是如何被使用的。 Unity提供的SurfaceShader的例子
Vertex Shader
如果不想使用Surface Shader而直接編寫opengl和Direct3D中常見的頂點著色器和片段著色器滤愕,可以通過Cg代碼段嵌入到Pass中:
Pass { // ... the usual pass state setup ... CGPROGRAM // compilation directives for this snippet, e.g.: #pragma vertex vert #pragma fragment frag // the Cg/HLSL code itself ENDCG // ... the rest of pass setup ... }
其中vert就是頂點著色器函數(shù)温算,frag就是片段著色器函數(shù)。一般來說间影,可以在頂點著色器中進(jìn)行的計算就不應(yīng)該放到片段著色器中去算注竿,因為頂點著色器是逐頂點計算的而片段著色器是逐像素計算的,一個模型頂點總比表明像素少很多吧魂贬。
編寫頂點和片段著色器一般需要包含Unity預(yù)定義的一個幫助文件UnityCG.cginc巩割,里面預(yù)定義了一些常用的結(jié)構(gòu)和方法。Windows版Unity這個文件位于({unity install path}/Data/CGIncludes/UnityCG.cginc
付燥。 Mac版位于/Applications/Unity/Unity.app/Contents/CGIncludes/UnityCG.cginc
宣谈。
在代碼中我們只需要添加 #include "UnityCG.cginc"
就可以使用里面的結(jié)構(gòu)和方法。
Input
頂點著色器的原型是 v2f vert (appdata v) appdata 是輸入键科,可以自己定義也可以使用Unity預(yù)定義的蒲祈。Unity在UnityCG.cginc預(yù)定義了三種常用的輸入結(jié)構(gòu):appdata_base甘萧,appdata_tan,appdata_full梆掸。
struct appdata_base { float4 vertex : POSITION; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; }; struct appdata_tan { float4 vertex : POSITION; float4 tangent : TANGENT; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; }; struct appdata_full { float4 vertex : POSITION; float4 tangent : TANGENT; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; float4 texcoord1 : TEXCOORD1; float4 texcoord2 : TEXCOORD2; float4 texcoord3 : TEXCOORD3; #if defined(SHADER_API_XBOX360) half4 texcoord4 : TEXCOORD4; half4 texcoord5 : TEXCOORD5; #endif fixed4 color : COLOR; };
我們注意到這些結(jié)構(gòu)的字段和表面著色器中的字段不同扬卷,后面多了一個冒號和一個標(biāo)簽。這是該字段的語義酸钦,用于告訴GPU這個字段的數(shù)據(jù)應(yīng)該去哪里讀寫怪得。GPU畢竟是為了圖形計算而特別設(shè)計的東西,很多東西都是固定的卑硫,我們只要記得有這么幾個名字可以用行了徒恋。
類型
名字
標(biāo)簽
備注
float4
vertex
POSITION
頂點在模型坐標(biāo)系下的位置
float3
normal
NORMAL
頂點的法向量
float4
tangent
TANGENT
頂點的切向量
float4
color
COLOR
頂點色
float4
texcoord
TEXCOORD0
頂點的第一個uv坐標(biāo)
float4
texcoord1
TEXCOORD1
頂點的第二個uv坐標(biāo),最多可以到5
Output
頂點著色器的輸出是也是一個可以自己定義的結(jié)構(gòu)欢伏,但是結(jié)構(gòu)內(nèi)容也是比較固定的入挣,一般包含了頂點投影后的位置,uv硝拧,頂點色等径筏,也可以加一些后面片段著色器需要用到但是需要在頂點著色器中計算的值。這個輸出就是后面片段著色器的輸入障陶。
struct v2f { float4 pos : SV_POSITION; half2 uv : TEXCOORD0; };
可以使用的字段有:
類型
標(biāo)簽
描述
float4
SV_POSITION
頂點在投影空間下的位置滋恬,注意和輸入的模型坐標(biāo)系下的位置不同,這個字段必必須設(shè)置抱究,這個坐標(biāo)轉(zhuǎn)換是頂點著色器的重要工作
float3
NORMAL
頂點在視圖坐標(biāo)系下的法向量
float4
TEXCOORD0
第一張貼圖的uv坐標(biāo)
float4
TEXCOORD1
第二張貼圖的uv坐標(biāo)
float4
TANGENT
切向量恢氯,主要用來修正法線貼圖Normal Maps
fixed4
COLOR
第一個定點色
fixed4
COLOR1
第二個定點色
Any
Any
其他自定義的字段
坐標(biāo)變換
頂點著色器有一項重要的工作就是進(jìn)行坐標(biāo)變換。頂點著色器的輸入中的坐標(biāo)是模型坐標(biāo)系(ObjectSpace)下的坐標(biāo)鼓寺,而最終繪制到屏幕上的是投影坐標(biāo)勋拟。 在我們Shader里面只需要一句話就可以完成坐標(biāo)的轉(zhuǎn)換,這也是最簡單的頂點著色器:
v2f vert(appdata v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); return o; }
用UNITY_MATRIX_MVP矩陣乘以頂點在模型坐標(biāo)系下的坐標(biāo)就得到投影坐標(biāo)妈候。 UNITY_MATRIX_MVP是Unity內(nèi)建的模型->視->投影矩陣指黎, Unity內(nèi)建矩陣如下:
UNITY_MATRIX_MVP:當(dāng)前模型->視圖->投影矩陣。(注:模型矩陣為 本地->世界)
UNITY_MATRIX_MV:當(dāng)前模型->視圖矩陣
UNITY_MATRIX_V:當(dāng)前視圖矩陣
UNITY_MATRIX_P:當(dāng)前投影矩陣
UNITY_MATRIX_VP:當(dāng)前視圖->投影矩陣
UNITY_MATRIX_T_MV:轉(zhuǎn)置模型->視圖矩陣
UNITY_MATRIX_IT_MV:逆轉(zhuǎn)置模型->視矩陣, 用于將法線從ObjectSpace旋轉(zhuǎn)到WorldSpace州丹。為什么法線變化不能和位置變換一樣用UNITY_MATRIX_MV呢醋安?一是因為法線是3維的向量而- UNITY_MATRIX_MV是一個4x4矩陣,二是因為法線是向量墓毒,我們只希望對它旋轉(zhuǎn)吓揪,但是在進(jìn)行空間變換的時候,如果發(fā)生非等比縮放所计,方向會發(fā)生偏移柠辞。
UNITY_MATRIX_TEXTURE0 to UNITY_MATRIX_TEXTURE3:紋理變換矩陣
下面簡單介紹一下里面提到的幾個坐標(biāo)系: 模型坐標(biāo)系:也叫物體坐標(biāo)系,3D建模的時候每個模型都是在自己的坐標(biāo)系下建立的主胧,如果一個人物模型腳底是(0,0,0) 點的話它的身上其它點的坐標(biāo)都是相對腳底這個原點的叭首。 世界坐標(biāo)系:我們場景是一個世界习勤,有自己的原點,模型放置到場景中后模型上的每個頂點就有了一個新的世界坐標(biāo)焙格。這個坐標(biāo)可以通過模型矩陣×模型上頂點的模型坐標(biāo)得到图毕。 視圖坐標(biāo)系:又叫觀察坐標(biāo)系,是以觀察者(相機(jī))為原點的坐標(biāo)系眷唉。場景中的物體只有被相機(jī)觀察到才會繪制到屏幕上予颤,相機(jī)可以設(shè)置視口大小和裁剪平面來控制可視范圍,這些都是相對相機(jī)來說的冬阳,所以需要把世界坐標(biāo)轉(zhuǎn)換到視圖坐標(biāo)系來方便處理蛤虐。 投影坐標(biāo)系:場景是3D的,但是最終繪制到屏幕上是2D肝陪,投影坐標(biāo)系完成這個降維的工作驳庭,投影變換后3D的坐標(biāo)就變成2D的坐標(biāo)了。投影有平行投影和透視投影兩種氯窍,可以在Unity的相機(jī)上設(shè)置饲常。 屏幕坐標(biāo)系 : 最終繪制到屏幕上的坐標(biāo)。屏幕的左下角為原點荞驴。
除了內(nèi)建矩陣,Unity還內(nèi)建了一些輔助函數(shù)也可以在頂點著色器里面使用:
float3 WorldSpaceViewDir (float4 v):根據(jù)給定的局部空間頂點位置到相機(jī)返回世界空間的方向(非規(guī)范化的)
float3 ObjSpaceViewDir (float4 v):根據(jù)給定的局部空間頂點位置到相機(jī)返回局部空間的方向(非規(guī)范化的)
float2 ParallaxOffset (half h, half height, half3 viewDir):為視差法線貼圖計算UV偏移
fixed Luminance (fixed3 c):將顏色轉(zhuǎn)換為亮度(灰度)
fixed3 DecodeLightmap (fixed4 color):從Unity光照貼圖解碼顏色(基于平臺為RGBM 或dLDR)
float4 EncodeFloatRGBA (float v):為儲存低精度的渲染目標(biāo)贯城,編碼[0..1)范圍的浮點數(shù)到RGBA顏色熊楼。
float DecodeFloatRGBA (float4 enc):解碼RGBA顏色到float。
float2 EncodeViewNormalStereo (float3 n):編碼視圖空間法線到在0到1范圍的兩個數(shù)能犯。
float3 DecodeViewNormalStereo (float4 enc4):從enc4.xy解碼視圖空間法線
Fragment Shader
// TODO