WebGL-學(xué)習(xí)筆記(五)

WebGL學(xué)習(xí)筆記(五).png

1. 光照和反射

要知道看到的物體的顏色實際上是物體反射的光的顏色曹阔,物體吸收了部分頻率的光玷犹,將不能吸收的光進行了反射儡循,從而我們看到了對應(yīng)物體呈現(xiàn)的顏色舶吗。
光照對于構(gòu)建一個三維圖形有著很大的影響,所以首先一起來討論一下基本的光照類型以及反射類型择膝。

1.1 光照類型

光照類型有很多誓琼,根據(jù)光源的不同以及發(fā)射出來的光線的特性,有三種最常用的:平行光源肴捉,點光源腹侣,環(huán)境光源

1.1.1 平行光源

平行光源光線是平行的,太陽光可以認為是平行光源齿穗。其實將一個點光源放在無限遠處筐带,那么最后我們所看到的光基本就是處于平行的,所以平行光源是點光源的極限狀態(tài)缤灵,同一表面上點對光的處理是一樣的(反射角度一樣)

1.1.2 點光源

點光源的特點就是光源是點狀伦籍,發(fā)射出來的光線角度是不一致的,同一表面上每個點對光線的處理會不同腮出。

1.1.3 環(huán)境光源

環(huán)境光源是墻面反射光線以后照射到物體表面的光帖鸦,環(huán)境光對于物體所有表面每一個點增加的強度可以認為是一致的。

1.2 反射類型

1.2.1 漫反射

漫反射是針對平行光源和點光源而言胚嘲,特點就是將物體默認為是類似鏡面的物體作儿,所有的光會以固定的角度反射回去。漫反射是一種理想的反射條件馋劈,忽略了物體本身材質(zhì)的影響(例如巖石攻锰,紙張會是斑駁的晾嘶,現(xiàn)實中沒有完全的鏡面,反射角度都不是固定的)
對于漫反射而言娶吞,我們看到的物體所呈現(xiàn)的顏色垒迂,其實就是:
漫反射顏色 = 入射光顏色 * 物體表面基底色 * cosx
其中的cosx是指入射光與物體表面的夾角。

1.2.2 環(huán)境反射

環(huán)境反射是針對環(huán)境光源而言妒蛇,可以認為光線均勻的鋪在物體表面机断,物體反射出的光線無論什么角度強度都是一樣的,其計算公式為:
環(huán)境反射顏色 = 入射光顏色 * 物體表面基底色

PS:于是最后物體反射的顏色(反射的顏色也就是我們看到的顏色)公式:物體反射顏色 = 漫反射顏色 + 環(huán)境反射顏色

2. 光照計算

于是在在WebGL中绣夺,根據(jù)光照類型以及對應(yīng)光照類型的反射特性來計算對應(yīng)物體的光照效果

2.1 平行光計算

平行光的反射類型是漫反射吏奸,所以根據(jù)漫反射公式,如果要計算物體表面顏色陶耍,那么需要指定到三個數(shù)據(jù):入射光顏色奋蔚,物體表面基底色,入射光角度烈钞。
入射光顏色我們和物體表面基底色在我們創(chuàng)建光源和物體表面的時候就可以進行指定泊碑,于是主要需要計算的部分就是入射光角度。
平行光的入射光角度是光源和物體表面的夾角棵磷,要根據(jù)入射光方向和物體表面朝向(法線方向)計算,其實并不容易晋涣。不過所幸可以通過矢量的點積的方式來計算出對應(yīng)入射角的余弦值(自己線性代數(shù)基本上忘了差不多了仪媒,補習(xí)中,不能很好說明為什么矢量的點積可以計算出這個結(jié)果)谢鹊。
于是說了那么多就變成了一下幾點:

  1. 獲取到表面的法線方向
  2. 光線方向和法線方向計算點積

也就是最后的計算公式就是
平行光漫反射 = 入射光顏色 * 物體表面基底色 * dot( 光線方向 * 法線方向)
以正方體且法線方向就是x,y,z軸的正負方向為例算吩,那么著色器中需要做的就是將我們的計算公式:

// VertexShader中增加
void main () {
    ...
    attribute vec4 a_Normal; // 法向量
    uniform vec3 u_LightDIrection; // 光線方向(歸一化)
    uniform vec3 u_LightColor; // 光線顏色
    
    // 法向量歸一化
    vec3 normal = normalize(vec3(a_Normal))
    // 點積計算
    float nDotL = max(dot(u_LightDirection, normal), 0.0);
    // 顏色計算
    vec3 diffuse = u_LightColor * vec3(a_Color) * nDotL
    v_Color = vec4(diffuse, a_Color.a);
}

需要注意的是這里的在進行點積計算的時候,法線和光線方向一定都要首先經(jīng)過歸一化佃扼,變成單位矢量后進行計算偎巢,所以u_LightDirection也要進行歸一化處理

2.2 環(huán)境光的疊加

環(huán)境光之前說是均勻的,所以環(huán)境光只需要入射光顏色和物體表面顏色進行確定兼耀,所以如果疊加上環(huán)境光压昼,反射光的計算公式就變?yōu)椋?br> 漫反射 = 入射光顏色 * 物體表面基底色 * dot( 光線方向 * 法線方向)+ 環(huán)境入射光顏色 * 物體表面基底色
所以頂點著色器中繼續(xù)增加環(huán)境光只需要

...
uniform vec3 u_AmbientLight;
vec3 ambient = u_AmbientLight * a_Color.rgb;
v_Color = vec4(diffuse + ambient, a_Color.a);
...

2.3 點光源點處理

點光源其實原理和平行光源類似,只是由于點光源的每個點的反射角度不同瘤运,所以不設(shè)定一個統(tǒng)一的光線方向窍霞,需要將平行光的光源方向變量u_LightDirection替換為,光源坐標(biāo)和表面頂點位置的矢量計算結(jié)果

// VertexShader中增加
void main () {
    ...
    uniform vec3 u_LightPosition; // 光源位置
    ...
    // 計算光線方向
    vec3 lightDirection = normalize(u_LightPosition - vec3(a_Position))
    // 將u_LightDirection替換為lightDirection進行點積計算
    float nDotL = max(dot(lightDirection, normal), 0.0);
}

2.4 片元著色器內(nèi)插隊光照計算的影響

剛才都是將計算放在頂點著色器內(nèi)進行拯坟,但是由于片元著色器的內(nèi)插過程影響但金,所以如果在頂點著色器內(nèi)渲染,內(nèi)插過程會出現(xiàn)偏差失真郁季,于是冷溃,要將在頂點著色器中渲染的內(nèi)容放到片元著色器中通過頂點和法向量的內(nèi)插值進行計算钱磅。

// VertexShader中計算光線方向和法線方向
void main () {
    ...
    varying vec3 v_Position;
    varying vec3 v_Normal;
    varying vec4 v_Color;
    // 計算光線方向
    v_Position = a_Position;
    v_Normal = normalize(a_Normal);
    v_Color = a_Color;
}
// FragmentShader色器
void main () {
    ...
    varying vec3 v_Position;
    varying vec3 v_Normal;
    varying vec4 v_Color;
    uniform vec3 u_LightPosition; // 光源位置
    uniform vec3 u_LightColor; // 光線顏色
    
    // 法向量歸一化
    vec3 normal = normalize(v_Normal)
    // 計算光線方向
    vec3 lightDirection = normalize(u_LightPosition - v_Position)
    // 將u_LightDirection替換為lightDirection進行點積計算
    float nDotL = max(dot(lightDirection, normal), 0.0);
    // 顏色計算
    vec3 diffuse = u_LightColor * vec3(v_Color) * nDotL
    gl_FragColor = vec4(diffuse, v_Color.a);
}

3. 總結(jié)

總的來說要計算光照對物體的影響,需要獲取到光線方向(光源位置)和法線方向似枕,通過物體漫反射光計算公式進行計算

這是基本上WebGL入門學(xué)習(xí)筆記的最后一期盖淡,雖然還有很多學(xué)習(xí)到的其他特性并沒有記錄,但是在接下來會用各種具體實現(xiàn)的事例的方式來解決具體問題

4. 參考

《WebGL編程指南》

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末菠净,一起剝皮案震驚了整個濱河市禁舷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌毅往,老刑警劉巖牵咙,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異攀唯,居然都是意外死亡洁桌,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進店門侯嘀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來另凌,“玉大人,你說我怎么就攤上這事戒幔》托唬” “怎么了?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵诗茎,是天一觀的道長工坊。 經(jīng)常有香客問我,道長敢订,這世上最難降的妖魔是什么王污? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮楚午,結(jié)果婚禮上昭齐,老公的妹妹穿的比我還像新娘。我一直安慰自己矾柜,他們只是感情好阱驾,可當(dāng)我...
    茶點故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著怪蔑,像睡著了一般啊易。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上饮睬,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天租谈,我揣著相機與錄音,去河邊找鬼。 笑死割去,一個胖子當(dāng)著我的面吹牛窟却,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播呻逆,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼夸赫,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了咖城?” 一聲冷哼從身側(cè)響起茬腿,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎宜雀,沒想到半個月后切平,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡辐董,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年悴品,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片简烘。...
    茶點故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡苔严,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出孤澎,到底是詐尸還是另有隱情届氢,我是刑警寧澤,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布覆旭,位于F島的核電站退子,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏姐扮。R本人自食惡果不足惜絮供,卻給世界環(huán)境...
    茶點故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一衣吠、第九天 我趴在偏房一處隱蔽的房頂上張望茶敏。 院中可真熱鬧,春花似錦缚俏、人聲如沸惊搏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽恬惯。三九已至,卻和暖如春亚茬,著一層夾襖步出監(jiān)牢的瞬間酪耳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留碗暗,地道東北人颈将。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像言疗,于是被迫代替她去往敵國和親晴圾。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,107評論 2 356

推薦閱讀更多精彩內(nèi)容