OpenGL ES 光照計算

  • 光照計算在片元著色器執(zhí)行,計算每一個像素點(diǎn)的顏色

一、光照計算

1、環(huán)境光計算

環(huán)境光 = 光源的環(huán)境光顏色 * 物體的材質(zhì)顏色

  • 環(huán)境光 = 光的顏色 * 材質(zhì)顏色;
    光是有顏色的,比如紅光、綠光等;
    材質(zhì)顏色也就是紋理顏色。

2、發(fā)射光的計算

發(fā)射顏色 = 物體的反射材質(zhì)顏色

  • 物體本身是有顏色的,比如手電筒,其本身能發(fā)光,發(fā)出的光的顏色就是發(fā)射顏色。

3、漫反射光照計算

  • 光照有陰面和陽面,由法線計算光與物體之間的夾角,這個夾角分為入射角和反射角

漫反射顏色 = 光源的漫反射顏色 * 物體的漫反射材質(zhì)顏色 * DiffuseFactor

DiffuseFactor = max(0, dot(N, L));

  • 漫反射因子DiffuseFactor 是光線與頂點(diǎn)法線向量的點(diǎn)積,是光線與法線之間的夾角,其值不能小于0

4、鏡面光計算

鏡面反射顏色 = 光源的鏡面光顏色 * 物體的鏡面材質(zhì)顏色 * SpecularFactor

SpecularFactor = power(max(0, dot(N, H)), shininess);
H:視線向量E 與光線向量L 的半向量
dot(N, H):H,N的點(diǎn)積幾何意義,平方線與法線夾角的cos值
shininess:高光的反光度

  • 鏡面因子SpecularFactor,shininess反光度越小光照越集中

5、普通光照計算

光照顏色 = (環(huán)境顏色 + 漫反射顏色 + 鏡面反射顏色) * 衰減因子

衰減因子計算

衰減因子 = 1.0 / (距離衰減常量 + 線性衰減常量 * 距離 + 二次衰減常量 * 距離的平方)
距離衰減常量、線性衰減常量和二次衰減常量均為常量值

tips:環(huán)境光、漫反射光和鏡面光的強(qiáng)度都會受距離的增大而衰減,只有發(fā)射光和全局環(huán)境光的強(qiáng)度不會受影響

6、聚光燈因子

聚光燈夾角cos值 = power(max(0, dot(單位光源位置, 單位光線向量)), 聚光燈指數(shù));

單位光線向量:是從光源指向頂點(diǎn)的單位向量
聚光燈指數(shù):表示聚光燈的亮度程度
公式解讀:單位光源位置 * 單位光線向量 點(diǎn)積 的 聚光燈指數(shù)次方

  • 增加過渡計算
    聚光燈因子 = clamp((外環(huán)的聚光燈角度cos值 - 當(dāng)前頂點(diǎn)的聚光燈角度cos值) / (外環(huán)的聚光燈角度cos值 - 內(nèi)環(huán)聚光燈的角度cos值), 0.1);

7、光照計算終極公式

光照顏色 = 發(fā)射顏色 + 全局環(huán)境顏色 + (環(huán)境顏色 + 漫反射顏色 + 鏡面顏色) * 聚光燈效果 * 衰減因子

平面光終極公式

  • 平面光也就是平行光,沒有具體的方向

點(diǎn)光源終極公式

  • 比如燈泡光源,點(diǎn)光源是有方向的

二、光照的GLSL實(shí)現(xiàn)

1、環(huán)境光的GLSL實(shí)現(xiàn)

varying vec3 objectColor;
void main() {

    //至少有10%的光照到物體所有面
    float ambientStrength = 0.1;

    //環(huán)境光顏色 = 環(huán)境光比率 * 環(huán)境光顏色
    vec3 ambient = ambientStrength * lightColor;

    //最終顏色 = 環(huán)境光顏色 * 物體顏色
    vec3 result = ambient * objectColor;
    //vec3轉(zhuǎn)化成vec4
    gl_FragColor = vec4(result, 1.0);

}

2、漫反射光的GLSL實(shí)現(xiàn)

uniform vec3 lightColor;     //光源顏色
uniform vec3 lightPo;         //光源位置
uniform vec3 objectColor; //物體顏色
uniform vec3 viewPo;        //物體位置
varying vec3 outNormal;  //傳入當(dāng)前頂點(diǎn)平面的法向量

//確保法線為單位向量,normalize為內(nèi)建函數(shù),把法向量轉(zhuǎn)換成單位向量
vec3 norm = normalize(outNormal);
//頂點(diǎn)指向光源的單位向量
vec3 lightDir = normalize(lightPo -   FragPo);
//得到兩向量的cos值,小于0則為0
float diff = max(dot(norm, lightDir), 0.0);
//夾角乘以光照顏色得到漫反射的光源向量
vec3 diffuse = diff * lightColor;

vec3 result = diffuse * objectColor;
gl_FragColor = vec4(result, 1.0);

3、鏡面光的GLSL實(shí)現(xiàn)

//鏡面強(qiáng)度
float specularStrength = 0.5;

//頂點(diǎn)指向觀察點(diǎn)的單位向量
vec3 viewDir = normalize(viewPo - FragPo);

//光線在頂點(diǎn)的反射線(傳入光源指向頂點(diǎn)的向量),鏡面光是反方向的光線
vec3 reflectDir = reflect(-lightDir, outNormal);

//夾角cos值,取256次冪,鏡面因子
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 256.0);

vec3 specular = specularStrength * spec * lightColor;

4、衰減因子計算

//距離衰減常量
float constantPara = 1.0;
//線性衰減常量
float linearPara = 0.09;
//二次衰減因子
float quadraticPara = 0.032;
//距離
float lightWeakPara = 1.0/(constantPara + linearPara * LFDistance + quadraticPara * (LFDistance * LFDistance));

5、聚光燈過渡計算

//一些復(fù)雜的計算操作應(yīng)該讓CPU做以提高效率,不變的量也建議外部傳輸,避免重復(fù)計算
//內(nèi)錐角cos值
float inCutoff = cos(radians(10.0));
//外錐角cos值
float outCutoff = cos(radians(15.0));
//聚光朝向
vec3 spotDir = vec3(-1.2, -1.0, -2.0);

//光源指向物體的向量和聚光朝向的cos值
float theta = dot(lightDir, normalize(-spotDir));
//內(nèi)外錐角cos差值
float epsilon = inCutoff - outCutoff;

//clamp(a, b, c);若b<a<c則函數(shù)返回a,若不是則返回最小b,最大c
/*(theta - outCutoff)/epsilon 若theta的角度小于內(nèi)錐角則其值>=1,
若theta的角度大于外錐角則其值<=0,這樣光線就在內(nèi)外錐角之間平滑變化*/
float intensity = clamp((theta - outCutoff) / epsilon, 0.0, 1.0);

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

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

  • 光照是OpenGL ES里很重要的一部分,下面我們來學(xué)習(xí)總結(jié)一下如何計算不同的光照效果。 光照基礎(chǔ)1?環(huán)境光照2?...
    jakeXu閱讀 752評論 1 14
  • 光照基礎(chǔ) 環(huán)境光 漫反射光 鏡面光 光照特性 發(fā)射光:由物體自身發(fā)光 環(huán)境光:環(huán)境中充分散射的光,而且無法分辨它的...
    JunkieBa閱讀 502評論 0 0
  • 現(xiàn)實(shí)世界的光照是極其復(fù)雜的,而且會受到諸多因素的影響,這是以目前我們所擁有的處理能力無法模擬的。因此OpenGL的...
    zhongxiaoyue閱讀 798評論 0 1
  • 馮氏光照模型:主要結(jié)構(gòu)由3個元素組成:環(huán)境(Ambient)光照、漫反射(Diffuse)光照和鏡面(Specul...
    盾子閱讀 638評論 0 0
  • 一朵紅花 文/付朝蘭 一朵鮮艷的紅花 開在小小綠葉下 靜靜等待有緣人 花錢把她抱回家
    付朝蘭閱讀 1,118評論 16 25

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