国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Three.js 3D建模必備基礎

這篇具有很好參考價值的文章主要介紹了Three.js 3D建模必備基礎。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

在 three.js 中,可見對象由幾何體和材質構成。 我們已經了解了如何創(chuàng)建適用于點和線圖元的簡單幾何圖形,并且遇到了各種標準網格幾何圖形,例如 THREE.CylinderGeometry 和 THREE.IcosahedronGeometry。 在本節(jié)中,我們將了解如何從頭開始創(chuàng)建新的網格幾何體。 我們還將了解 three.js 為處理對象和材質提供的其他一些支持。

Three.js 3D建模必備基礎

推薦:使用 NSDT場景設計器 快速搭建 3D場景。

1、索引面集

three.js 中的網格就是我們之前中所說的索引面集。 在 three.js 網格中,所有的多邊形都是三角形。 three.js 中的幾何是 THREE.Geometry 類型的對象。 任何幾何對象都包含一個頂點數組,表示為 THREE.Vector3 類型的對象。 對于網格幾何體,它還包含一個面數組,表示為 THREE.Face3 類型的對象。 Face3 類型的每個對象指定幾何體的一個三角形面。 三角形的三個頂點由三個整數指定。 每個整數都是幾何頂點數組的索引。 這三個整數可以指定為 THREE.Face3 構造函數的參數。 例如,

var f = new THREE.Face3( 0, 7, 2 );

這三個索引存儲為面對象的屬性 f.a、f.b 和 f.c。 作為一個例子,讓我們看看如何直接為這個金字塔創(chuàng)建一個 three.js 幾何體:

Three.js 3D建模必備基礎

請注意,金字塔的底面是正方形,必須將其分成兩個三角形才能將金字塔表示為網格幾何體。 如果 pyramidGeom 是此金字塔的幾何對象,則 pyramidGeom.vertices 是頂點數組,而 pyramidGeom.faces 是面數組。 考慮到這一點,我們可以定義:

var pyramidGeom = new THREE.Geometry();

pyramidGeom.vertices = [  // array of Vector3 giving vertex coordinates
        new THREE.Vector3( 1, 0, 1 ),    // vertex number 0
        new THREE.Vector3( 1, 0, -1 ),   // vertex number 1
        new THREE.Vector3( -1, 0, -1 ),  // vertex number 2
        new THREE.Vector3( -1, 0, 1 ),   // vertex number 3
        new THREE.Vector3( 0, 1, 0 )     // vertex number 4
    ];

pyramidGeom.faces = [  // array of Face3 giving the triangular faces
        new THREE.Face3( 3, 2, 1 ),  // first half of the bottom face
        new THREE.Face3 3, 1, 0 ),   // second half of the bottom face
        new THREE.Face3( 3, 0, 4 ),  // remaining faces are the four sides
        new THREE.Face3( 0, 1, 4 ),
        new THREE.Face3( 1, 2, 4 ),
        new THREE.Face3( 2, 3, 4 )
    ];

請注意,面上頂點的順序并不是完全隨意的:它們應該按照逆時針順序排列,從面的前面看,也就是從金字塔外面看面。

給定的金字塔幾何體將與 MeshBasicMaterial 一起使用,但要與 MeshLambertMaterial 或 MeshPhongMaterial 等光照材質一起使用,幾何體需要法向量。 如果幾何體沒有法向量,Lambert 和 Phong 材質將顯示為黑色。

可以手動分配法向量,但也可以讓 three.js 通過調用幾何類中的方法來為您計算它們。 對于金字塔,這將通過調用:

pyramidGeom.computeFaceNormals();

此方法為每個面計算一個法向量,其中法線垂直于面。 如果材質使用平面著色,這就足夠了; 也就是說,如果材質的 flatShading 屬性設置為 true。 flatShading 屬性在之前討論過。

平面著色(flatShading)適用于金字塔。 但是當一個對象應該看起來是光滑的而不是多面的時,它需要每個頂點的法向量而不是每個面的法向量。 Face3 具有三個頂點法線的數組。 它們可以手動設置,或者 Three.js 可以通過平均共享一個頂點的所有面的面法線來計算光滑表面的合理頂點法線。 只需調用:

geom.computeVertexNormals();

其中 geom 是幾何對象。 請注意,在調用 computeVertexNormals 之前面法線必須已經存在,因此通常會在調用 geom.computeFaceNormals() 之后立即調用 geom.computeVertexNormals()。 具有面法線但沒有頂點法線的幾何體不適用于 flatShading 屬性具有默認值 false 的材質。 為了能夠在像金字塔這樣的表面上使用平滑著色,每個面的所有頂點法線都應該設置為等于它的面法線。 在那種情況下,即使有平滑的陰影,金字塔的側面看起來也是平坦的。 標準的 three.js 幾何體(例如 BoxGeometry)帶有正確的面和頂點法線。

類型為 THREE.Face3 的對象的面法線存儲在屬性 face.normal 中。 頂點法線存儲在 face.vertexNormals 中,它是一個包含三個 Vector3 的數組。

有了完整的法向量集,金字塔就可以與我們介紹過的任何網格材質一起使用,但只有一種顏色看起來有點無聊。 可以在一個網格上使用多種顏色。 為此,你可以向網格對象構造函數提供一組材料,而不是單一材料。 這使得可以將不同的材料應用于不同的面。 例如,這里是如何制作一個六面具有不同材料的立方體:

var cubeGeom = new THREE.BoxGeometry(10,10,10);
var cubeMaterials =  [
    new THREE.MeshPhongMaterial( { color: "red" } ),
    new THREE.MeshPhongMaterial( { color: "cyan" } ),
    new THREE.MeshPhongMaterial( { color: "green" } ),
    new THREE.MeshPhongMaterial( { color: "magenta" } ), // for the -y face
    new THREE.MeshPhongMaterial( { color: "blue" } ),    // for the +z face
    new THREE.MeshPhongMaterial( { color: "yellow" } )   // for the -z face
];
var cube = new THREE.Mesh( cubeGeom, cubeMaterials );

為了使其與幾何體一起使用,幾何體的每個面都需要一個“材質索引”。 面的材質索引是一個整數,它是材質數組的索引。 BoxGeometry 的面具有適當的索引。 請注意,長方體幾何體有 12 個面,因為每個矩形邊都被分成兩個三角形面。 組成矩形邊的兩個三角形具有相同的材料指數。 (BoxGeometry 是我能找到的唯一具有非零材質索引的標準幾何體。材質索引的默認值為零。)

假設我們想在上面創(chuàng)建的金字塔的每一側使用不同的材質。 為此,每個面都需要一個材質索引,該索引存儲在名為 materialIndex 的面屬性中。 對于金字塔,面數組中的前兩個面構成了金字塔的方形底面。 它們可能應該具有相同的材質索引。 以下代碼將材質索引 0 分配給前兩個面,將材質索引 1、2、3 和 4 分配給其他四個面:

pyramidGeom.faces[0].materialIndex = 0;
for (var i = 1; i <= 5; i++) {
    pyramidGeom.faces[i].materialIndex = i-1;
}

代碼來自示例程序threejs/MeshFaceMaterial.html。 該程序在每個對象上使用多種材料顯示一個立方體和一個金字塔。 這是它們的樣子:
Three.js 3D建模必備基礎

還有另一種方法可以為網格對象的每個面分配不同的顏色:可以將顏色存儲為幾何體中面對象的屬性。 然后,可以在對象上使用普通材質,而不是材質數組。 但是還必須告訴材質使用幾何體中的顏色來代替材質的顏色屬性。

有幾種方法可以將顏色分配給網格中的面。 一種是簡單地使每張臉具有不同的純色。 每個人臉對象都有一個顏色屬性,可以用來實現這個想法。 color 屬性的值是一個 THREE.Color 類型的對象,表示整個面部的顏色。 例如,我們可以設置金字塔的面顏色:

pyramidGeom.faces[0].color = new THREE.Color(0xCCCCCC);
pyramidGeom.faces[1].color = new THREE.Color(0xCCCCCC);
pyramidGeom.faces[2].color = new THREE.Color("green");
pyramidGeom.faces[3].color = new THREE.Color("blue");
pyramidGeom.faces[4].color = new THREE.Color("yellow");
pyramidGeom.faces[5].color = new THREE.Color("red");

要使用這些顏色,必須將材質的 vertexColors 屬性設置為值 THREE.FaceColors; 例如:

material = new THREE.MeshLambertMaterial({
        vertexColors: THREE.FaceColors,
        shading: THREE.FlatShading
    });

該屬性的默認值為 THREE.NoColors,它告訴渲染器為每個面使用材質的顏色屬性。

將顏色應用于面的第二種方法是將不同的顏色應用于面的每個頂點。 然后,WebGL 將對頂點顏色進行插值以計算面部內像素的顏色。 每個面對象都有一個名為 vertexColors 的屬性,其值應該是三個 THREE.Color 對象的數組,一個對應面的每個頂點。 要使用這些顏色,必須將材質的 vertexColors 屬性設置為 THREE.VertexColors。

演示 c5/vertex-and-color-animation.html 是使用頂點和面顏色的示例。 它可以為顏色設置動畫,也可以為對象的頂點位置設置動畫。 這是該演示中的一張圖片,顯示了一個多色的二十面體幾何體,其中一些頂點已被置換:
Three.js 3D建模必備基礎

2、曲線和曲面

除了可以構建索引面集外,three.js 還支持使用數學定義的曲線和曲面。 示例程序 threejs/curves-and-surfaces.html 中說明了一些可能性,我將在這里討論其中的一些。

參數化曲面是最容易使用的。 參數曲面由數學函數 f(u,v) 定義,其中 u 和 v 是數字,函數的每個值都是空間中的一個點。 該表面由所有點組成,這些點是某些指定范圍內 u 和 v 的函數值。 對于 three.js,該函數是一個常規(guī) JavaScript 函數,它返回 THREE.Vector3 類型的值。 通過在 uv 點網格處評估函數來創(chuàng)建參數化表面幾何體。 這給出了表面上的點網格,然后連接這些點以給出表面的多邊形近似。 在 three.js 中,u 和 v 的值始終在 0.0 到 1.0 的范圍內。 幾何是由構造函數創(chuàng)建的:

new THREE.ParametricGeometry( func, slices, stacks )

其中 func 是 JavaScript 函數,切片和堆棧確定網格中的點數; slices給出u方向0到1區(qū)間的細分數,v方向stacks。 一旦你有了幾何圖形,你就可以用它以通常的方式制作網格。 這是示例程序中的示例:
Three.js 3D建模必備基礎

該表面由函數定義:

function surfaceFunction( u, v ) {
    var x,y,z;  // A point on the surface, calculated from u,v.
        //u and v range from 0 to 1.
    x=20*(u-0.5); // x and z range from -10 to 10
    z = 20 * (v - 0.5);
    y = 2*(Math.sin(x/2) * Math.cos(z));
    return new THREE.Vector3( x, y, z );
}

表示表面的 three.js 網格是使用如下代碼創(chuàng)建的:

var surfaceGeometry = new THREE.ParametricGeometry(surfaceFunction, 64, 64);

var surface = new THREE.Mesh( surfaceGeometry, material );

Three.js 中的曲線更加復雜(不幸的是,用于處理曲線的 API 不是很一致)。

THREE.Curve 類表示二維或三維參數曲線的抽象概念。 (它不代表 three.js 幾何體。)參數化曲線由一個數值變量 t 的函數定義。 函數返回的值對于 2D 曲線是 THREE.Vector2 類型,對于 3D 曲線是 THREE.Vector3 類型。 對于類型為 THREE.Curve 的對象曲線,方法 curve.getPoint(t) 應返回曲線上對應于參數 t 的值的點。 然而,在 Curve 類本身中,這個函數是未定義的。 要獲得實際曲線,你必須對其進行定義。 例如,

var helix = new THREE.Curve();
helix.getPoint = function(t) {
    var s = (t - 0.5) * 12*Math.PI;
        // As t ranges from 0 to 1, s ranges from -6*PI to 6*PI
    return new THREE.Vector3(
        5*Math.cos(s),
        s,
        5*Math.sin(s)
    );
}

定義 getPoint 后,你就有了可用的曲線。 可以用它做的一件事是創(chuàng)建一個管幾何體,它定義了一個表面,該表面是一個具有圓形橫截面的管,并且曲線沿著管的中心延伸。 示例程序使用上面定義的螺旋曲線來創(chuàng)建兩個管:
Three.js 3D建模必備基礎

較寬管的幾何形狀是用如下代碼創(chuàng)建:

tubeGeometry1 = new THREE.TubeGeometry( helix, 128, 2.5, 32 );

構造函數的第二個參數是曲面沿曲線長度的細分數。 第三個是管子圓形截面的半徑,第四個是截面圓周周圍的細分數。

要制作管道,你需要 3D 曲線。 也有幾種方法可以從 2D 曲線制作曲面。 一種方法是圍繞一條線旋轉曲線,生成一個旋轉表面。 曲面由曲線在旋轉時經過的所有點組成。 這稱為車削加工(lathing )。 示例程序中的這張圖片顯示了通過車削余弦曲線生成的曲面。 (圖像旋轉 90 度,因此 y 軸水平。)曲線本身顯示在曲面上方:
Three.js 3D建模必備基礎

曲面是在 three.js 中使用 THREE.LatheGeometry 對象創(chuàng)建的。 LatheGeometry 不是根據曲線構造的,而是根據位于曲線上的點數組構造的。 這些點是 Vector2 類型的對象,曲線位于 xy 平面中。 曲面是通過繞 y 軸旋轉曲線生成的。

LatheGeometry 構造函數采用以下形式:

new THREE.LatheGeometry( points, slices )

第一個參數是 Vector2 的數組。 第二個是點繞軸旋轉時,曲面沿圓產生的細分數。 (表面的“堆?!睌涤牲c數組的長度給出。)在示例程序中,我通過調用 cosine.getPoints(128) 從類型為 Curve 的對象 cosine 創(chuàng)建了點數組。 此函數使用 0.0 到 1.0 范圍內的參數值在曲線上創(chuàng)建一個包含 128 個點的數組。

可以使用 2D 曲線做的另一件事是簡單地填充曲線的內部,給出一個 2D 填充形狀。 要在 three.js 中做到這一點,你可以使用 THREE.Shape 類型的對象,它是 THREE.Curve 的子類。 Shape 可以用與前面介紹的 2D Canvas API 中的路徑相同的方式定義。 也就是說,類型為 THREE.Shape 的對象形狀具有可用于定義路徑的方法 shape.moveTo、shape.lineTo、shape.quadraticCurveTo 和 shape.bezierCurveTo。 例如,我們可以創(chuàng)建一個淚珠形狀:

var path = new THREE.Shape();
path.moveTo(0,10);
path.bezierCurveTo( 0,5, 20,-10, 0,-10 );
path.bezierCurveTo( -20,-10, 0,5, 0,10 );

要在 three.js 中使用路徑創(chuàng)建填充形狀,我們需要一個 ShapeGeometry 對象:

var shapeGeom = new THREE.ShapeGeometry( path );

使用此幾何體創(chuàng)建的 2D 形狀顯示在這張圖片的左側:
Three.js 3D建模必備基礎

圖片中的其他兩個對象是通過擠壓形狀創(chuàng)建的。 在擠壓中,填充的 2D 形狀沿著 3D 路徑移動。 形狀穿過的點構成了 3D 實體。 在這種情況下,形狀是沿著垂直于形狀的線段拉伸的,這是最常見的情況。 基本的拉伸形狀顯示在插圖的右側。 中間的對象是具有“斜角”邊緣的相同形狀。 有關擠壓的更多詳細信息,請參閱 THREE.ExtrudeGeometry 的文檔和示例程序的源代碼。

3、紋理

紋理可用于為對象添加視覺趣味和細節(jié)。 在 three.js 中,圖像紋理由 THREE.Texture 類型的對象表示。 由于我們談論的是網頁,因此 three.js 紋理的圖像通常是從網址加載的。

圖像紋理通常是使用 THREE.TextureLoader 類型對象中的加載函數創(chuàng)建的。 該函數以 URL(網址,通常是相對地址)作為參數并返回一個 Texture 對象:

var loader = new THREE.TextureLoader();
var texture = loader.load( imageURL );

three.js 中的紋理被認為是材質的一部分。 要將紋理應用于網格,只需將 Texture 對象分配給網格上使用的網格材質的貼圖屬性:

material.map = texture;

貼圖屬性也可以在材質構造函數中設置。 所有三種類型的網格材質(Basic、Lambert 和 Phong)都可以使用紋理。 通常,材質基色為白色,因為材質顏色會與紋理顏色相乘。 非白色材質顏色會為紋理顏色添加“色調”。 將圖像映射到網格所需的紋理坐標是網格幾何體的一部分。 標準網格幾何體(例如 THREE.SphereGeometry)帶有已經定義的紋理坐標。

這是基本思想—從圖像 URL 創(chuàng)建紋理對象并將其分配給材質的貼圖屬性。 然而,也有一些復雜的東西。 首先,圖片加載是“異步的”。 也就是說,調用加載函數只會啟動加載圖像的過程,并且該過程可以在函數返回后的某個時間完成。 在圖像完成加載之前在對象上使用紋理不會導致錯誤,但對象將呈現為全黑。 加載圖像后,必須再次渲染場景以顯示圖像紋理。 如果動畫正在運行,這將自動發(fā)生; 加載完成后,圖像將出現在第一幀中。 但是,如果沒有動畫,則需要一種在圖像加載后渲染場景的方法。 事實上,TextureLoader 中的加載函數有幾個可選參數:

loader.load( imageURL, onLoad, undefined, onError );

這里的第三個參數未定義,因為不再使用該參數。 onLoad 和 onError 參數是回調函數。 onLoad 函數(如果已定義)將在成功加載圖像后調用。 如果嘗試加載圖像失敗,將調用 onError 函數。 例如,如果有一個渲染場景的函數 render(),那么 render 本身可以用作 onLoad 函數:

var texture = new THREE.TextureLoader().load( "brick.png", render );

onLoad 的另一種可能用途是延遲將紋理分配給材質,直到圖像完成加載。 如果你確實更改了 material.map 的值,請務必設置

material.needsUpdate = true;

以確保更改將在重繪對象時生效。

紋理有許多可以設置的屬性,包括用于設置紋理的縮小和放大過濾器的屬性,以及用于控制 mipmap 生成的屬性,這在默認情況下是自動完成的。 您最有可能想要更改的屬性是 0 到 1 范圍之外的紋理坐標的環(huán)繞模式和紋理變換。

對于紋理對象 tex,屬性 tex.wrapS 和 tex.wrapT 控制如何處理 0 到 1 范圍之外的 s 和 t 紋理坐標。 默認值為“clamp to edge”。 你很可能希望通過將屬性值設置為 THREE.RepeatWrapping 來使紋理在兩個方向上重復:

tex.wrapS = THREE.RepeatWrapping;

tex.wrapT = THREE.RepeatWrapping;

RepeatWrapping 最適合“無縫”紋理,其中圖像的上邊緣與下邊緣匹配,左邊緣與右邊緣匹配。 Three.js 還提供了一個有趣的變體,稱為“鏡像重復”,其中重復圖像的每個其他副本都被翻轉。 這消除了圖像副本之間的接縫。 對于鏡像重復,使用屬性值 THREE.MirroredRepeatWrapping:

tex.wrapS = THREE.MirroredRepeatWrapping;

tex.wrapT = THREE.MirroredRepeatWrapping;

紋理屬性 repeat 和 offset 控制作為紋理變換應用于紋理的縮放和平移。 (沒有紋理旋轉。)這些屬性的值屬于 THREE.Vector2 類型,因此每個屬性都有一個 x 和一個 y 分量。 對于紋理 tex,tex.offset 的兩個組件給出了水平和垂直方向的紋理平移。 要水平偏移紋理 0.5,可以這樣設置:

tex.offset.x = 0.5;

//or

tex.offset.set( 0.5, 0 );

請記住,正的水平偏移會將紋理移動到對象的左側,因為偏移應用于紋理坐標而不是紋理圖像本身。

屬性 tex.repeat 的組件給出了水平和垂直方向的紋理縮放。 例如,

tex.repeat.set(2,3);

將紋理坐標水平縮放 2 倍,垂直縮放 3 倍。 同樣,對圖像的影響是相反的,因此圖像在水平方向上縮小了 2 倍,在垂直方向上縮小了 3 倍。 結果是你在水平方向上得到了兩個圖像副本,而在水平方向上你會得到一個副本,在垂直方向上得到三個副本。 這解釋了名稱“repeat”,但請注意值不限于整數。

演示 c5/textures.html 顯示了應用于各種 three.js 對象的圖像紋理。

假設我們要在本節(jié)開頭創(chuàng)建的金字塔上使用圖像紋理。 為了將紋理圖像應用于對象,WebGL 需要該對象的紋理坐標。 當我們從頭開始構建網格時,我們必須提供紋理坐標作為網格幾何對象的一部分。

示例中的 pyramidGeom 等幾何對象具有名為 faceVertexUvs 的屬性,用于保存紋理坐標。 (“UV”是指物體上的坐標映射到紋理中的s和t坐標。)faceVertexUvs的值是一個數組,其中數組的每個元素本身就是一個數組數組; 在大多數情況下,僅使用元素 faceVertexUvs[0],但在某些高級應用程序中會使用額外的 uv 坐標集。 faceVertexUvs[0] 的值本身是一個數組,幾何中的每個面都有一個元素。 同樣,為每個面存儲的數據是一個數組:faceVertexUvs[0][N] 是一個數組,其中包含面編號 N 的三個頂點中的每一個的一對坐標。最后,該數組中的每對紋理坐標是 表示為 THREE.Vector2 類型的對象。

金字塔有六個三角形面。 每個面都需要一個包含三個 Vector2 類型對象的數組。 必須選擇坐標以將圖像以合理的方式映射到面部。 我選擇的坐標將整個紋理圖像映射到金字塔的正方形底部,并從圖像中切出一個三角形以應用于每個邊。 想出正確的坐標需要一些小心。 我定義金字塔幾何體的紋理坐標如下:

pyramidGeometry.faceVertexUvs = [[
    [ new THREE.Vector2(0,0), new THREE.Vector2(0,1), new THREE.Vector2(1,1) ],
    [ new THREE.Vector2(0,0), new THREE.Vector2(1,1), new THREE.Vector2(1,0) ],
    [ new THREE.Vector2(0,0), new THREE.Vector2(1,0), new THREE.Vector2(0.5,1) ],
    [ new THREE.Vector2(1,0), new THREE.Vector2(0,0), new THREE.Vector2(0.5,1) ],
    [ new THREE.Vector2(0,0), new THREE.Vector2(1,0), new THREE.Vector2(0.5,1) ],
    [ new THREE.Vector2(1,0), new THREE.Vector2(0,0), new THREE.Vector2(0.5,1) ],
]];

請注意,這是一個三維數組。

示例程序 threejs/textured-pyramid.html 顯示了帶有磚紋理的金字塔。

這是程序中的圖像:
Three.js 3D建模必備基礎

4、變換

為了理解如何在 three.js 中有效地使用對象,了解更多關于它如何實現變換會很有用。 我已經解釋過 Object3D 對象具有屬性 obj.position、obj.scale 和 obj.rotation,這些屬性在其自己的局部坐標系中指定其模型變換。

但是這些屬性在渲染對象時并不直接使用。 相反,它們被組合起來計算另一個屬性 obj.matrix,它將轉換表示為矩陣。 默認情況下,每次渲染場景時都會自動重新計算此矩陣。 如果轉換從不改變,這可能是低效的,所以 obj 有另一個屬性 obj.matrixAutoUpdate,它控制是否自動計算 obj.matrix。 如果將 obj.matrixAutoUpdate 設置為 false,則不會完成更新。 在這種情況下,如果確實想要更改模型的變換,可以調用 obj.updateMatrix() 以根據 obj.position、obj.scale 和 obj.rotation 的當前值計算矩陣。

我們已經了解了如何通過直接更改屬性 obj.position、obj.scale 和 obj.rotation 的值來修改 obj 的模型變換。 但是,你也可以通過調用函數 obj.translateX(dx)、obj.translateY(dy) 或 obj.translateZ(dz) 將對象沿坐標軸方向移動指定量來更改位置。 還有一個函數 obj.translateOnAxis(axis, amount),其中 axis 是一個 Vector3,amount 是一個給出平移對象距離的數字。 對象沿矢量軸的方向移動。 向量必須歸一化; 也就是說,它的長度必須為 1。例如,要在向量 (1,1,1) 的方向上將 obj 平移 5 個單位,這一這樣調用:

obj.translateOnAxis( new THREE.Vector3(1,1,1).normalize(), 5 );

沒有用于更改縮放變換的函數。 但是你可以使用函數 obj.rotateX(angle)、obj.rotateY(angle) 和 obj.rotateZ(angle) 更改對象的旋轉,以圍繞坐標軸旋轉對象。 (請記住,角度以弧度為單位。)調用 obj.rotateX(angle) 與將角度添加到 obj.rotation.x 的值上不同,因為它在其他旋轉之上應用繞 x 軸的旋轉 可能已經應用了。

還有一個函數 obj.rotateOnAxis(axis, angle),其中 axis 是一個 Vector3。 此函數將對象繞軸矢量(即,關于原點和軸給定的點之間的線)旋轉 angle 角度。 軸必須是歸一化向量。

我要強調的是平移和旋轉函數修改對象的位置和旋轉屬性。 也就是說,它們適用于對象坐標,而不是世界坐標,并且它們在渲染對象時作為對象的第一個模型變換應用。 例如,旋轉是世界坐標可以改變對象的位置,如果它不位于原點。 然而,改變一個對象的旋轉屬性的值永遠不會改變它的位置。

旋轉實際上更復雜。對象 obj 的旋轉實際上是由屬性 obj.quaternion 表示的,而不是由屬性 obj.rotation 表示的。四元數是計算機圖形學中經常使用的數學對象,作為 Euler 角的替代品來表示旋轉。但是,當你更改屬性 obj.rotation 或 obj.quaterion 之一時,另一個屬性會自動更新以確保兩個屬性表示相同的旋轉。因此,我們不需要直接使用 四元數。

還有一種更有用的方法來設置旋轉:obj.lookAt(vec),它旋轉對象使其面向給定點。 參數vec是一個Vector3,必須用物體自己的局部坐標系表示。 (對于沒有父對象或其祖先沒有模型變換的對象,這將與世界坐標相同。)該對象也被旋轉,使其“向上”方向等于屬性 obj.up 的值 ,默認情況下為 (0,1,0)。 此函數可用于任何對象,但對相機最有用。

5、加載 JSON 模型

雖然可以通過列出頂點和面來創(chuàng)建網格對象,但是對于除了非常簡單的對象以外的所有對象,手動創(chuàng)建是很困難的。 例如,在 Blender等交互式建模程序中設計對象要容易得多。 Three.js 具有從文件加載模型的實用函數,它附帶的腳本可用于將對象從 Blender 和其他 3D 建模程序導出為 three.js 可以讀取的文件格式。

Three.js 有自己的文件格式,其中模型使用 JSON 指定,JSON 是一種表示 JavaScript 對象的通用格式。 這是導出腳本生成的文件格式。 類 THREE.JSONLoader 可用于從此類文件中讀取模型描述。 還有一些其他加載器,可以處理其他文件格式,但我在這里只討論 JSONLoader。

如果 loader 是一個 THREE.JSONLoader 類型的對象,可以使用它的 load() 方法來啟動加載模型的過程:

loader.load( url, callback );

第一個參數是包含模型的文件的 URL。 JSON 模型存儲為實際的 JavaScript 代碼,因此該文件的名稱通常以“.js”結尾。 第二個參數 callback 是加載完成時將調用的函數。 加載是異步的; loader.load() 啟動進程并立即返回。

回調函數負責使用文件中的數據創(chuàng)建 three.js Object3D 并將其添加到場景中。 回調函數有兩個參數,geometry 和 materials,其中包含創(chuàng)建對象所需的信息; 參數表示已從文件中讀取的數據。 材料參數是一種材質或材質數組,可用作網格對象構造函數中的第二個參數。 當然,你也可以不使用文件中的材質,而是使用自己的。

下面函數可用于從指定的 url 加載 JSON 模型并將其添加到場景中:

function loadModel( url ) {  // Call this function to load the model.
    var loader = new THREE.JSONLoader();
    loader.load( url, modelLoaded ); // Start load, call modelLoaded when done.
}

function modelLoaded( geometry, material ) { // callback function for loader
    var object = new THREE.Mesh( geometry, material );
    scene.add(object);
    render(); // (only need this if there is no animation running)
}

示例程序 threejs/json-model-viewer.html 使用 JSONLoader 讀取模型描述。 它可以顯示七個不同的對象。 我使用 Blender 創(chuàng)建了其中一個對象。 其他對象帶有 three.js。 其中五個對象使用簡單的白色材料; “horse”和“stork”使用模型文件中作為頂點顏色(而非材質)提供的顏色。

我還需要指出, JSON 模型可以定義簡單的關鍵幀動畫。 為此,該文件包含每個關鍵幀的替代頂點集(three.js 稱它們?yōu)椤白冃文繕恕保?Three.js 有幾個支持動畫的類,包括 THREE.AnimationMixer、THREE.AnimationAction 和 THREE.AnimationClip。 這里不討論動畫,在線演示 c5/mesh-animation.html 中這三個類用于制作馬和鸛模型的動畫。


原文鏈接:Three.js 3D建?;A — BimAnt文章來源地址http://www.zghlxwxcb.cn/news/detail-406315.html

到了這里,關于Three.js 3D建模必備基礎的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 【Three.js基礎入門】:創(chuàng)建你的第一個3D場景

    【Three.js基礎入門】:創(chuàng)建你的第一個3D場景

    Three.js是一種強大的JavaScript庫,用于在Web瀏覽器中創(chuàng)建交互式的3D圖形和動畫。無需熟練的圖形編程經驗,你也可以通過Three.js輕松地構建令人驚嘆的3D場景。 本文將帶你逐步學習如何入門Three.js,從創(chuàng)建一個簡單的3D場景開始。 我們將介紹如何使用Three.js創(chuàng)建你的第一個3D場景

    2024年02月16日
    瀏覽(764)
  • THREE.JS使用詳細(three.js創(chuàng)建3d物體,three.js的使用方式)

    THREE.JS使用詳細(three.js創(chuàng)建3d物體,three.js的使用方式)

    簡述:three.js封裝了WebGL的底層細節(jié),是一款運行在瀏覽器中的 3D 引擎,可以用它創(chuàng)建各種三維場景,包括了攝影機、光影、材質等各種對象,目前在Git上已經擁有90k+的star,今天用three.js來構建一個三維模型; 1、首先,在項目中需要下載threejs的相關依賴; 2、在js頁面引入使

    2024年01月23日
    瀏覽(230)
  • three.js(一):認識three.js并創(chuàng)建第一個3D應用

    three.js(一):認識three.js并創(chuàng)建第一個3D應用

    1-three.js 是什么? three.js是用JavaScript編寫的WebGL第三方庫; three.js 提供了非常多的3D顯示和編輯功能; 具體而言,three.js 是一款運行在瀏覽器中的 3D 引擎,可以用three.js 創(chuàng)建各種三維場景,并對其進行編輯; 在three.js 的官網上看到許多精彩的演示和文檔 three.js 官網:https://thre

    2024年02月11日
    瀏覽(310)
  • three.js添加3d模型

    three.js添加3d模型

    three官方的幾何體也就那么幾個,想要生成各種各樣的模型,其難度十分之大,這時引入外部模型也不失為一種選擇。具體引入辦法如下。 雖然名字為GLTFLoader,但實際上glb文件也是能加載的。 其中需要注意的是調節(jié)相機參數與相機位置,否則很有可能導致場景中看不見任何東

    2024年02月04日
    瀏覽(104)
  • Three.js3D可視化介紹,以及本地搭建three.js官網

    Three.js3D可視化介紹,以及本地搭建three.js官網

    一、什么是Three.js three.js官網 :https://threejs.org/ Three.js 是一個基于 WebGL 的 JavaScript 3D 圖形庫,它可以輕松地在瀏覽器中 創(chuàng)建3D場景和動畫 。同時,它支持外部模型和紋理的導入,讓開發(fā)者可以更加便捷地創(chuàng)建出震撼的 3D場景 。 Three.js 的應用場景非常廣泛,主要包括以下幾個

    2024年02月09日
    瀏覽(299)
  • Three.js教程:對象克隆、復制

    推薦:將 NSDT場景編輯器 加入你的3D工具鏈 其他系列工具: NSDT簡石數字孿生 Threejs大多數對象都有克隆 .clone() 和復制 .copy() 兩個方法,點模型 Points 、線模型 Line 、網格網格模型 Mesh 一樣具有這兩個方法。 A.copy(B) 表示B屬性的值賦值給A對應屬性。 N = M.clone() 表示返回一個和

    2024年02月08日
    瀏覽(13)
  • 【three.js / React-three-fiber】加載3D模型性能優(yōu)化

    【three.js / React-three-fiber】加載3D模型性能優(yōu)化

    無論是大型虛擬世界還是簡單的網站,性能優(yōu)化都是必要的。 特別是在運用三維模型的情況下,我們需要更加深入的優(yōu)化。因為 三維模型通常包含大量的數據和復雜的幾何形狀 ,如果不進行性能優(yōu)化,瀏覽器可能會因為負載過重而崩潰。 在本文中,我們將探討如何在 thre

    2024年02月02日
    瀏覽(24)
  • Three.js之創(chuàng)建3D場景

    【G】Three.js官方文檔:https://threejs.org/docs/ Three.js是一個流行的WebGL庫,官方文檔提供了詳細的API參考和示例,適合學習和參考。 【G】Three.js GitHub鏈接:https://github.com/mrdoob/three.js 這是一個流行的基于WebGL的3D圖形庫,提供了豐富的功能和工具,用于創(chuàng)建交互式的3D場景和應用。

    2024年02月14日
    瀏覽(160)
  • Three.js中的3D文字效果

    Three.js中的3D文字效果

    對于一些設計網頁中經常會出現一些3D的文字效果,本文將利用Three.js實現各種動畫WebGL文本輸入效果。 示例效果 原文章 通常情況下,文本網格是2D的平面形狀,我們所要實現的3D文本形狀則是要在2D的平面下,再生成z值形成一個立體的效果。 首先,我們創(chuàng)建一個canvas元素,

    2024年02月02日
    瀏覽(22)
  • Three.js--》實現3d小島模型搭建

    Three.js--》實現3d小島模型搭建

    目錄 項目搭建 初始化three.js基礎代碼 設置環(huán)境背景 設置水面樣式 添加天空小島 今天簡單實現一個three.js的小Demo,加強自己對three知識的掌握與學習,只有在項目中才能靈活將所學知識運用起來,話不多說直接開始。 項目搭建 本案例還是借助框架書寫three項目,借用vite構建

    2024年02月05日
    瀏覽(430)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包