使用threejs繪制簡單的3D圖形


  首先,如果想要學習threejs,先去看看 官方基礎教程 ,里面闡述了threejs的核心概念和一些重要的對象。這邊文章就是具體使用threejs加入3D圖形的一個水文,看了自由添加其他物體有個參照。

  使用threejs繪制3D圖形,一般繪制的結果都是通過canvas元素生成,對於平面、3D效果、視角變化和交互、動畫這一塊,使用threejs可以快速便捷地幫助我們完成工作,而不必一步一步創建canvas,獲取context再逐條繪制。threejs有一些基本概念在使用之前必須要了解。

  核心三大塊:場景、相機、渲染器。作用分別為:在canvas中展示所有內容的3D容器、顯示3D容器中可見區域的投影框、畫面選定后進行拍照展示的渲染器。所有渲染器渲染時需要確定場景和相機。
  在實際進行繪制更加豐富的內容時,threejs提供了許多對象可以很快的完成一個復雜的3D圖形,並且對於3D圖像的靈活多變的調整。這些對象包括有幾何形狀、材料、光線、計時器、射線、輔助線、動畫、音頻、模型加載器、控制器等,除此之外還有例如矩陣、四元數等等一些進階的運算,簡單應用都不會涉及。
  首先創建三大核心對象:
   場景
  對於一個3D應用,場景應當是唯一的,所有相關的內容都應當添加到唯一的場景中,不管是要顯示還是不顯示的,顯示的畫面是通過調整相機角度決定的。所有場景就是所有具體內容的容器。
const scene = new THREE.Scene();

   場景的初始化可以自定義其中一些內容,Scene接收對象形式的參數,比較有用屬性的包括:

    * fog: 表示是否在場景中添加霧氣效果,在3D空間中會變成一個有可見度的空間,默認值為null,可以設置一個Fog對象
    * overrideMaterial:默認值是null,可以設定一個Material對象,這樣場景中所有的物體被渲染出來就會是設定的材料
 
   相機
  相機用於控制3D空間顯示的區域,通常會采用顯示距離的透視相機和顯示投影的正交相機,當然以可以直接使用相機,並配置合適的參數來實現相應的相機。透視相機會根據場景中物體默認Z軸的深度進行近大遠小的顯示,而正交投影相機則會將遠近不同的物體按正常的比例進行顯示。
  普通相機直接使用:const camera = new THREE.Camera();
  3D場景匯總常用透視相機, 如果是生成一個透視相機,那么對於3D空間內同樣大小但是Z軸距離不容的兩個物體在相機中同時顯示,更遠的物體顯示更小。
const camera = new THREE.PerspectiveCamera(45, 1, 1, 100);
  透視相機默認接受4個參數,分別表示視角、截面縱橫比, 近截面距離,遠截面距離(具體參數解釋看上面那個鏈接,還有模型可看)
   渲染器
  瀏覽器中3D效果展示是基於webGL的API,使用渲染器從名字上能夠體現這一點
const renderer = new THREE.WebGLRenderer();
  初始化是可以配備參數的:
    * canvas:傳遞一個canvas的dom元素,如果不傳入,那么會新增畫布,通過renderer.domElement來獲取,畫布用於展示繪制的內容
    * alpha: 畫布默認是黑色背景,有時候我們只想要顯示的內容有顏色,那么這一項就要設置為true
    * antialias:抗鋸齒效果,顧名思義,默認為false
    * logarithmicDepthBuffer:這個值默認為false,是采用對數深度檢測的內容,場景中物體離視野的距離不一,一般情況下在物體重疊時顯示近的物體,特殊情況有可能深度判定有問題,前后材料有重疊破損的表現,此時就需要設置為true
 
  三個核心對象確定完畢,那么就和頁面直接關聯起來,設置畫布大小並添加到body中:
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

   下面就粗暴地添加一組物體:

  所謂組的概念,是由於場景中3D圖形是一個一個的,多個3D圖形就可以組成一組,一個或者一組圖形都可以通過name屬性命名,並通過name找到對應的3D對象。對於一個場景中有多個模型,分組是十分必要的。

  添加一組物體,首先要有一個物體,物體有形狀,有材料,要想顯示材料就需要有光,更多地還需要確定物體的位置、旋轉角度、縮放比例。想要顯示還需要添加到場景中,相機正確就位,渲染器將相機定住的視野進行拍照渲染。
let group = new THREE.Group();
scene.add(group);

// 添加兩個物體
let cube = new THREE.BoxGeometry( 10, 10, 10 );
let boxMaterial = new THREE.MeshBasicMaterial( {color: 0x00ff00, wireframe: true} );
let box = new THREE.Mesh( cube, boxMaterial );
box.position.x = 10;
group.add( box );
let sphere
= new THREE.SphereGeometry( 5, 32, 32 ); let sphereMaterial = new THREE.MeshNormalMaterial({ wireframe: true, transparent: true} ); let blet = new THREE.Mesh( sphere, sphereMaterial ); blet.position.x = -10; group.add( blet ); // 添加光 let light = new THREE.AmbientLight( 0x404040 ); scene.add( light ); // 想要看到空間內的物體,需要調整一下距離和方位 camera.position.z = 100; // 更新空間需要重新渲染 renderer.render(scene, camera);

   Geometry對應有許多幾何形狀,大部分都進行封裝,規則圖形很好進行繪制,獨特的圖形也需要自己描點傳入數據繪制,比如shape。

  材料又分許多種,這里材料都用到wireframe,便於觀察我們添加的物體的確是3D結構。

  場景中有一個組,那么組內所有顯示的3D對象都是在場景中的。而想要顯示必須要確保視野對着物體,也就是camera的位置、角度都合適,然后有光才能看見材料的顏色。最后別忘了render一下。

  這時候場景中是這樣的:

  好像3D想過也不是很明顯,那么加上動畫轉一轉,將兩個物體延自身中心旋轉:

window.requestAnimationFrame(function animate() {
  requestAnimationFrame(animate);
  box.rotation.x += 0.01; 
  box.rotation.y += 0.01; 
  blet.rotation.x += 0.01;
  blet.rotation.y += 0.01;
  renderer.render(scene, camera)
})

 

   差不多這樣吧:

 

   更多用法參考:https://threejs.org/examples/

  還是很有意思的。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM