日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

threejs 三面体_three.js初探,立体几何入手(一)

發布時間:2024/1/1 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 threejs 三面体_three.js初探,立体几何入手(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言:首先先推薦一篇博客,關于webgl原理,講的非常之通俗易懂了?圖解WebGL&Three.js工作原理??webGL可以理解為openGL ES2.0

(webGL2.0 - openGL ES3.0)的javascript綁定。所以實現的語言是javascript和opengl(最常用的跨平臺圖形庫)著色語言,webgl是

HTML5中提出的新技術,是一種3D繪圖標準。

three.js是以webgl為基礎的庫,封裝了一些3D渲染需求中重要的工具方法與渲染循環。WebGL門檻相對較高,Three.js對WebGL提供的接

口進行了非常好的封裝,簡化了很多細節,大大降低了學習成本

我們可能還聽說過一個D3.js(Data-Driven Documents),是一個數據可視化的庫,技術基礎是SVG。兼容性是IE9+,官網(http://d3js.org),

從官網的example中可以看出,它跟3d視圖還是不同的。

我們只需要從官網上下載一個three.js,然后用script標簽引入即可。

首先注意的一點是,我們在頁面上并不需要一個canvas標簽,只需要一個盛放canvas的容器就行,canvas是three.js動態生成的。

01.01 - WebGLRenderer - Skeleton

#canvas3d{

width:800px;

height:450px;

margin:100px auto;

}

threejs里最重要的幾個元素,如下:

var renderer; //渲染器

var scene;   //場景

var camera; //相機

var light;   //光源

var cube; //物體

1,生成3d渲染器,設置渲染器的寬高和背景色,(通常我們可以直接獲取頁面上畫布的寬高,便于嵌入改動)

renderer = new THREE.WebGLRenderer({antialias:true}); //生成渲染器對象(antialias屬性:抗鋸齒效果為設置有效)

renderer.setClearColor(0x333333, 1.0);

//renderer.setSize(window.innerWidth, window.innerHeight);

renderer.setSize('800', '450');

2,設置一個場景,也就是一個三維空間,用 [Scene] 類聲明一個叫 [scene] 的對象。

scene = new THREE.Scene();

3,設置一個攝像機camera,

OpenGL(WebGL)中、三維空間中的物體投影到二維空間的方式中,存在透視投影和正投影兩種相機。 透視投影就是、從視點開始越近的物體越大、遠處的物體繪制的較小的一種方式、和日常生活中我們看物體的方式是一致的。 正投影就是不管物體和視點距離,都按照統一的大小進行繪制、在建筑和設計等領域需要從各個角度來繪制物體,因此這種投影被廣泛應用。在 Three.js 也能夠指定透視投影和正投影兩種方式的相機。

正交投影與透視投影的區別如上圖所示,左圖是正交投影,物體發出的光平行地投射到屏幕上,遠近的方塊都是一樣大的;右圖是透視投影,近大遠小,符合我們平時看東西的感覺。

camera坐標系

Three中使用采用常見的右手坐標系定位。

// 四個參數分別代表了攝像機的視角、寬高比、近和遠兩個視截面。

//設置透視投影的相機,默認情況下相機的上方向為Y軸,右方向為X軸,沿著Z軸朝里(視野角:fov 縱橫比:aspect 相機離視體積最近的距離:near 相機離視體積最遠的距離:far)

camera = new THREE.PerspectiveCamera(90, window.innerWidth / window.innerHeight, 0.1, 1000);

// position and point the camera to the center of the scene

camera.position.x = 20;

camera.position.y = 18;

camera.position.z = 35;

camera.lookAt(scene.position); //設置視野的中心坐標

4,設置光源light

OpenGL(WebGL)的三維空間中,存在點光源和聚光燈兩種類型。 而且,作為點光源的一種特例還存在平行光源(無線遠光源)。另外,作為光源的參數還可以進行 [環境光] 等設置。 作為對應, Three.js中可以設置 [點光源(Point Light)] [聚光燈(Spot Light)] [平行光源(Direction Light)],和 [環境光(Ambient Light)]。 和OpenGL一樣、在一個場景中可以設置多個光源。 基本上,都是環境光和其他幾種光源進行組合。 如果不設置環境光,那么光線照射不到的面會變得過于黑暗.

//設置light

light = new THREE.DirectionalLight(0xff0000, 1.0, 0); //設置平行光

light.position.set( 200, 200, 200 ); //設置光源向量

scene.add(light); // 追加光源到場景

5,設置物體 object

在three.js中,我們使用Mesh模型,Mesh的構造函數是這樣的:Mesh( geometry, material )?geometry是它的形狀,material是它的材質。 三維模型通常用三角形的網格來描述

對于圖中的兔子,隨著三角形數量的增加,它的表面越來越平滑/準確

我們這里是一個立方體 cube

var cubeGeometry = new THREE.BoxGeometry(20, 10, 15,2,3,1); //設置長寬高 以及對應長寬高的分段,在使用線模式({wireframe:true})進行渲染的時候可以看到效果

var cubeMaterial = new THREE.MeshNormalMaterial({wireframe : true}); //材質

cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

var border = new THREE.EdgesHelper( cube,0xffff00 ); //添加邊框

scene.add(cube);

scene.add(border);

6,最后一步,進行渲染

//將渲染器的元素添加到頁面中

document.getElementById('canvas3d').appendChild(renderer.domElement);

renderer.render(scene, camera);

完整的代碼已經上傳到github上: github(three-one)? 如果你覺得我寫的對你有所幫助的話,請給我個star吧,謝謝

最后的效果圖如下:

在上面的學習基礎上,我們繼續深入的探究一下,如何給3d視圖添加動畫,紋理等;

1,首先我們在上面的基礎上,添加多個立體幾何圖形

//立方體

var cubeGeometry = new THREE.BoxGeometry(15,15,15,1,1,1);

var cubeMaterial = new THREE.MeshNormalMaterial({wireframe : true}); //材質

cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

var border = new THREE.EdgesHelper( cube,0xffff00 ); //添加邊框

scene.add(cube);

scene.add(border);

//圓柱體

var cylinderGeometry = new THREE.CylinderGeometry(8, 8,10,30,30);

var cylinderMaterial = new THREE.MeshNormalMaterial();

var cylinder = new THREE.Mesh(cylinderGeometry,cylinderMaterial);

cylinder.position.x = -10;

cylinder.position.y = -5;

cylinder.position.z = 25;

cylinder.castShadow = true;

scene.add(cylinder);

//球體

var sphereGeometry = new THREE.SphereGeometry(7, 25, 25);

var sphereMaterial = new THREE.MeshLambertMaterial({color: 0x7777ff});

var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);

// position the sphere

sphere.position.x = 0;

sphere.position.y = 0;

sphere.position.z = 0;

sphere.castShadow = true;

// add the sphere to the scene

scene.add(sphere);

//圓環

var torusGeometry = new THREE.TorusGeometry(10,3,20,20);

var torusMaterial = new THREE.MeshBasicMaterial();

var tours = new THREE.Mesh(torusGeometry,torusMaterial);

tours.position.x = 10;

tours.position.y = -10;

tours.position.z = -40;

tours.castShadow = true;

scene.add(tours);我們通過position屬性

調整立體幾何在scene中的位置(x,y,z)

創建幾何體時有一點強調的是,對于參數的設置,例如創建圓環的時候,

THREE.TorusGeometry(10,3,20,20)

我們第三四個參數分割比的值越大,立體幾何中拼湊的平面圖形就越多,立體幾何就越圓滑,就是上一篇博客中兔子的那個原理。

2,添加動畫

我們要針對每個幾何體添加不同的動畫,所以就需要為每個幾何體添加一個name屬性來指定,比如:

cube.name = 'cube';

cylinder.name = 'cylinder';

然后在render函數中,用getObjectByName獲取到對應的幾何體,用setInterval的思想原理,通過requestAnimationFrame函數使得幾何體動起來

scene.getObjectByName('cube').rotation.x += control.rotationSpeed;

scene.getObjectByName('cube').scale.set(control.scale, control.scale, control.scale);

scene.getObjectByName('cylinder').rotation.z += control.rotationSpeed2;

scene.getObjectByName('tours').rotation.z += 0.05;

requestAnimationFrame(render);

3,stats性能插件

stats.js用于對JavaScript進行性能檢測。

我們創建一個createStats的函數,然后在init初始化中調用它

function createStats() {

var stats = new Stats();

stats.setMode(0);

stats.domElement.style.position = 'absolute';

stats.domElement.style.left = '0px';

stats.domElement.style.top = '5px';

return stats;

}

需要特別注意的一點是,我們需要在render函數中不斷的更新stats顯示

stats.update();

dat.gui.js用于創建菜單欄,可以用來控制場景中的各個參數來調試場景。

function addControls(controlObject){

var gui = new dat.GUI();

gui.add(controlObject,'rotationSpeed',-0.1,0.1);

gui.add(controlObject, 'scale', 0.01, 2);

gui.add(controlObject, 'rotationSpeed2', -0.1, 0.1);

}

創建addControls函數,然后在init初始化函數中設置默認值,并調用這個函數

control = new function (){

this.rotationSpeed = 0.005;

this.scale = 1;

this.rotationSpeed2 = 0.05;

}

addControls(control);

4,添加紋理

這個首先注意的就是圖片應該是異步獲取的,所以你可以放在本地的apache中,也可以自己用nodejs非常方便的搭建一個服務器,不然的話,他就會報錯,跨域了。

var texture = new THREE.ImageUtils.loadTexture("http://10.1.26.29:84/Brick-2399.jpg");

torusMaterial.map = texture;

最后的效果圖如下:

完整的代碼:github(threejs-two)? 如果你覺得我寫的對你有幫助的話,請給我個star吧,謝謝,我會繼續更新下去的

5,最后,從完整的代碼中,我們可以看出,關于材質,我們也是調用了不同的函數,這里總結一下材質

材質種類:

MeshBasicMaterial:為幾何體賦予一種簡單的顏色,或者顯示幾何體的線框

MeshDepthMaterial:根據網格到相機的距離,該材質決定如何給網格染色

MeshNormalMaterial:根據物體表面的法向量計算顏色

MeshFaceMaterial:這是一種容器,可以在該容器中為物體的各個表面上設置不同的顏色

MeshLambertMaterial:考慮光照的影響,可以創建顏色暗淡,不光亮的物體

MeshPhongMaterial:考慮光照的影響,可以創建光亮的物體

ShaderMaterial:使用自定義的著色器程序,直接控制頂點的放置方式,以及像素的著色方式。

LineBasicMaterial:可以用于THREE.Line幾何體,從而創建著色的直線

LineDashedMaterial:類似與基礎材質,但可以創建虛線效果

(1)MeshBasicMaterial:不考慮光照的影響。

屬性:

color

wireframe

wireframeLinewidth

wireframeLinecap:線段端點如何顯示。可選值有:butt(平)、round、square。默認是round。WebGLRenderer對象不支持該屬性。

wireframeLinejoin:線段連接點如何顯示??蛇x值有:round、bevel(斜角)、miter(尖角)。默認是round。WebGLRenderer對象不支持屬性。

shading:著色模式。可選值:THREE.SmoothShading、THREE.FlatShading。

vertexColors:為每個頂點定義不同的顏色。在CanvasRenderer對象中不起作用。

fog:指示當前是否會受全局霧化效果設置的影響。

兩種設置屬性的方式:

//1.構造函數

var meshMaterial = new THREE.MeshBasicMaterial({color:0xffccff});

//2屬性

meshMaterial.visible = false;

(2)MeshDepthMaterial

使用這種材質的物體,其外觀不是由光照或某個材質屬性決定的;而是由物體到相機的距離決定的??梢詫⑦@種材質與其他材質相結合,從而很容易創建逐漸消失的效果。

只有兩個控制線框的屬性:

wireframe

wireframeLinewidth

可以通過設置相機的near和far的值,來控制創建中使用這種材質的物體的消失速度。如果near和fat之間的差值越大,那么物體遠離相機時,只會稍微消失一點;反之,物體消失的效果非常明顯。

var cubeMaterial = new THREE.MeshDepthMaterial();

var colorMaterial = new THREE.MeshBasicMaterial({color:0x00ff00,transparent:true,blending:THREE.MultiplyBlending});

var cube = new THREE.SceneUtils.createMultiMaterialObject(cubeGeometry,[colorMaterial,cubeMaterial]);

cube.children[1].scale.set(0.99,0.99,0.99);//避免渲染遮擋而造成的閃爍

(3)MeshNormalMaterial

法向量的作用:?決定光的發射方向、在計算光照、陰影時提供信息、為物體表面上色。法向量所指的方向決定每個面從MeshNormalMaterial材質獲取的顏色。

屬性:

wireframe

wireframeLinewidth

shading

for(var f = 0 , f1 = sphere.geometry.faces.length; f < f1 ; f++){

var face = spere.geometry.faces[f];

var arrow = new THREE.ArrowHelper(face.normal,face.centroid,2,0x3333ff);

spere.add(arrow);

}

在球體的每個面上添加了一個長度為2,顏色為0x3333ff的箭頭

(4)MeshFaceMaterial

可以為幾何體的每一個面指定不同的材質。

假設有一個正方體,可以為每個面指定不同的顏色。

var matArray = [];

matArray.push(new THREE.MeshBasicMaterial({color:0x00ff00}));

matArray.push(new THREE.MeshBasicMaterial({color:0x00ff00}));

matArray.push(new THREE.MeshBasicMaterial({color:0x00ff00}));

matArray.push(new THREE.MeshBasicMaterial({color:0x00ff00}));

matArray.push(new THREE.MeshBasicMaterial({color:0x00ff00}));

matArray.push(new THREE.MeshBasicMaterial({color:0x00ff00}));

var faceMaterial = new THREE.MeshFaceMaterial(matArray);

var cubeGeometry = new THREE.CubeGeometry(3,3,3);

var cube = new THREE.Mesh(cubeGeometry,faceMaterial);

(5)MeshLambertMaterial

對光源有反應。

基本屬性:

color、opacity、shading、blending、depthTest、depthWrite、wireframe、wireframeLineWith、wirefLinecap、wireframeLinejoin、vertexColors、fog。

獨特屬性:

ambient:和AmbientLight光源一起使用。該顏色會與AmbientLight光源的顏色相乘。默認是白色。

emissive:該材質發射的屬性。不像是光源,只是一種純粹的、不受其他光照影響的顏色。默認是黑色。

(6)MeshPhongMaterial

基本屬性:

color、opacity、shading、blending、depthTest、depthWrite、wireframe、wireframeLineWith、wirefLinecap、wireframeLinejoin、vertexColors、fog。

獨特屬性:

ambient

emissive

specular:指定該材質的光亮程度及其高光部分的顏色。如果將他設置成跟color屬性相同的顏色,將會得到一種更加類似金屬的材質。如果設置為灰色,材質將變得更像塑料。

shininess:指定高光部分的亮度。默認是30.

(7)ShaderMaterial

屬性:

wireframe

wireframeLinewidth

shading

vertexColor

fog:指示當前是否會受全局霧化效果設置的影響。

獨特屬性:

fragmentShader:定義每個傳入的像素的顏色。

vertexShader:允許你修改每一個傳入的頂點的位置

uniforms:該屬性可以向你的著色器發送消息。將同樣的信息發送到每一個頂點和片段。

defines:該屬性可以轉換為vertexShader和fragmentShader里的#define代碼。該屬性可以用來設置著色器程序里的一些全局變量。

attributes:該屬性可以修改每個頂點和片段。常用來傳遞位置數據和法向量相關的數據。如果要用這個屬性,辣么你要為幾何體中的所有頂點提供信息。

lights:定義光照數據是否傳遞給著色器。默認是false。

獨特屬性:

fragmentShader:定義每個傳入的像素的顏色。

vertexShader:允許你修改每一個傳入的頂點的位置

uniforms:該屬性可以向你的著色器發送消息。將同樣的信息發送到每一個頂點和片段。

defines:該屬性可以轉換為vertexShader和fragmentShader里的#define代碼。該屬性可以用來設置著色器程序里的一些全局變量。

attributes:該屬性可以修改每個頂點和片段。常用來傳遞位置數據和法向量相關的數據。如果要用這個屬性,辣么你要為幾何體中的所有頂點提供信息。

lights:定義光照數據是否傳遞給著色器。默認是false。

(8)LineBasicMaterial

基本屬性:

color

lineWidth

LineCap:butt、round、square。默認是round。WebGLRenderer不支持該屬性。

LineJoin:round、bevel(斜切)、miter(尖角)。默認是round。WebGLRenderer不支持該屬性。

vertexColors:該屬性值設置為 THREE.VertexColors值時,就可以為每個頂點指定一種顏色。

fog:指定當前物體是否受全局霧化效果的影響。

(9)LineDashedMaterial

和LineBasicMaterial有著一樣的屬性,但是有幾個額外的屬性,可以用來定義短劃線長度和短劃線中間空格長度的屬性。

獨特屬性:

scale:縮放dashSize和gapSize。如果scale<1,則dashSize和gapSize就會增大。

dashSize:短線劃的長度

gapSize:間隔的長度

總結

以上是生活随笔為你收集整理的threejs 三面体_three.js初探,立体几何入手(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。