Three.js源碼閱讀筆記(光照部分)
更新時(shí)間:2012年12月27日 16:26:39 作者:
好久沒看Three.js源碼了。今天天氣不錯(cuò),接著看;這次從光照部分看起:光照模型,從光線本身角度來看包括環(huán)境光、平行光、點(diǎn)光源,從物體表面材質(zhì)角度看又包括漫反射和鏡面反射,需要了解的朋友可以參考下
天氣越來越冷了,人也越來越懶怠,越來越像呆在溫暖的寢室里看小說或者打游戲,也好久沒看Three.js源碼了。今天天氣不錯(cuò),接著看!
這次從光照部分看起:光照模型,從光線本身角度來看包括環(huán)境光、平行光、點(diǎn)光源,從物體表面材質(zhì)角度看又包括漫反射和鏡面反射。
Lights:Light
THREE.Light = function ( hex ) {
THREE.Object3D.call( this );
this.color = new THREE.Color( hex );
};
該對(duì)象是其他光照對(duì)象的原型/基類,本身繼承自O(shè)bject3D對(duì)象/類型。它自身只有一個(gè)THREE.Color類型的color屬性,就是顏色,這很好理解。
在Three.js中,光照作為一種Object3D對(duì)象,是經(jīng)過Scene.add()方法加入到場(chǎng)景中的,渲染器會(huì)自動(dòng)渲染所加入的光照效果。
Light::AmbientLight
THREE.AmbientLight = function ( hex ) {
THREE.Light.call( this, hex );
};
無方向的環(huán)境光,并沒有比Light類型多一個(gè)屬性或方法,而僅僅為了語義上的繼承而繼承自Light,它甚至沒有必要是Object3D對(duì)象。
Light::DirectionalLight
THREE.DirectionalLight = function ( hex, intensity ) {
THREE.Light.call( this, hex );
this.position = new THREE.Vector3( 0, 1, 0 );
this.target = new THREE.Object3D();
this.intensity = ( intensity !== undefined ) ? intensity : 1;
this.castShadow = false;
this.onlyShadow = false;
// more settings about shadow ......
};
平行光(有方向的光),使用new運(yùn)算符構(gòu)造該函數(shù)時(shí)需傳入顏色hex和光線的“密度”intensity。這個(gè)類有這樣一些屬性:
position:一個(gè)位置,以該位置為起點(diǎn),原點(diǎn)為終點(diǎn)的方向是光線的方向。
intensity:光線的密度,默認(rèn)為1。因?yàn)镽GB的三個(gè)值均在0~255之間,不能反映出光照的強(qiáng)度變化,光照越強(qiáng),物體表面就更明亮。
distance:衰減距離,默認(rèn)值為0,光照無衰減;如果是非0值,光照會(huì)從position位置(實(shí)際上是position所處的那個(gè)平面)開始衰減,衰減到distance距離之后,光照強(qiáng)度intensity為0。
castShadow:布爾值,控制是否產(chǎn)生陰影,默認(rèn)為false。如果設(shè)為true,對(duì)于所有表面都會(huì)逐像元地計(jì)算其在光照方向上是否被遮擋,這會(huì)消耗大量的計(jì)算。
onlyShadow:布爾值,控制是否只產(chǎn)生陰影而不“照亮”物體,默認(rèn)為false。這種模式也許有什么特殊應(yīng)用吧。
shadowCameraLeft,shadowCameraRight……系列,以position點(diǎn)為中心控制產(chǎn)生陰影的范圍?
shadowBias:陰影偏心,默認(rèn)為0。
shadowDarkness:陰影對(duì)物體亮度的影響,在0~1之間,默認(rèn)為0.5。
還有不少屬性暫時(shí)猜不出含義(真該去補(bǔ)補(bǔ)計(jì)算機(jī)圖形學(xué)啊,硬著頭皮繼續(xù)看吧)。
Light::PointLight
THREE.PointLight = function ( hex, intensity, distance ) {
THREE.Light.call( this, hex );
this.position = new THREE.Vector3( 0, 0, 0 );
this.intensity = ( intensity !== undefined ) ? intensity : 1;
this.distance = ( distance !== undefined ) ? distance : 0;
};
點(diǎn)光源,position那肯定就是光源點(diǎn)了。注意點(diǎn)光源的position和平行光的position的區(qū)別,前者默認(rèn)在原點(diǎn),而后者默認(rèn)在點(diǎn)(0,1,1),這使得默認(rèn)的平行光方向和相機(jī)的默認(rèn)朝向一致。
其他兩個(gè)屬性和平行光中一樣。PointLight點(diǎn)光源沒有關(guān)于如何產(chǎn)生陰影的設(shè)定。
Light::SpotLight
THREE.SpotLight = function ( hex, intensity, distance, angle, exponent ) {
THREE.Light.call( this, hex );
this.position = new THREE.Vector3( 0, 1, 0 );
this.target = new THREE.Object3D();
this.intensity = ( intensity !== undefined ) ? intensity : 1;
this.distance = ( distance !== undefined ) ? distance : 0;
this.angle = ( angle !== undefined ) ? angle : Math.PI / 2;
this.exponent = ( exponent !== undefined ) ? exponent : 10; // more settings about shadow...
};
一種可以在某個(gè)方向上產(chǎn)生陰影的點(diǎn)光源,影響MeshLamberMaterial和MeshPhongMaterial類型材質(zhì)的表面。對(duì)陰影如何處理的設(shè)定和DirectionLight一致。
總之,光照對(duì)象并不承擔(dān)渲染光照的任務(wù),而僅僅是定義如何渲染光照。
Object::Partical
THREE.Particle = function ( material ) {
THREE.Object3D.call( this );
this.material = material;
};
粒子就是一個(gè)由材質(zhì)的Object3D,這很好理解。Object3D對(duì)象提供一個(gè)坐標(biāo)(就是粒子的坐標(biāo)),負(fù)責(zé)粒子的運(yùn)動(dòng),粒子只需要指定表現(xiàn)它的材質(zhì)即可。
Object::ParticalSystem
THREE.ParticleSystem = function ( geometry, material ) {
THREE.Object3D.call( this );
this.geometry = geometry;
this.material = ( material !== undefined ) ? material : new THREE.ParticleBasicMaterial( { color: Math.random() * 0xffffff } );
this.sortParticles = false;
if ( this.geometry ) {
if( this.geometry.boundingSphere === null ) {
this.geometry.computeBoundingSphere();
}
this.boundRadius = geometry.boundingSphere.radius;
}
this.frustumCulled = false;
};
粒子系統(tǒng)表現(xiàn)多個(gè)粒子的運(yùn)動(dòng),粒子系統(tǒng)本身繼承自是Object3D對(duì)象。有這樣幾個(gè)屬性:
geometry屬性,每一個(gè)節(jié)點(diǎn)都是一個(gè)粒子,這些共享一個(gè)材質(zhì)。
material屬性,即這些節(jié)點(diǎn)的材質(zhì)。
frustumCulled屬性,布爾值,如果設(shè)定為真,那么在相機(jī)視界之外的會(huì)被踢出,但還沒弄清楚是粒子系統(tǒng)中心坐標(biāo)在視界外就踢出整個(gè)粒子系統(tǒng)還是單個(gè)粒子出去了就剔除,猜測(cè)多半是后者。
其實(shí)這幾篇都是涉及怎么定義場(chǎng)景的,至于怎么渲染場(chǎng)景很難有深入。我準(zhǔn)備接下來去看Demo的代碼,結(jié)合者看看WebGLRenderer類的源代碼(幾千行OMG)。
這次從光照部分看起:光照模型,從光線本身角度來看包括環(huán)境光、平行光、點(diǎn)光源,從物體表面材質(zhì)角度看又包括漫反射和鏡面反射。
Lights:Light
復(fù)制代碼 代碼如下:
THREE.Light = function ( hex ) {
THREE.Object3D.call( this );
this.color = new THREE.Color( hex );
};
該對(duì)象是其他光照對(duì)象的原型/基類,本身繼承自O(shè)bject3D對(duì)象/類型。它自身只有一個(gè)THREE.Color類型的color屬性,就是顏色,這很好理解。
在Three.js中,光照作為一種Object3D對(duì)象,是經(jīng)過Scene.add()方法加入到場(chǎng)景中的,渲染器會(huì)自動(dòng)渲染所加入的光照效果。
Light::AmbientLight
復(fù)制代碼 代碼如下:
THREE.AmbientLight = function ( hex ) {
THREE.Light.call( this, hex );
};
無方向的環(huán)境光,并沒有比Light類型多一個(gè)屬性或方法,而僅僅為了語義上的繼承而繼承自Light,它甚至沒有必要是Object3D對(duì)象。
Light::DirectionalLight
復(fù)制代碼 代碼如下:
THREE.DirectionalLight = function ( hex, intensity ) {
THREE.Light.call( this, hex );
this.position = new THREE.Vector3( 0, 1, 0 );
this.target = new THREE.Object3D();
this.intensity = ( intensity !== undefined ) ? intensity : 1;
this.castShadow = false;
this.onlyShadow = false;
// more settings about shadow ......
};
平行光(有方向的光),使用new運(yùn)算符構(gòu)造該函數(shù)時(shí)需傳入顏色hex和光線的“密度”intensity。這個(gè)類有這樣一些屬性:
position:一個(gè)位置,以該位置為起點(diǎn),原點(diǎn)為終點(diǎn)的方向是光線的方向。
intensity:光線的密度,默認(rèn)為1。因?yàn)镽GB的三個(gè)值均在0~255之間,不能反映出光照的強(qiáng)度變化,光照越強(qiáng),物體表面就更明亮。
distance:衰減距離,默認(rèn)值為0,光照無衰減;如果是非0值,光照會(huì)從position位置(實(shí)際上是position所處的那個(gè)平面)開始衰減,衰減到distance距離之后,光照強(qiáng)度intensity為0。
castShadow:布爾值,控制是否產(chǎn)生陰影,默認(rèn)為false。如果設(shè)為true,對(duì)于所有表面都會(huì)逐像元地計(jì)算其在光照方向上是否被遮擋,這會(huì)消耗大量的計(jì)算。
onlyShadow:布爾值,控制是否只產(chǎn)生陰影而不“照亮”物體,默認(rèn)為false。這種模式也許有什么特殊應(yīng)用吧。
shadowCameraLeft,shadowCameraRight……系列,以position點(diǎn)為中心控制產(chǎn)生陰影的范圍?
shadowBias:陰影偏心,默認(rèn)為0。
shadowDarkness:陰影對(duì)物體亮度的影響,在0~1之間,默認(rèn)為0.5。
還有不少屬性暫時(shí)猜不出含義(真該去補(bǔ)補(bǔ)計(jì)算機(jī)圖形學(xué)啊,硬著頭皮繼續(xù)看吧)。
Light::PointLight
復(fù)制代碼 代碼如下:
THREE.PointLight = function ( hex, intensity, distance ) {
THREE.Light.call( this, hex );
this.position = new THREE.Vector3( 0, 0, 0 );
this.intensity = ( intensity !== undefined ) ? intensity : 1;
this.distance = ( distance !== undefined ) ? distance : 0;
};
點(diǎn)光源,position那肯定就是光源點(diǎn)了。注意點(diǎn)光源的position和平行光的position的區(qū)別,前者默認(rèn)在原點(diǎn),而后者默認(rèn)在點(diǎn)(0,1,1),這使得默認(rèn)的平行光方向和相機(jī)的默認(rèn)朝向一致。
其他兩個(gè)屬性和平行光中一樣。PointLight點(diǎn)光源沒有關(guān)于如何產(chǎn)生陰影的設(shè)定。
Light::SpotLight
復(fù)制代碼 代碼如下:
THREE.SpotLight = function ( hex, intensity, distance, angle, exponent ) {
THREE.Light.call( this, hex );
this.position = new THREE.Vector3( 0, 1, 0 );
this.target = new THREE.Object3D();
this.intensity = ( intensity !== undefined ) ? intensity : 1;
this.distance = ( distance !== undefined ) ? distance : 0;
this.angle = ( angle !== undefined ) ? angle : Math.PI / 2;
this.exponent = ( exponent !== undefined ) ? exponent : 10; // more settings about shadow...
};
一種可以在某個(gè)方向上產(chǎn)生陰影的點(diǎn)光源,影響MeshLamberMaterial和MeshPhongMaterial類型材質(zhì)的表面。對(duì)陰影如何處理的設(shè)定和DirectionLight一致。
總之,光照對(duì)象并不承擔(dān)渲染光照的任務(wù),而僅僅是定義如何渲染光照。
Object::Partical
復(fù)制代碼 代碼如下:
THREE.Particle = function ( material ) {
THREE.Object3D.call( this );
this.material = material;
};
粒子就是一個(gè)由材質(zhì)的Object3D,這很好理解。Object3D對(duì)象提供一個(gè)坐標(biāo)(就是粒子的坐標(biāo)),負(fù)責(zé)粒子的運(yùn)動(dòng),粒子只需要指定表現(xiàn)它的材質(zhì)即可。
Object::ParticalSystem
復(fù)制代碼 代碼如下:
THREE.ParticleSystem = function ( geometry, material ) {
THREE.Object3D.call( this );
this.geometry = geometry;
this.material = ( material !== undefined ) ? material : new THREE.ParticleBasicMaterial( { color: Math.random() * 0xffffff } );
this.sortParticles = false;
if ( this.geometry ) {
if( this.geometry.boundingSphere === null ) {
this.geometry.computeBoundingSphere();
}
this.boundRadius = geometry.boundingSphere.radius;
}
this.frustumCulled = false;
};
粒子系統(tǒng)表現(xiàn)多個(gè)粒子的運(yùn)動(dòng),粒子系統(tǒng)本身繼承自是Object3D對(duì)象。有這樣幾個(gè)屬性:
geometry屬性,每一個(gè)節(jié)點(diǎn)都是一個(gè)粒子,這些共享一個(gè)材質(zhì)。
material屬性,即這些節(jié)點(diǎn)的材質(zhì)。
frustumCulled屬性,布爾值,如果設(shè)定為真,那么在相機(jī)視界之外的會(huì)被踢出,但還沒弄清楚是粒子系統(tǒng)中心坐標(biāo)在視界外就踢出整個(gè)粒子系統(tǒng)還是單個(gè)粒子出去了就剔除,猜測(cè)多半是后者。
其實(shí)這幾篇都是涉及怎么定義場(chǎng)景的,至于怎么渲染場(chǎng)景很難有深入。我準(zhǔn)備接下來去看Demo的代碼,結(jié)合者看看WebGLRenderer類的源代碼(幾千行OMG)。
相關(guān)文章
JS不用正則驗(yàn)證輸入的字符串是否為空(包含空格)的實(shí)現(xiàn)代碼
下面小編就為大家?guī)硪黄狫S不用正則驗(yàn)證輸入的字符串是否為空(包含空格)的實(shí)現(xiàn)代碼。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-06-06實(shí)例講解JavaScript中instanceof運(yùn)算符的用法
JavaScript中的instanceof運(yùn)算符可以用來判斷對(duì)象類型,而更重要的是instanceof能夠判斷對(duì)象的繼承關(guān)系,這里我們就來以實(shí)例講解JavaScript中instanceof運(yùn)算符的用法2016-06-06uni-app自定義組件components導(dǎo)入失敗或頁面不顯示文本等解決方法
這篇文章主要給大家介紹了關(guān)于uni-app自定義組件components導(dǎo)入失敗或頁面不顯示文本等的解決方法,眾所周知Uni-app支持使用自定義組件,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08js對(duì)象內(nèi)部訪問this修飾的成員函數(shù)示例
這篇文章主要介紹了js對(duì)象內(nèi)部訪問this修飾的成員函數(shù)示例,需要的朋友可以參考下2014-04-04Javascript入門學(xué)習(xí)第九篇 Javascript DOM 總結(jié)
作為一個(gè)js-DOM開發(fā)者,你必須知道的一些DOM方法:2008-07-07javaScript parseInt字符轉(zhuǎn)化為數(shù)字函數(shù)使用小結(jié)
前幾天做網(wǎng)站的時(shí)候需要講數(shù)據(jù)庫中的時(shí)間讀取到變量中進(jìn)行使用,用到parseInt函數(shù),講字符轉(zhuǎn)化為數(shù)字。2009-11-11