您好,登錄后才能下訂單哦!
之前在“ShaderLab學(xué)習(xí)小結(jié)(三)漫反射+高光+點光源”中
用了Shade4PointLights()函數(shù)來計算點光源的反射。
這個函數(shù)定義在unitycg.cginc中,其中用到的前八個參數(shù)來自于UnityShaderVariables.cginc。
在這個例子中,只一個pass就實現(xiàn)了平行光、點光源反射,以及高光反射。
后來在學(xué)習(xí)中,接觸到另一種點光源反射的例子,用到兩個pass,第一個pass實現(xiàn)平行光的,第二個實現(xiàn)點光源的
Shader "Custom/TestLightColor0" {
SubShader {
pass{
tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "unitycg.cginc"
#include "lighting.cginc"
struct v2f{
float4 pos:POSITION;
float3 normal:NORMAL;
float3 wpos:TEXCOORD0;
};
v2f vert(appdata_base v)
{
v2f o;
o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
o.normal=UnityObjectToWorldNormal(v.normal);
o.wpos=mul(unity_ObjectToWorld, v.vertex).xyz;
return o;
}
fixed4 frag(v2f IN):COLOR
{
float3 N = IN.normal;
float3 L = normalize(_WorldSpaceLightPos0).xyz;
float ndotl=saturate(dot(N,L));
fixed4 col=_LightColor0*ndotl;
col+=UNITY_LIGHTMODEL_AMBIENT;
return col;
}
ENDCG
}
pass{
tags{"LightMode"="ForwardAdd"}
blend one one
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "unitycg.cginc"
#include "lighting.cginc"
struct v2f{
float4 pos:POSITION;
float3 normal:NORMAL;
float3 wpos:TEXCOORD0;
};
v2f vert(appdata_tan v)
{
v2f o;
o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
o.normal=UnityObjectToWorldNormal(v.normal);
o.wpos=mul(unity_ObjectToWorld, v.vertex).xyz;
return o;
}
fixed4 frag(v2f IN):COLOR
{
float3 N = IN.normal;
float3 L = normalize(_WorldSpaceLightPos0).xyz;
float ndotl=saturate(dot(N,L));
float atten=1;
if(_WorldSpaceLightPos0.w!=0)
{
atten = 1.0/length(_WorldSpaceLightPos0.xyz);
}
fixed4 col=_LightColor0*ndotl*atten;
return col;
}
ENDCG
}
}
}
兩個pass幾乎一樣,叫pass1和pass2吧。pass1是forwardbase,pass2是forwardadd,pass2還要用上blend one one,不然pass1的光照就沒了,因為pass1中加了環(huán)境光LIGHT_MODEL_AMBIENT,pass2中就不用再加了。
共同點,都用的是_LightColor0。之前學(xué)習(xí)時,認(rèn)為_LightColor0就是指的平行光,所以點光源要用Shade4PointLights,但現(xiàn)在看來并不是。在網(wǎng)上搜索的結(jié)果之一:
LightMode=ForwardBase: _LightColor0將會是主要的directional light的顏色。
LightMode=ForwardAdd: _LightColor0將是該逐像素光源的顏色。
也就是說在lightmode為forwardadd的pass里,_LightColor0代表不同的光源
pass2中多定義了一個衰減系數(shù)atten,且進(jìn)行判斷賦值
float atten=1;
if(_WorldSpaceLightPos0.w!=0)
{
atten = 1.0/length(_WorldSpaceLightPos0.xyz);
}
點光源和平行光不同,與物體距離不同反射的強度也不同,所以這個顏色要乘一個衰減系數(shù)。
fixed4 col=_LightColor0*ndotl*atten;
當(dāng)然這個只是簡單寫的一個衰減系數(shù)
這個衰減系數(shù)的計算算是抄來的吧,稍做修改
原出處用的是
atten = 1.0/length(IN.LightDir);
顯然這個LightDir是在結(jié)構(gòu)體中要定義,float3型
float3 LightDir:TEXCOORD1;
代表光的方向,且在頂點程序中要轉(zhuǎn)化到切線空間
即
v2f vert(appdata_tan v)
{
...
TANGENT_SPACE_ROTATION;
o.LightDir=mul(rotation, ObjSpaceLightDir(v.vertex));
...
}
也就是計算衰減系數(shù)時,length()函數(shù)中的參數(shù),我為了更加簡化,直接用了_WorldSpaceLightPos0.xyz,就省去了上面那一堆。
最后結(jié)果如下兩圖,點光源為×××
把兩個球體放在同一個位置,分別單獨顯示
上邊的是兩個通道出來的,下邊的是一個通道Shade4PointLights出來的
兩個球體都反射了平行光和點光源,看上去兩個的漫反射的效果基本一樣
下面的球體暗部邊緣處更黑一些
注:本例只做漫反射
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。