OpenGL ES 光照模型(二)

OpenGL固定管線中默認(rèn)的光照類似于將三種光照分量組合起來:環(huán)境光+漫反射+鏡面反射。
其中漫反射之前就說過了。環(huán)境光和光源之于頂點(diǎn)的入射角度無關(guān),僅僅與物體本身的反射系數(shù)相關(guān)。本身也非常好理解,給出公式如下


Ambient公式
鏡面反射模型如下圖所示


Specular模型
怎么理解這個(gè)模型呢。鏡面反射模型中,最終我們看到的光照強(qiáng)度是光源向量與頂點(diǎn)法線的反射向量的點(diǎn)積。想象一下拿著光束照鏡子,與光束的反射角越大,則越不刺眼,就能理解這個(gè)模型了。模型的公式為

鏡面反射公式
公式本身是很好理解的,其中系數(shù)f為鏡面反射系數(shù)。類似物體的光滑程度吧,相同角度的光源照射在石塊上的反射光強(qiáng)度和玻璃上的反射光強(qiáng)度是不同的。這里就通過這個(gè)鏡面反射系數(shù)f來決定。
這個(gè)模型稱為Phong反射模型。最終公式如下:


Phong
有了公式之后剩下的就是代碼實(shí)現(xiàn)了。這里給出關(guān)鍵的shader代碼——
先上vertex shader的
attribute vec3 vertPosition;
attribute vec3 vertNormal;

varying vec3 lightIntensity;

struct LightInfo {
    vec3 Position;  // Light position in eye - coordinate
    vec3 La;        // Ambient light intensity
    vec3 Ld;        // Diffuse light intensity
    vec3 Ls;        // Sepcular light intesity
};
uniform LightInfo light;

struct MaterialInfo {
    vec3 Ka;        // Ambient reflectivity
    vec3 Kd;        // Diffuse reflectivity
    vec3 Ks;        // Specular reflectivity
    float Shininess;// Specular shininess factor
};
uniform MaterialInfo material;

uniform mat3 normMat;
uniform mat4 modelview;
uniform mat4 projection;

void main() {
    vec3 tnorm = normalize(normMat * vertNormal);
    vec3 eyecoord = vec3(modelview * vec4(vertPosition, 1.0));
    vec3 s = normalize(light.Position - eyecoord);
    vec3 v = normalize(-eyecoord.xyz);
    vec3 r = reflect(-s, tnorm);
    vec3 ambient = light.La * material.Ka;
    float sDotN = max(dot(s, tnorm), 0.0);
    vec3 diffuse = light.Ld * material.Kd * sDotN;
    vec3 spec = vec3(0.0);
    if (sDotN > 0.0)
        spec = light.Ls * material.Ks * pow(max(dot(r, v), 0.0), material.Shininess);
    lightIntensity = ambient + diffuse + spec;
    gl_Position = projection * modelview * vec4(vertPosition, 1.0);
}

OpenGL ES shading 語法類似C的語法。結(jié)構(gòu)體定義是一樣的。首先定義了表示光源的結(jié)構(gòu)體LightInfo以及相關(guān)的光源坐標(biāo)、三種光的反射強(qiáng)度,然后是材質(zhì)結(jié)構(gòu)MaterialInfo以及相關(guān)三種光的材質(zhì)反射系數(shù)以及鏡面光反射系數(shù)Shininess,然后是變換矩陣。
其他的語句不過多解釋了,和之前的處理差不多。

    vec3 v = normalize(-eyecoord.xyz);

這里取頂點(diǎn)坐標(biāo)的反向向量是因?yàn)樵谟^察坐標(biāo)下,要計(jì)算反射光和觀察點(diǎn)的角度,換句話來說,就是從頂點(diǎn)發(fā)射出去的光和從頂點(diǎn)到觀察點(diǎn)的向量之間的夾角的余弦值才是我們要的值。
接下來給出Fragment shader的代碼

precision mediump float;

varying vec3 lightIntensity;

void main() {
    gl_FragColor = vec4(lightIntensity, 1.0);
}

這個(gè)代碼和OpenGL ES 光照模型(一)是一樣的。
猛戳代碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 版本記錄 前言 OpenGL 圖形庫項(xiàng)目中一直也沒用過,最近也想學(xué)著使用這個(gè)圖形庫,感覺還是很有意思,也就自然想著...
    刀客傳奇閱讀 6,482評(píng)論 0 2
  • 一.標(biāo)準(zhǔn)光照模型OpenGL與Direct3D提供了幾乎相同的固定功能光照模型。什么是固定功能光照模型?在過去只有...
    karma085閱讀 3,866評(píng)論 0 2
  • 一、四大光照類型1.環(huán)境光(Ambient Light) 一個(gè)物體即使沒有直接被光源照射,但是只要有光線通過其他物...
    CarlDonitz閱讀 1,626評(píng)論 0 0
  • 在講Unity光照模型之前,先介紹圖形學(xué)中的兩個(gè)基礎(chǔ)光照模型原理,將會(huì)更利于我們理解和使用Unity中的光照模型。...
    Unity云中客閱讀 3,640評(píng)論 1 6
  • 他六歲的時(shí)候,父母去世了,一位族叔說,走,我?guī)阋埲?。他與族叔離開了有著一條河,河上有座橋,橋邊有棵樹的村莊。一...
    purpleyang閱讀 323評(píng)論 7 3

友情鏈接更多精彩內(nèi)容