推薦:將?NSDT場景編輯器?加入你的3D開發(fā)工具鏈
介紹
??光是人類可以視覺感知的任何事物的視覺表示背后的最重要的思想浙于。光感知的概念在于规阀,你所看到的不是基于你正在觀看的物體,而是基于光源投射并從這些物體反射的光線。重要的是要注意,你的眼睛不會直接看到物體鱼辙,因為你的眼睛和這些物體之間沒有物理相關(guān)性舵揭。
??當(dāng)然防楷,所有這些都是理論上的如筛。我們使用術(shù)語光線只是抽象出更復(fù)雜的機制堡牡。
??光線通常來自能量來源,例如太陽或房間內(nèi)的燈杨刨。重要的是要注意晤柄,從理論上講,光線沿直線傳播妖胀,當(dāng)您在視覺上感知物體時芥颈,您的眼睛吸收的是該物體反射或散射的光線。
光的抽象類型
??以下術(shù)語描述了在對需要光源的 3D 應(yīng)用程序進(jìn)行編程時必須了解的不同類型的光赚抡。了解每種類型的光在渲染的 3D 對象表面上產(chǎn)生的效果非常重要爬坑。創(chuàng)建這些術(shù)語是因為需要描述光對物體產(chǎn)生的某些效果,以便提煉出光的復(fù)雜數(shù)學(xué)計算涂臣。然而盾计,這并不意味著這些確切類型的光實際上存在于自然界中,我們只是將它們視為光投射在不同材料上時可能產(chǎn)生的效果的抽象肉康。計算光的真實機制及其在自然界中的工作方式將非常耗時闯估,因此,OpenGL 通常采用這組常見的光類型:環(huán)境光吼和、漫射光和鏡面光涨薪。發(fā)射光與其他光不同,是物體發(fā)出的光的類型炫乓,而其他三種類型的光通常用于描述光源刚夺。讓我們詳細(xì)看看這些類型的光:
環(huán)境光
??被環(huán)境光照亮的 3D 球體看起來只有 2D末捣。環(huán)境光是由照明區(qū)域周圍(或位于照明區(qū)域內(nèi)部)的所有光源發(fā)射光而產(chǎn)生的平均光量侠姑。當(dāng)陽光穿過房間的窗戶時,它們會打到墻壁上箩做,反射并散射到各個不同的方向莽红,平均照亮整個房間。這種視覺質(zhì)量由環(huán)境光描述邦邦。僅環(huán)境光無法傳達(dá)在 3D 空間中設(shè)置的對象的完整表示安吁,因為所有頂點都由相同的顏色均勻照明,并且對象看起來像是二維的燃辖,如上圖所示鬼店。盡管顯示的對象實際上是一個 3D 球體,但當(dāng)僅由環(huán)境光照亮?xí)r黔龟,它在屏幕上看起來是平坦的妇智。
漫反射光
??紅色的漫射光投射到定義其 3D 形狀的黑色物體上滥玷。
??漫射光表示光源投射的定向光。漫射光可以描述為在空間中具有位置并且來自單個方向的光巍棱。手電筒稍微高于它所照亮的物體惑畴,可以被認(rèn)為是發(fā)射漫射光。在上圖中拉盾,投射紅色漫射光的光源位于物體的左側(cè)桨菜。當(dāng)漫射光接觸物體表面時,它會在該表面上均勻地散射和反射捉偏。
??為了演示環(huán)境光和漫射光如何協(xié)同工作以創(chuàng)建看起來更逼真的對象倒得,請想象一個 3D 球體,其上散布著深紅色的環(huán)境光:
??現(xiàn)在夭禽,通過將漫射光源放置在球體的右側(cè)霞掺,我們得到以下結(jié)果:
??請注意球體現(xiàn)在看起來是 3D 的。
鏡面光
??除了環(huán)境光層和漫反射層外讹躯,此處還顯示鏡面反射(或鏡面反射高光)菩彬。您可以觀察到鏡面反射光源屬性如何大大增強對象的 3D 表示。 就像漫射光一樣潮梯,鏡面反射光是一種定向光骗灶。它來自一個特定的方向。
??兩者之間的區(qū)別在于鏡面光以銳利而均勻的方式從表面反射秉馏。鏡面反射光的渲染取決于觀察者和光源之間的角度耙旦。從觀察者的角度來看,鏡面反射光會在被觀察對象的表面上創(chuàng)建一個突出顯示的區(qū)域萝究,稱為鏡面反射或鏡面反射免都。鏡面反射的強度取決于構(gòu)成物體的材料以及包含鏡面反射光分量的光源的強度。
發(fā)射光
??自發(fā)光與之前解釋的任何其他光分量略有不同帆竹。自發(fā)光光組件負(fù)責(zé)物體材質(zhì)反射或吸收光的屬性绕娘。當(dāng)應(yīng)用于對象的材質(zhì)時,自發(fā)光光的作用是模擬從物體反射的光栽连。
??由于周圍沒有其他光源险领,僅應(yīng)用自發(fā)光光分量的物體顏色與僅應(yīng)用環(huán)境光的對象具有相同的視覺質(zhì)量。然而秒紧,任何額外的漫射光或鏡面光如何與僅施加自發(fā)光光的同一物體的表面反應(yīng)的機制是不同的舷暮。讓我們考慮一個平均發(fā)出綠色的物體。在下圖中噩茄,自發(fā)光分量應(yīng)用于球體。如您所見复颈,結(jié)果類似于在上面示例中將環(huán)境光應(yīng)用于同一球體所創(chuàng)建的效果绩聘。
??反射綠色自發(fā)光光的 3D 球體沥割。在將其他光源引入場景之前,該效果類似于環(huán)境光凿菩。
??如您所知机杜,光源可以分配所有三個組件,即環(huán)境光衅谷、漫反射光和鏡面反射光組件椒拗。讓我們看看當(dāng)我們在上面的場景中應(yīng)用光源時會發(fā)生什么。我們應(yīng)用的光源具有以下屬性:紅色環(huán)境光获黔、紅色漫射光和白色鏡面光蚀苛。
??如果上面的球體沒有發(fā)出綠色的光,它就會呈現(xiàn)紅色玷氏。但是堵未,自發(fā)光的綠色分量被施加到它上面。當(dāng)光源的“光線”照射到球體表面時盏触,“光源”和“目標(biāo)”顏色融合在一起渗蟹,產(chǎn)生淡黃色的表面。光源的鏡面反射光分量為白色赞辩。鏡面反射的中心中心是白色的雌芽,但是當(dāng)它擴(kuò)散時,它與綠色和紅色融合辨嗽,在黃色(即綠紅色)上增加世落。同樣,請注意召庞,如果沒有將自發(fā)光光應(yīng)用于球體岛心,它看起來就像上面鏡面反射部分下顯示的球體一樣,全部為紅色篮灼,帶有白色鏡面反射忘古。
??本教程的以下部分將介紹 OpenGL 著色多邊形以模擬光線的方式,以及如何將光源屬性分配給光源和材質(zhì)诅诱。
光源
??為了計算 3D 物體的陰影髓堪,CHAI3D 需要知道落在其上的光線的強度、方向和顏色娘荡。這些屬性由世界中的光對象提供干旁。所有光源的基色和強度設(shè)置相同,但方向取決于您使用的光源類型炮沐。此外争群,光線可能會隨著與光源的距離而減弱。下面介紹了 CHAI3D 中可用的三種類型的光源大年。
位置燈
??位置光位于空間中的某個點换薄,并平等地向各個方向發(fā)出光玉雾。光線照射表面的方向是從接觸點回到光對象中心的線。強度隨著與光的距離而減小轻要,在指定范圍內(nèi)達(dá)到零复旬。點光源可用于模擬場景中的燈和其他局部光源。
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);
方向燈
??定向光源沒有任何可識別的光源位置冲泥,因此光源對象可以放置在世界任何地方驹碍。世界上所有的物體都被照亮,就好像光線總是來自同一個方向一樣凡恍。光與目標(biāo)物體的距離未定義志秃,因此光不會減弱。
??定向光源表示來自活動工作區(qū)范圍之外的位置的大而遠(yuǎn)的光源咳焚。在逼真的場景中洽损,它們可以用來模擬太陽或月亮。在抽象的模擬世界中革半,它們可以成為一種有用的方法碑定,可以為對象添加令人信服的陰影,而無需準(zhǔn)確指定光線的來源又官。在場景視圖中檢查對象時(例如延刘,查看其網(wǎng)格、著色器和材質(zhì)的外觀)六敬,定向光通常是了解其著色顯示方式的最快方法碘赖。對于這樣的測試,您通常對光線來自哪里不感興趣外构,而只是想看到物體看起來“固體”并尋找模型中的毛刺普泡。
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);
聚光燈
??與位置光源一樣,聚光燈具有光源落落的指定位置和范圍审编。但是撼班,聚光燈被限制在一個角度,導(dǎo)致錐形照明區(qū)域垒酬。圓錐體的中心指向光源對象的向后 (X) 方向砰嘁。
??聚光燈通常用于人造光源,例如可以連接到觸覺工具(例如模擬內(nèi)窺鏡)的手電筒勘究。
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ū)或深度圖像進(jìn)行比較口糕。
??如果你從光源向外看昌跌,你能看到的所有物體都會出現(xiàn)在光線中湿刽。然而握联,這些物體后面的任何東西都會在陰影中。這是用于創(chuàng)建陰影貼圖的基本原則包竹。渲染光源的視圖,存儲它看到的每個表面的深度(陰影貼圖)。接下來婶肩,渲染常規(guī)場景,將繪制的每個點的深度(好像它被光而不是眼睛看到)與此深度圖進(jìn)行比較说搅。
示例
??在 CHAI3D 中炸枣,聚光燈支持陰影貼圖。在下面的示例中弄唧,我們說明了如何設(shè)置陰影貼圖适肠。
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);
??為了最大限度地提高陰影的質(zhì)量,重要的是 de 分配盡可能小的截止角度候引。此外侯养,可以通過提高陰影貼圖的分辨率來調(diào)整陰影貼圖的質(zhì)量。較大的陰影貼圖顯然需要更長的時間來渲染澄干,并且在低性能圖形卡上可能不受支持逛揩。
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建模學(xué)習(xí)工作室翻譯整理从媚,轉(zhuǎn)載請標(biāo)明出處逞泄!