opengl 不同光源下三種反射光的計算

2021-09-13 18:49:10 字數 3577 閱讀 8413

平行光源:如太陽光源,類似於燈源在無窮遠處,照射物體的各個地方光照強度相同,光照方向也相同。

點光源:離物體有限距離,且燈光會隨著距離衰減,物體表面光照方向不同。

聚光燈:如 手電筒照在乙個圓圈上,周圍衰減。(這裡光照計算暫不介紹)

vec4 ambientcolor=u_lightambient*u_ambientmaterial;
1、平行光源

由圖可見,太陽是平行光源,我們的反光照強度與入射光與法向量的夾角有關,因此可以利用向量ab 和 an的乘積(綠色箭頭向量,入射方向的反方向)來表示反射光大小,當然 最小值為0,即沒有反射光。

unitform vec4 u_ligthtpos;

uniform vec4 u_diffuselightcolor;

uniform vec4 udiffusematerial;

varying vec4 v_diffusecolor;

void main()

2、點光源1、點光源與平行光源不同,它的l向量計算方法不同,是由平面上點 和 燈源位置組成l向量

vec4 specularcolor=vec4(0.0,0.0,0.0,0.0);

if(diffuseindensity>0.0)

2、衰減係數 有3個 constantfactor、linea***ctor、expfactor這些是常量值,靠經驗值來設定,後面2個常量分別與燈光的距離和距離的平方乘積構成衰減係數。

float attenuation=1.0;

//light attribute

float constantfactor=0.5;

float linea***ctor=0.3;

float expfactor=0.1;

l=u_lightpos.xyz-v_worldpos;

distance=length(l);

attenuation=1.0/(constantfactor+linea***ctor*distance+expfactor*distance*distance);

l=normalize(l);

//n vector

vec3 n=normalize(v_normal);

float diffuseintensity=max(0.0,dot(l,n));

vec4 diffusecolor=u_diffuselightcolor*u_diffusematerial*diffuseintensity*attenuation;

平行光 和 點光源的計算方法除了上面l的計算法方法不一樣外,其餘的一樣。計算方法在下面的blin-phong講到了,就是反射光向量與點和眼睛的向量乘積作為底數,32為常量設定。見blin的影象 ac 和 ad的乘積

反射光線的向量利用reflect函式來計算得到,引數為入射光的方向向量 和 法向量 (都歸一化了)。

// 計算鏡面反射

vec4 specularcolor=vec4(0.0,0.0,0.0,0.0);

if(diffuseindensity>0.0)

reflect 計算反射向量複雜度比較高,blin-phong模型就是針對這裡進行的乙個簡化計算。

該模型主要是針對求鏡面反射光線向量來簡化,如下圖

藍色d為眼睛的位置,然後鏡面反射的強度為 反射光纖 與 眼睛和點a的夾角來表示,越小強度越大,因此用向量ad與ac的乘機表示,但反射角計算量大,這裡利用 ab 與 an的和 計算得到 中間的ae, 用 ae乘以an來代替 ac乘以ad。attenuation為衰減係數,跟上面的點光源的attenuation是一樣的。

//reflection

vec3 halfvector=l+viewdir;

halfvector=normalize(halfvector);

specularintensity=pow(max(0.0,dot(n,halfvector)),128.0);

vec4 specularcolor=u_specularlightcolor*u_specularmaterial*specularintensity*attenuation;

這裡給出乙個完整的iblind-phone shader的模型,其中利用u_lightpos.w==0.0 來判斷是否為平行光還是點光源的。

uniform vec4 u_lightpos;

uniform vec3 u_eyepos;

uniform vec4 u_ambientlightcolor;

uniform vec4 u_ambientmaterial;

uniform vec4 u_diffuselightcolor;

uniform vec4 u_diffusematerial;

uniform vec4 u_specularlightcolor;

uniform vec4 u_specularmaterial;

varying vec3 v_normal;

varying vec3 v_worldpos;

void main()

else

l=normalize(l);

//n vector

vec3 n=normalize(v_normal);

float diffuseintensity=max(0.0,dot(l,n));

vec4 diffusecolor=u_diffuselightcolor*u_diffusematerial*diffuseintensity*attenuation;

//specular

//inverse view direction : object->eye

vec3 viewdir=u_eyepos-v_worldpos;

viewdir=normalize(viewdir);

//reflection

vec3 halfvector=l+viewdir;

halfvector=normalize(halfvector);

float specularintensity=0.0;

if(diffuseintensity==0.0)

else

vec4 specularcolor=u_specularlightcolor*u_specularmaterial*specularintensity*attenuation;

gl_fragcolor=ambientcolor+diffusecolor+specularcolor;

}

unity三種光源解決方案

一。unity三種解決方案 1.subtractive模式 動態物體 主光實時,環境光diffuse項lightprobe提供,高光項由reflectionprobe提供。陰影通過shadowmap提供。靜態物體產生在動態物體的陰影由lightprobe提供 靜態物體沒有高光,環境光diffuse項...

三種不同SSH隧道

想通過ssh隧道連線遠端機器的vnc服務,對ssh l命令不太熟悉,man ssh後發現3組與隧道 turnnel 相關的引數 ssh d,ssh l,ssh r,一下子就搞糊塗了,所有下決心仔細研究一番。ssh隧道有3種型別 動態埠 動態埠允許通過配置乙個本地埠,把通過隧道到資料 到遠端的所有位址...

三種不同的分頁方式

習慣了ext的ext.grid.gridpanel與ext.data.store封裝好了的分頁方式以及 ajax處理方式 ext.ajax.request success function response,action 和對後台響應json的處理 ext.ajax.request success ...