博客專欄

EEPW首頁 > 博客 > Chai 3D之燈光與陰影

Chai 3D之燈光與陰影

發(fā)布人:ygtu 時間:2023-03-14 來源:工程師 發(fā)布文章

推薦:將 NSDT場景編輯器 加入你的3D開發(fā)工具鏈

介紹

??光是人類可以視覺感知的任何事物的視覺表示背后的最重要的思想。光感知的概念在于,你所看到的不是基于你正在觀看的物體,而是基于光源投射并從這些物體反射的光線。重要的是要注意,你的眼睛不會直接看到物體,因為你的眼睛和這些物體之間沒有物理相關性。

??當然,所有這些都是理論上的。我們使用術語光線只是抽象出更復雜的機制。

??光線通常來自能量來源,例如太陽或房間內的燈。重要的是要注意,從理論上講,光線沿直線傳播,當您在視覺上感知物體時,您的眼睛吸收的是該物體反射或散射的光線。

光的抽象類型

??以下術語描述了在對需要光源的 3D 應用程序進行編程時必須了解的不同類型的光。了解每種類型的光在渲染的 3D 對象表面上產生的效果非常重要。創(chuàng)建這些術語是因為需要描述光對物體產生的某些效果,以便提煉出光的復雜數(shù)學計算。然而,這并不意味著這些確切類型的光實際上存在于自然界中,我們只是將它們視為光投射在不同材料上時可能產生的效果的抽象。計算光的真實機制及其在自然界中的工作方式將非常耗時,因此,OpenGL 通常采用這組常見的光類型:環(huán)境光、漫射光和鏡面光。****光與其他光不同,是物體發(fā)出的光的類型,而其他三種類型的光通常用于描述光源。讓我們詳細看看這些類型的光:

將環(huán)境、漫反射和鏡面反射分量組合在一起

環(huán)境光

??被環(huán)境光照亮的 3D 球體看起來只有 2D。環(huán)境光是由照明區(qū)域周圍(或位于照明區(qū)域內部)的所有光源****光而產生的平均光量。當陽光穿過房間的窗戶時,它們會打到墻壁上,反射并散射到各個不同的方向,平均照亮整個房間。這種視覺質量由環(huán)境光描述。僅環(huán)境光無法傳達在 3D 空間中設置的對象的完整表示,因為所有頂點都由相同的顏色均勻照明,并且對象看起來像是二維的,如上圖所示。盡管顯示的對象實際上是一個 3D 球體,但當僅由環(huán)境光照亮時,它在屏幕上看起來是平坦的。

漫反射光

??紅色的漫射光投射到定義其 3D 形狀的黑色物體上。

??漫射光表示光源投射的定向光。漫射光可以描述為在空間中具有位置并且來自單個方向的光。手電筒稍微高于它所照亮的物體,可以被認為是****漫射光。在上圖中,投射紅色漫射光的光源位于物體的左側。當漫射光接觸物體表面時,它會在該表面上均勻地散射和反射。

??為了演示環(huán)境光和漫射光如何協(xié)同工作以創(chuàng)建看起來更逼真的對象,請想象一個 3D 球體,其上散布著深紅色的環(huán)境光:

??現(xiàn)在,通過將漫射光源放置在球體的右側,我們得到以下結果:

??請注意球體現(xiàn)在看起來是 3D 的。

鏡面光

??除了環(huán)境光層和漫反射層外,此處還顯示鏡面反射(或鏡面反射高光)。您可以觀察到鏡面反射光源屬性如何大大增強對象的 3D 表示。 就像漫射光一樣,鏡面反射光是一種定向光。它來自一個特定的方向。

??兩者之間的區(qū)別在于鏡面光以銳利而均勻的方式從表面反射。鏡面反射光的渲染取決于觀察者和光源之間的角度。從觀察者的角度來看,鏡面反射光會在被觀察對象的表面上創(chuàng)建一個突出顯示的區(qū)域,稱為鏡面反射或鏡面反射。鏡面反射的強度取決于構成物體的材料以及包含鏡面反射光分量的光源的強度。

****光

??自發(fā)光與之前解釋的任何其他光分量略有不同。自發(fā)光光組件負責物體材質反射或吸收光的屬性。當應用于對象的材質時,自發(fā)光光的作用是模擬從物體反射的光。

??由于周圍沒有其他光源,僅應用自發(fā)光光分量的物體顏色與僅應用環(huán)境光的對象具有相同的視覺質量。然而,任何額外的漫射光或鏡面光如何與僅施加自發(fā)光光的同一物體的表面反應的機制是不同的。讓我們考慮一個平均發(fā)出綠色的物體。在下圖中,自發(fā)光分量應用于球體。如您所見,結果類似于在上面示例中將環(huán)境光應用于同一球體所創(chuàng)建的效果。

??反射綠色自發(fā)光光的 3D 球體。在將其他光源引入場景之前,該效果類似于環(huán)境光。

??如您所知,光源可以分配所有三個組件,即環(huán)境光、漫反射光和鏡面反射光組件。讓我們看看當我們在上面的場景中應用光源時會發(fā)生什么。我們應用的光源具有以下屬性:紅色環(huán)境光、紅色漫射光和白色鏡面光。

??如果上面的球體沒有發(fā)出綠色的光,它就會呈現(xiàn)紅色。但是,自發(fā)光的綠色分量被施加到它上面。當光源的“光線”照射到球體表面時,“光源”和“目標”顏色融合在一起,產生淡黃色的表面。光源的鏡面反射光分量為白色。鏡面反射的中心中心是白色的,但是當它擴散時,它與綠色和紅色融合,在黃色(即綠紅色)上增加。同樣,請注意,如果沒有將自發(fā)光光應用于球體,它看起來就像上面鏡面反射部分下顯示的球體一樣,全部為紅色,帶有白色鏡面反射。

??本教程的以下部分將介紹 OpenGL 著色多邊形以模擬光線的方式,以及如何將光源屬性分配給光源和材質。

光源

??為了計算 3D 物體的陰影,CHAI3D 需要知道落在其上的光線的強度、方向和顏色。這些屬性由世界中的光對象提供。所有光源的基色和強度設置相同,但方向取決于您使用的光源類型。此外,光線可能會隨著與光源的距離而減弱。下面介紹了 CHAI3D 中可用的三種類型的光源。

CHAI3D 光源

位置燈

??位置光位于空間中的某個點,并平等地向各個方向發(fā)出光。光線照射表面的方向是從接觸點回到光對象中心的線。強度隨著與光的距離而減小,在指定范圍內達到零。點光源可用于模擬場景中的燈和其他局部光源。

using namespace chai3d;
// create a light source
light = new cPositionalLight(world);
// attach light to camera
world->addChild(light);
// enable light source
light->setEnabled(true);
// position the light source
light->setLocalPos(1.0, 1.0, 0.5);

方向燈

??定向光源沒有任何可識別的光源位置,因此光源對象可以放置在世界任何地方。世界上所有的物體都被照亮,就好像光線總是來自同一個方向一樣。光與目標物體的距離未定義,因此光不會減弱。

??定向光源表示來自活動工作區(qū)范圍之外的位置的大而遠的光源。在逼真的場景中,它們可以用來模擬太陽或月亮。在抽象的模擬世界中,它們可以成為一種有用的方法,可以為對象添加令人信服的陰影,而無需準確指定光線的來源。在場景視圖中檢查對象時(例如,查看其網(wǎng)格、著色器和材質的外觀),定向光通常是了解其著色顯示方式的最快方法。對于這樣的測試,您通常對光線來自哪里不感興趣,而只是想看到物體看起來“固體”并尋找模型中的毛刺。

using namespace chai3d;
// create a directional light source
light = new cDirectionalLight(world);
// insert light source inside world
world->addChild(light);
// enable light source
light->setEnabled(true);
// define direction of light beam
light->setDir(-1.0, 0.0, 0.0);

聚光燈

??與位置光源一樣,聚光燈具有光源落落的指定位置和范圍。但是,聚光燈被限制在一個角度,導致錐形照明區(qū)域。圓錐體的中心指向光源對象的向后 (X) 方向。

??聚光燈通常用于人造光源,例如可以連接到觸覺工具(例如模擬內窺鏡)的手電筒。

using namespace chai3d;
// create a light source
light = new cSpotLight(world);
// attach light to camera
world->addChild(light);
// enable light source
light->setEnabled(true);
// position the light source
light->setLocalPos(0.6, 0.6, 0.5);
// define the direction of the light beam
light->setDir(-0.5,-0.5,-0.5);

陰影

燈光與陰影

??陰影映射或投影陰影是將陰影添加到 3D 計算機圖形的過程。陰影是通過測試像素從光源中是否可見來創(chuàng)建的,方法是將其與以紋理形式存儲的光源視圖的 z 緩沖區(qū)或深度圖像進行比較。

從光源生成的陰影貼圖

??如果你從光源向外看,你能看到的所有物體都會出現(xiàn)在光線中。然而,這些物體后面的任何東西都會在陰影中。這是用于創(chuàng)建陰影貼圖的基本原則。渲染光源的視圖,存儲它看到的每個表面的深度(陰影貼圖)。接下來,渲染常規(guī)場景,將繪制的每個點的深度(好像它被光而不是眼睛看到)與此深度圖進行比較。

示例

??在 CHAI3D 中,聚光燈支持陰影貼圖。在下面的示例中,我們說明了如何設置陰影貼圖。

using namespace chai3d;
// create a light source
light = new cSpotLight(world);
// attach light to camera
world->addChild(light);
// enable light source
light->setEnabled(true);
// position the light source
light->setLocalPos(0.6, 0.6, 0.5);
// define the direction of the light beam
light->setDir(-0.5,-0.5,-0.5);
// set light cone half angle
light->setCutOffAngleDeg(30);
// enable this light source to generate shadows
light->setShadowMapEnabled(true);

??為了最大限度地提高陰影的質量,重要的是 de 分配盡可能小的截止角度。此外,可以通過提高陰影貼圖的分辨率來調整陰影貼圖的質量。較大的陰影貼圖顯然需要更長的時間來渲染,并且在低性能圖形卡上可能不受支持。

using namespace chai3d;
// (1) set the resolution of the shadow map - low quality
light->m_shadowMap->setQualityLow();
// (2) set the resolution of the shadow map - medium quality
light->m_shadowMap->setQualityMedium();
// (3) set the resolution of the shadow map - high quality
light->m_shadowMap->setQualityHigh();

??渲染攝像機場景時,首先更新所有陰影貼圖非常重要。如果使用多個攝像機和多個幀緩沖區(qū)(窗口顯示)渲染場景,則只需計算一次陰影貼圖。

using namespace chai3d;
// update shadow maps
world->updateShadowMaps(false, mirroredDisplay);
// render scene
camera->renderView(windowW, windowH);

3D建模學習工作室翻譯整理,轉載請標明出處!


*博客內容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權請聯(lián)系工作人員刪除。




相關推薦

技術專區(qū)

關閉