一、Surface Output (表面著色器的標準輸出結(jié)構(gòu))
Surface Shader的標準輸出結(jié)構(gòu)-第一要素
定義一個“表面函數(shù)(surface function)”夫凸,需要輸入相關(guān)的UV或數(shù)據(jù)信息,并在輸出結(jié)構(gòu)中填充SurfaceOutput扰路。SurfaceOutput基本上描述了表面的特性(光照的顏色反射率环壤、法線、散射鹿响、鏡面等)。其實還是需要用CG或者HLSL編寫此部分的代碼谷饿。
通過表面著色器(Surface Shader)來編譯這段CG或者HLSL代碼的惶我,然后計算出需要填充輸入什么,輸出什么等相關(guān)信息博投,并產(chǎn)生真實的頂點(vertex)&像素(pixel)著色器绸贡,以及把渲染路徑傳遞到正向或延時渲染路徑。
Surface Shader的標準輸出結(jié)構(gòu):
struct SurfaceOutput
{
half3 Albedo; //反射率毅哗,也就是紋理顏色值(r,g,b)
half3 Normal; //法線听怕,法向量(x, y, z)
half3 Emission; //自發(fā)光顏色值(r, g,b)
half Specular; //鏡面反射度
half Gloss; //光澤度
half Alpha; //透明度
};
ps:Albedo是half3類型的。所以o.Albedo = 0.6和o.Albedo = float3(0.6,0.6,0.6)是等價的虑绵。
二尿瞭、表面著色器的編譯指令
表面著色器的編譯指令為編寫表面著色器的第二個要素。
表面著色器放在CGPROGRAM .. ENDCG塊里面翅睛,就像其他的著色器一樣声搁。區(qū)別是:
其必須嵌在子著色器(SubShader)塊里面。而不是Pass塊里面捕发。因為表面著色器( Surface shader)將在多重通道(multiple passes)內(nèi)編譯自己疏旨,而不是放在某個Pass中。
我們甚至可以這樣說扎酷,如果你寫表面著色器檐涝,用不到Pass代碼塊,一般直接在SubShader塊中完成就行了法挨。
使用的 #pragma surface...指令骤铃,以聲明這是一個表面著色器。指令的句法是:
#pragma surface surfaceFunction lightModel[optionalparams]
所需參數(shù):
surfaceFunction - 表示指定名稱的Cg函數(shù)中有表面著色器(surface shader)代碼坷剧。這個函數(shù)的格式:void surf (Input IN,inout SurfaceOutput o), 其中Input是我們自己定義的結(jié)構(gòu)喊暖。Input結(jié)構(gòu)中應(yīng)該包含所需的紋理坐標(texture coordinates)和表面函數(shù)(surfaceFunction)所需要的額外的必需變量惫企。
lightModel -使用的光照模式。內(nèi)置的是Lambert (diffuse)和 BlinnPhong (specular)兩種,一般習(xí)慣用Lambert狞尔,也就是蘭伯特光照模式丛版。
進階可選參數(shù):
alpha -透明( Alpha)混合模式。使用它可以寫出半透明的著色器偏序。
alphatest:VariableName -透明( Alpha)測試模式页畦。使用它可以寫出 鏤空效果的著色器。鏤空大小的變量(VariableName)是一個float型的變量研儒。
vertex:VertexFunction - 自定義的頂點函數(shù)(vertex function)豫缨。相關(guān)寫法可參考Unity內(nèi)建的Shader:樹皮著色器(Tree Bark shader),如Tree Creator Bark端朵、Tree Soft Occlusion Bark這兩個Shader好芭。
finalcolor:ColorFunction - 自定義的最終顏色函數(shù)(final color function)。
exclude_path:prepass 或者 exclude_path:forward - 使用指定的渲染路徑冲呢,不需要生成通道舍败。
addshadow - 添加陰影投射 & 收集通道(collector passes)。通常用自定義頂點修改敬拓,使陰影也能投射在任何程序的頂點動畫上邻薯。
dualforward - 在正向(forward)渲染路徑中使用雙重光照貼圖(dual lightmaps)。
fullforwardshadows - 在正向(forward)渲染路徑中支持所有陰影類型乘凸。
decal:add - 添加貼圖著色器(decal shader) (例如: terrain AddPass)厕诡。
decal:blend - 混合半透明的貼圖著色器(Semitransparent decal shader)。
softvegetation - 使表面著色器(surface shader)僅能在Soft Vegetation打開時渲染翰意。
noambient - 不適用于任何環(huán)境光照(ambient lighting)或者球面調(diào)和光照(spherical harmonics lights)木人。
novertexlights - 在正向渲染(Forward rendering)中不適用于球面調(diào)和光照(spherical harmonics lights)或者每個頂點光照(per-vertex lights)。
nolightmap - 在這個著色器上禁用光照貼圖(lightmap)冀偶。(適合寫一些小著色器)
nodirlightmap - 在這個著色器上禁用方向光照貼圖(directional lightmaps)醒第。 (適合寫一些小著色器)。
noforwardadd - 禁用正向渲染添加通道(Forward rendering additive pass)进鸠。 這會使這個著色器支持一個完整的方向光和所有光照的per-vertex/SH計算稠曼。(也是適合寫一些小著色器).
approxview - 著色器需要計算標準視圖的每個頂點(per-vertex)方向而不是每個像索(per-pixel)方向。 這樣更快客年,但是視圖方向不完全是當(dāng)前攝像機(camera) 所接近的表面霞幅。
halfasview - 在光照函數(shù)(lighting function)中傳遞進來的是half-direction向量,而不是視圖方向(view-direction)向量量瓜。 Half-direction會計算且會把每個頂點(per vertex)標準化司恳。這樣做會提高執(zhí)行效率,但是準確率會打折扣绍傲。
ps:可以在 CGPROGRA內(nèi)編寫 #pragma debug扔傅,然后表面編譯器(surface compiler)會進行解釋生成代碼耍共。
三、Input Structure(表面著色器輸入結(jié)構(gòu))
表面著色器書寫的第三個要素是指明表面輸入結(jié)構(gòu)(Input Structure)猎塞。
Input 這個輸入結(jié)構(gòu)通常擁有著色器需要的所有紋理坐標(texture coordinates)试读。紋理坐標(Texturecoordinates)必須被命名為“uv”后接紋理(texture)名字。(或者uv2開始荠耽,使用第二紋理坐標集)钩骇。
可選附加候選值:
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ù)梯影。為了獲得基于每個頂點法線貼圖( per-pixel normal map)的反射向量(reflection vector)需要使用世界反射向量(WorldReflectionVector (IN, o.Normal))巫员。請參考這個例子: Reflect-Bumped著色器。
float3 worldNormal; INTERNAL_DATA -世界空間中的法線向量(normal vector)甲棍。如果表面著色器(surface shader)不寫入法線(o.Normal)參數(shù)简识,將包含這個參數(shù)。為了獲得基于每個頂點法線貼圖( per-pixel normal map)的法線向量(normal vector)需要使用世界法線向量(WorldNormalVector (IN, o.Normal))感猛。
四七扰、一些CG函數(shù)
4.1 UnpackNormal()函數(shù)
UnpackNormal接受一個fixed4的輸入,并將其轉(zhuǎn)換為所對應(yīng)的法線值(fixed3)陪白,并將其賦給輸出的Normal颈走,就可以參與到光線運算中完成接下來的渲染工作了。
4.2 saturate()函數(shù)
saturate的字面解釋是浸濕咱士,浸透疫鹊。其作用是將取值轉(zhuǎn)化為[0,1]之內(nèi)的一個值袖瞻。
可選原型:
float saturate(float x);
float1 saturate(float1 x);
float2 saturate(float2 x);
float3 saturate(float3 x);
float4 saturate(float4 x);
half saturate(half x);
half1 saturate(half1 x);
half2 saturate(half2 x);
half3 saturate(half3 x);
half4 saturate(half4 x);
fixed saturate(fixed x);
fixed1 saturate(fixed1 x);
fixed2 saturate(fixed2 x);
fixed3 saturate(fixed3 x);
fixed4 saturate(fixed4 x);
其唯一的一個參數(shù)x表示矢量或者標量的飽和值(Vector or scalar to saturate.),也就是將這個x轉(zhuǎn)化為[0,1]之內(nèi)的值拆吆。
其返回值:
如果x取值小于0,則返回值為0.
如果x取值大于1脂矫,則返回值為1.
若x在0到1之間枣耀,則直接返回x的值。
4.3 dot()函數(shù)
高等數(shù)學(xué)中的點積操作庭再,用于返回兩個向量的標量積捞奕。
可選原型:
float dot(float a, float b);
float dot(float1 a, float1 b);
float dot(float2 a, float2 b);
float dot(float3 a, float3 b);
float dot(float4 a, float4 b);
half dot(half a, half b);
half dot(half1 a, half1 b);
half dot(half2 a, half2 b);
half dot(half3 a, half3 b);
half dot(half4 a, half4 b);
fixed dot(fixed a, fixed b);
fixed dot(fixed1 a, fixed1 b);
fixed dot(fixed2 a, fixed2 b);
fixed dot(fixed3 a, fixed3 b);
fixed dot(fixed4 a, fixed4 b);
4.4 tex2D()函數(shù)
CG中用于2D紋理采樣的tex2D函數(shù)的用法。
可選原型:
float4 tex2D(sampler2D samp, float2 s)
float4 tex2D(sampler2D samp, float2 s, inttexelOff)
float4 tex2D(sampler2D samp, float3 s)
float4 tex2D(sampler2D samp, float3 s, inttexelOff)
float4 tex2D(sampler2D samp, float2 s,float2 dx, float2 dy)
float4 tex2D(sampler2D samp, float2 s,float2 dx, float2 dy, int texelOff)
float4 tex2D(sampler2D samp, float3 s,float2 dx, float2 dy)
float4 tex2D(sampler2D samp, float3 s,float2 dx, float2 dy, int texelOff)
int4 tex2D(isampler2D samp, float2 s)
int4 tex2D(isampler2D samp, float2 s, inttexelOff)
int4 tex2D(isampler2D samp, float2 s,float2 dx, float2 dy)
int4 tex2D(isampler2D samp, float2 s,float2 dx, float2 dy, int texelOff)
unsigned int4 tex2D(usampler2D samp, float2s)
unsigned int4 tex2D(usampler2D samp, float2s, int texelOff)
unsigned int4 tex2D(usampler2D samp, float2s, float2 dx, float2 dy)
unsigned int4 tex2D(usampler2D samp, float2s, float2 dx, float2 dy,int texelOff)
參數(shù)簡介:
samp-需要查找的采樣對象拄轻,就是在這里填個紋理對象颅围。
s-需進行查找的紋理坐標。
dx-預(yù)計算的沿X軸方向的導(dǎo)數(shù)恨搓。
dy-預(yù)計算的沿Y軸方向的導(dǎo)數(shù)院促。
texelOff-添加給最終紋理的偏移量
其返回值,是查找到的紋理斧抱。
五常拓、光照模型的概念
5.1 漫反射
環(huán)境光是對光照現(xiàn)像的最簡單抽象,因而局限性很大辉浦。它僅能描述光線在空間中無方向并均勻散布時的狀態(tài)弄抬。很多情況下,入射光是帶有方向的宪郊,比如典型的陽光网杆。
如果光照射到比較粗糙的物體表面凶硅,如粉筆,由于這些表面從各個方向等強度地反射光,因而從各個視角出發(fā)鸟蟹,物體表面呈現(xiàn)相同的亮度,所看到的物體表面某點的明暗程度不隨觀測者的位置變化的绊序,這種等同地向各個方向散射的現(xiàn)象稱為光的漫反射(diffuse reflection)茴迁。
簡單光照模型模擬物體表面對光的反射作用。光源被假定為點光源灌闺,其幾何形狀為一個點艰争,向周圍所有方向上輻射等強度的光,在物體表面產(chǎn)生反射作用桂对。
如圖:
5.2 Lambert模型
漫反射光的強度近似地服從于Lambert定律甩卓,即漫反射光的光強僅與入射光的方向和反射點處表面法向夾角的余弦成正比。
由此可以構(gòu)造出Lambert漫反射模型:
Idiffuse =Id Kd cosθ
Idiffuse表示物體表面某點的漫反射光強
Id為點光源蕉斜,Kd(0<Kd<1)表示物體表面該點對漫反射光的反射屬性
θ是入射光線的方向與物體表面該點處法線N的夾角逾柿,或稱為入射角(0≤θ≤90°)
入射角為零時缀棍,說明光線垂直于物體表面,漫反射光強最大机错;
90°時光線與物體表面平行爬范,物體接收不到任何光線。
如圖:
把環(huán)境光模型添加進來弱匪,最后青瀑,Lambert光照模型可寫為:
I= IaKa + Id Kdcosθ= IaKa + Id Kd(L·N)
該模型包含環(huán)境光和漫反射光。
5.3 鏡面反射
Lambert模型較好地表現(xiàn)了粗糙表面上的光照現(xiàn)象萧诫,如石灰粉刷的墻壁斥难、紙張等
但在用于諸如金屬材質(zhì)制成的物體時,則會顯得呆板帘饶,表現(xiàn)不出光澤哑诊,主要原因是該模型沒有考慮這些表面的鏡面反射效果。
如果光照射到相當(dāng)光滑的表面及刻,就產(chǎn)生鏡面反射(specular reflection)镀裤,鏡面反射的特點是在光滑表面會產(chǎn)生一塊稱之為高光(high light)的特亮區(qū)域 。
鏡面反射遵循光的反射定律:反射光與入射光位于表面法向兩側(cè)提茁,對理想反射面(如鏡面)淹禾,入射角等于反射角,觀察者只能在表面法向的反射方向一側(cè)才能看到反射茴扁。
5.4 Phong光照模型
Lambert模型能很好的表示粗糙表面的光照铃岔,但不能表現(xiàn)出鏡面反射高光。1975年P(guān)hong Bui Tong發(fā)明的Phong模型峭火,提出了計算鏡面高光的經(jīng)驗?zāi)P突傧埃R面反射光強與反射光線和視線的夾角a相關(guān):
Ispecular = KsIs(cos a) n
其中Ks為物體表面的高光系數(shù),Is為光強卖丸,a是反射光與視線的夾角纺且,n為高光指數(shù),n越大稍浆,則表面越光滑载碌,反射光越集中,高光范圍越小衅枫。如果V表示頂點到視點的單位向量嫁艇,R表示反射光反向,則cos a可表示為V和R的點積弦撩。模型可表示為:
Ispecular = KsIs(V●R) n
反射光放向R可由入射光放向L(頂點指向光源)和物體法向量N求出步咪。
R = (2N●L)N – L
Phong光照的另一種表現(xiàn)形式:
Ispec = IsKscosns α(α∈(0,90o))
Ks為物體表面某點的高亮光系數(shù)
ns為物體表面的鏡面反射指數(shù),反映了物體表面的光澤程度益楼, ns越大猾漫,表示物體越接近于鏡面点晴。
只有視線與光源在物體表面的反射光線非常接近時才能看到鏡面反射光,此時悯周,鏡面反射光將會在反射方向附近形成很亮的光斑粒督,稱為高光現(xiàn)象。ns越小队橙,表示物體越粗糙坠陈;當(dāng)ns為零時,鏡面反射光便退化為與視點捐康、光源均無關(guān)的環(huán)境光。
將鏡面反射光與環(huán)境光庸蔼、漫反射光疊加起來形成單一光源照射下更為真實的Phong光照模型:
I = Ia Ka+IdKdcosθ+IsKscosns α
θ :入射角
α :視線與鏡面反射方向的夾角
5.5 Blinn-Phong光照模型
Jim Blinn對Phong模型進行了改進解总,提出了Blinn-Phong模型。Blinn-Phong模型與Phong模型的區(qū)別是姐仅,把dot(V,R)換成了dot(N,H)花枫,其中H為半角向量,位于法線N和光線L的角平分線方向掏膏。Blinn-Phong模型可表示為:
Ispecular = KsIs pow(( dot(N,H), n )
其中H = (L + V) / | L+V |劳翰,計算H比計算反射向量R更快速。
Unity中馒疹,Phong實際上指的就是Blinn-Phong佳簸,兩者指的同一種內(nèi)置光照模型。
PS:光照模型部分的內(nèi)容主要參考為:http://cg.sjtu.edu.cn/
六颖变、custom lighting model(自定義光照模型)
光照模式(lighting model)無外乎是幾個Cg/HLSL函數(shù)的組合生均。
Unity內(nèi)置的 Lambert 和 Blinn-Phong模型的Shader源代碼
#ifndef LIGHTING_INCLUDED
#define LIGHTING_INCLUDED
struct SurfaceOutput {
fixed3 Albedo;
fixed3 Normal;
fixed3 Emission;
half Specular;
fixed Gloss;
fixed Alpha;
};
#ifndef USING_DIRECTIONAL_LIGHT
#if defined (DIRECTIONAL_COOKIE) || defined (DIRECTIONAL)
#define USING_DIRECTIONAL_LIGHT
#endif
#endif
// NOTE: you would think using half is fine here, but that would make
// Cg apply some precision emulation, making the constants in the shader
// much different; and do some other stupidity that actually increases ALU
// count on d3d9 at least. So we use float.
//
// Also, the numbers in many components should be the same, but are changed
// very slightly in the last digit, to prevent Cg from mis-optimizing
// the shader (it tried to be super clever at saving one shader constant
// at expense of gazillion extra scalar moves). Saves about 6 ALU instructions
// on d3d9 SM2.
#define UNITY_DIRBASIS \
const float3x3 unity_DirBasis = float3x3( \
float3( 0.81649658, 0.0, 0.57735028), \
float3(-0.40824830, 0.70710679, 0.57735027), \
float3(-0.40824829, -0.70710678, 0.57735026) \
);
inline half3 DirLightmapDiffuse(in half3x3 dirBasis, fixed4 color, fixed4 scale, half3 normal, bool surfFuncWritesNormal, out half3 scalePerBasisVector)
{
half3 lm = DecodeLightmap (color);
// will be compiled out (and so will the texture sample providing the value)
// if it's not used in the lighting function, like in LightingLambert
scalePerBasisVector = DecodeLightmap (scale);
// will be compiled out when surface function does not write into o.Normal
if (surfFuncWritesNormal)
{
half3 normalInRnmBasis = saturate (mul (dirBasis, normal));
lm *= dot (normalInRnmBasis, scalePerBasisVector);
}
return lm;
}
fixed4 _LightColor0;
fixed4 _SpecColor;
inline fixed4 LightingLambert (SurfaceOutput s, fixed3 lightDir, fixed atten)
{
fixed diff = max (0, dot (s.Normal, lightDir));
fixed4 c;
c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten * 2);
c.a = s.Alpha;
return c;
}
inline fixed4 LightingLambert_PrePass (SurfaceOutput s, half4 light)
{
fixed4 c;
c.rgb = s.Albedo * light.rgb;
c.a = s.Alpha;
return c;
}
inline half4 LightingLambert_DirLightmap (SurfaceOutput s, fixed4 color, fixed4 scale, bool surfFuncWritesNormal)
{
UNITY_DIRBASIS
half3 scalePerBasisVector;
half3 lm = DirLightmapDiffuse (unity_DirBasis, color, scale, s.Normal, surfFuncWritesNormal, scalePerBasisVector);
return half4(lm, 0);
}
// NOTE: some intricacy in shader compiler on some GLES2.0 platforms (iOS) needs 'viewDir' & 'h'
// to be mediump instead of lowp, otherwise specular highlight becomes too bright.
inline fixed4 LightingBlinnPhong (SurfaceOutput s, fixed3 lightDir, half3 viewDir, fixed atten)
{
half3 h = normalize (lightDir + viewDir);
fixed diff = max (0, dot (s.Normal, lightDir));
float nh = max (0, dot (s.Normal, h));
float spec = pow (nh, s.Specular*128.0) * s.Gloss;
fixed4 c;
c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * _SpecColor.rgb * spec) * (atten * 2);
c.a = s.Alpha + _LightColor0.a * _SpecColor.a * spec * atten;
return c;
}
inline fixed4 LightingBlinnPhong_PrePass (SurfaceOutput s, half4 light)
{
fixed spec = light.a * s.Gloss;
fixed4 c;
c.rgb = (s.Albedo * light.rgb + light.rgb * _SpecColor.rgb * spec);
c.a = s.Alpha + spec * _SpecColor.a;
return c;
}
inline half4 LightingBlinnPhong_DirLightmap (SurfaceOutput s, fixed4 color, fixed4 scale, half3 viewDir, bool surfFuncWritesNormal, out half3 specColor)
{
UNITY_DIRBASIS
half3 scalePerBasisVector;
half3 lm = DirLightmapDiffuse (unity_DirBasis, color, scale, s.Normal, surfFuncWritesNormal, scalePerBasisVector);
half3 lightDir = normalize (scalePerBasisVector.x * unity_DirBasis[0] + scalePerBasisVector.y * unity_DirBasis[1] + scalePerBasisVector.z * unity_DirBasis[2]);
half3 h = normalize (lightDir + viewDir);
float nh = max (0, dot (s.Normal, h));
float spec = pow (nh, s.Specular * 128.0);
// specColor used outside in the forward path, compiled out in prepass
specColor = lm * _SpecColor.rgb * s.Gloss * spec;
// spec from the alpha component is used to calculate specular
// in the Lighting*_Prepass function, it's not used in forward
return half4(lm, spec);
}
#ifdef UNITY_CAN_COMPILE_TESSELLATION
struct UnityTessellationFactors {
float edge[3] : SV_TessFactor;
float inside : SV_InsideTessFactor;
};
#endif // UNITY_CAN_COMPILE_TESSELLATION
#endif
七、光照模式的聲明方式
在Unity Shaderlab和CG語言中腥刹,光照模式是一個以Lighting開頭+自定義文字組合在一起的函數(shù)马胧。即,函數(shù)名為:
Lighting+ [自定義部分]
可以在著色器文件(shader file)或?qū)胛募?included files)中的任何一個地方聲明此函數(shù)衔峰。一般情況下佩脊,此函數(shù)有五種原型可供選擇,具體如下:
1.half4 LightingName (SurfaceOutput s, half3 lightDir, half atten);
此種形式的函數(shù)可以表示在正向渲染路徑(forward rendering path)中的光照模式垫卤,且此函數(shù)不取決于視圖方向(view direction)威彰。例如:漫反射(diffuse)。
2.half4 LightingName (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten);
此種形式的函數(shù)可以表示在正向渲染路徑(forward rendering path)中使用的光照模式葫男,且此函數(shù)包含了視圖方向(view direction)抱冷。
3.half4 LightingName_PrePass (SurfaceOutput s, half4 light);
此種形式的函數(shù)可以在延時光照路徑(deferred lighting path)中使用的。
4.half4 LightingName_DirLightmap(SurfaceOutput s, fixed4 color, fixed4 scale, bool surfFuncWritesNormal);
這種形式也是不依賴于視圖方向(view direction)的光照模式梢褐。例如:漫反射(diffuse)旺遮。
5.half4 LightingName_DirLightmap(SurfaceOutput s, fixed4 color, fixed4 scale, half3 viewDir, bool surfFuncWritesNormal,out half3 specColor);
這是使用的依賴于視圖方向(view direction)的光照模式(light model)赵讯。
ps:對于形式四和形式五的選擇,主要取決于光照模式(light model)是否依賴視圖方向(view direction)耿眉。需要注意的是边翼,這兩個函數(shù)將自動處理正向和延時光照路徑(forwardand deferred lighting rendering paths)。
ps: Unity在移動平臺中暫時不支持延遲光照渲染鸣剪。
ps:在自定義自己的光照模型函數(shù)時组底,根據(jù)需要在五種函數(shù)原型中選擇一種,且:
光照模式的函數(shù)名為:Lighting+ [自定義函數(shù)名]
pragma聲明為: #pragmasurface surf [自定義函數(shù)名]
然后就需要仿照著其他的光照模式來填充函數(shù)體