⑴ three.js obj模型如何轉成json 給threejs使用啊
具體實現步驟:
obj轉換成js:
不要打開Python.
下載three.js。並將utilsexportersmaya
目錄下的plug-ins和scripts文件。拷貝到C:中,在maya插件管理版界面中開啟權threeJsFileTranlator.py即直接在命令行運行 python convert_obj_three.py -i ... 。
⑵ ThreeJS簡介
近年來web得到了快速的發展。隨著HTML5的普及,網頁的表現能力越來越強大。網頁上已經可以做出很多復雜的動畫,精美的效果。 但是,人總是貪的。那麼,在此之上還能做什麼呢?其中一種就是通過WebGL在網頁中繪制高性能的3D圖形。
OpenGL 它是最常用的跨平台圖形庫。
WebGL 是基於 OpenGL 設計的面向web的圖形標准,提供了一系列javaScript API,通過這些API進行圖形渲染將得以利用圖形硬體從而獲得較高性能。
而 Three.js 是通過對 WebGL 介面的封裝與簡化而形成的一個易用的圖形庫。
簡單點的說法 threejs=three + js ,three表示3D的意思,js表示javascript的意思。那麼合起來,three.js就是使用javascript 來寫3D程序的意思。而javascript的計算能力因為google的V8引 擎得到了迅猛的增強,做3D程序,做伺服器都沒有問題。
WebGL 門檻相對較高,需要相對較多的數學知識(線性代數、解析幾何)。因此,想要短時間上手 WebGL 還是挺有難度的。 Three.js 對 WebGL 提供的介面進行了非常好的封裝,簡化了很多細節,大大降低了學習成本。並且,幾乎沒有損失 WebGL 的靈活性。
因此,從 Three.js入 手是值得推薦的,這可以讓你在較短的學習後就能面對大部分需求場景。
Three.js 的入門是相對簡單的,但是當我們真的去學的時候,會發現一個很尷尬的問題:相關的學習資料很少。
通常這種流行的庫都有很完善的文檔,很多時候跟著官方的文檔或官方的入門教程學習就是最好的路線。但Three不是的,它的文檔對初學者來說太過簡明扼要。
不過官方提供了非常豐富的examples,幾乎所有你需要的用法都在某個example中有所體現。但這些example不太適合用來入門,倒是適合入門之後的進一步學習。
這里推薦一些相對較好的教程:
當然,實際的學習過程中這些資料肯定是不太夠的,遇到問題還是要自己去查資料。不過這里要提醒一下,Three.js的更新是相當頻繁的,現在是r80版本,自2010年4月發布r1以來,這已經是第72個版本了(中間有的版本號跳過了)。因此,在網上找到的資料有些可能是不適合當前版本的,需要注意甄別(前面推薦的資料也都或多或少存在這樣的問題)。
要在屏幕上展示3D圖形,思路大體上都是這樣的:
1、構建一個三維空間
Three中稱之為場景(Scene)
2、選擇一個觀察點,並確定觀察方向/角度等
Three中稱之為相機(Camera)
3、在場景中添加供觀察的物體
Three中的物體有很多種,包括Mesh,Line,Points等,它們都繼承自Object3D類
4、將觀察到的場景渲染到屏幕上的指定區域
Three中使用Renderer完成這一工作
場景是所有物體的容器,也對應著我們創建的三維世界。
Camera是三維世界中的觀察者,為了觀察這個世界,首先我們要描述空間中的位置。 Three中使用採用常見的右手坐標系定位。
Three中的相機有兩種,分別是正投影相機THREE.OrthographicCamera和透視投影相機THREE.PerspectiveCamera。
這里補充一個視景體的概念:視景體是一個幾何體,只有視景體內的物體才會被我們看到,視景體之外的物體將被裁剪掉。這是為了去除不必要的運算。
正交投影相機的視景體是一個長方體,OrthographicCamera的構造函數是這樣的:
Camera本身可以看作是一個點,left則表示左平面在左右方向上與Camera的距離。另外幾個參數同理。於是六個參數分別定義了視景體六個面的位置。
可以近似地認為,視景體里的物體平行投影到近平面上,然後近平面上的圖像被渲染到屏幕上。
2)透視投影相機
fov對應著圖中的視角,是上下兩面的夾角。aspect是近平面的寬高比。在加上近平面距離near,遠平面距離far,就可以唯一確定這個視景體了。
透視投影相機很符合我們通常的看東西的感覺,因此大多數情況下我們都是用透視投影相機展示3D效果。
有了相機,總要看點什麼吧?在場景中添加一些物體吧。
Three中供顯示的物體有很多,它們都繼承自Object3D類,這里我們主要看一下Mesh和Points兩種。
1)Mesh
我們都知道,計算機的世界裡,一條弧線是由有限個點構成的有限條線段連接得到的。線段很多時,看起來就是一條平滑的弧線了。
計算機中的三維模型也是類似的,普遍的做法是用三角形組成的網格來描述,我們把這種模型稱之為Mesh模型。
geometry是它的形狀,material是它的材質。
不止是Mesh,創建很多物體都要用到這兩個屬性。下面我們來看看這兩個重要的屬性。
2)Geometry
Geometry,形狀,相當直觀。Geometry通過存儲模型用到的點集和點間關系(哪些點構成一個三角形)來達到描述物體形狀的目的。
Three提供了立方體(其實是長方體)、平面(其實是長方形)、球體、圓形、圓柱、圓台等許多基本形狀;
你也可以通過自己定義每個點的位置來構造形狀;
對於比較復雜的形狀,我們還可以通過外部的模型文件導入。
3)Material
Material,材質,這就沒有形狀那麼直觀了。
材質其實是物體表面除了形狀以為所有可視屬性的集合,例如色彩、紋理、光滑度、透明度、反射率、折射率、發光度。
這里講一下材質(Material)、貼圖(Map)和紋理(Texture)的關系。
材質上面已經提到了,它包括了貼圖以及其它。
貼圖其實是『貼』和『圖』,它包括了圖片和圖片應當貼到什麼位置。
紋理嘛,其實就是『圖』了。
Three提供了多種材質可供選擇,能夠自由地選擇漫反射/鏡面反射等材質。
4)Points
講完了Mesh,我們來看看另一種Object——Points。
Points其實就是一堆點的集合,它在之前很長時間都被稱為ParticleSystem(粒子系統),r68版本時更名為PointCloud,r72版本時才更名為Points。更名主要是因為,Mr.doob認為,粒子系統應當是包括粒子和相關的物理特性的處理的一套完整體系,而Three中的Points簡單得多。因此最終這個類被命名為Points。
5)Light
神說:要有光!
光影效果是讓畫面豐富的重要因素。
Three提供了包括環境光AmbientLight、點光源PointLight、 聚光燈SpotLight、方向光DirectionalLight、半球光HemisphereLight等多種光源。
只要在場景中添加需要的光源就好了。
6)Renderer
在場景中建立了各種物體,也有了光,還有觀察物體的相機,是時候把看到的東西渲染到屏幕上了。這就是Render做的事情了。
Renderer綁定一個canvas對象,並可以設置大小,默認背景顏色等屬性。
調用Renderer的render函數,傳入scene和camera,就可以把圖像渲染到canvas中了。
現在,一個靜態的畫面已經可以得到了,怎麼才能讓它動起來?
很簡單的想法,改變場景中object的位置啊角度啊各種屬性,然後重新調用render函數渲染就好了。
那麼重新渲染的時機怎麼確定?
HTML5為我們提供了requestAnimFrame,它會自動在每次頁面重繪前調用傳入的函數。
如果我們一開始這樣渲染:
只需要改成這樣:
object就可以動起來了!
下面我們用一個簡單的例子來梳理一下這個過程。
首先寫一個有Canvas元素的頁面吧。
下面來做Javascript的部分
首先初始化Renderer
初始化場景:
初始化相機:
要唯一確定一個相機的位置與方向,position、up、lookAt三個屬性是缺一不可的。
這里我們創建了一個正交投影相機,這里我將視景體大小與屏幕解析度保持一致只是為了方便,這樣坐標系中的一個單位長度就對應屏幕的一個像素了。
我們將相機放在Z軸上,面向坐標原點,相機的上方向為Y軸方向,注意up的方向和lookAt的方向必然是垂直的(類比自己的頭就知道了)。
下面添加一個立方體到場景中:
注意我們使用了法向材質 MeshNormalMaterial ,這樣立方體每個面的顏色與這個面對著的方向是相關的,更便於觀察/調試。
在這個簡單的demo里我不打算添加光影效果,而法向材質對光也是沒有反應的。 最後來創建一個動畫循環吧
每次重繪都讓這個立方體轉動一點點。 當頁面載入好時,調用前面這些函數就好了。
WebGL中文網 強烈推薦!!
WebGL中文教程網
⑶ threejs需要載入大量場景模型,需要時時清理無用模型出場景同時能夠顯著降低內存消耗,清除場景我
想當然的在這里意淫罷了,模型都已經載入到內存了,你給我說remove出scene就可以了?就算上你這樣的思路是正確的,請問你怎麼處理業務邏輯?何時載入需要的模型?光處理哪些模型載入,哪些模型何時載入就夠你受的了
⑷ three.js 怎樣綁定陀螺儀
three.js 綁定陀螺儀實現例子如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="renderer" content="webkit">
<script>
<div id="CanvasBody">
<input id="onDevice" type="button" value="開啟陀螺儀">
</div>
<!-- 滑鼠控制 (OrbitControls.js) -->
<script>
THREE.OrbitControls=function(object,domElement){return}event.preventDefault();event.stopPropagation();handleMouseWheel(event);scope.dispatchEvent(startEvent);scope.dispatchEvent(endEvent)}function onKeyDown(event){if(scope.enabled===false||scope.enableKeys===false||scope.enablePan===false){return}handleKeyDown(event)}function onTouchStart(event){if(scope.enabled===false){return}switch(event.touches.length){case 1:if(scope.enableRotate===false){return}handleTouchStartRotate(event);state=STATE.TOUCH_ROTATE;break;case 2:if(scope.enableZoom===false){return}handleTouchStartDolly(event);state=STATE.TOUCH_DOLLY;break;case 3:if(scope.enablePan===false)
</script>
<!-- 控制陀螺儀 (DeviceOrientationControls.js) -->
<!-- 代碼 -->
<script>
"use strict";
(function (CanvasBody, _window) {
var Scene = void 0,
Camera = void 0,
Renderer = void 0,
FpsStats = void 0,
AnimateFrame = void 0,
Controls = void 0,
Devices = void 0;
var onDevice = document.getElementById("onDevice");
var isDeviceing = 0;
/* 初始化函數 */
function initScene() {
Scene = new THREE.Scene();
}
// 初始化照相機
function initCamera() {
Camera = new THREE.PerspectiveCamera(60, CanvasBody.clientWidth / CanvasBody.clientHeight, 1, 3000);
Camera.position.set(1, 0, 0);
Camera.lookAt({ x: 200, y: 0, z: 0 });
}
// 初始化渲染器
function initRenderer() {
Renderer = new THREE.WebGLRenderer();
Renderer.setSize(CanvasBody.clientWidth, CanvasBody.clientHeight);
Renderer.setClearColor(0x000000, 1);
CanvasBody.appendChild(Renderer.domElement);
}
// 初始化監視器
function initFpsStats() {
FpsStats = new Stats();
CanvasBody.appendChild(FpsStats.domElement);
FpsStats.domElement.style.cssText = "position: absolute;top: 0;left: 0;";
}
// 初始化控制器
function initControls() {
Controls = new THREE.OrbitControls(Camera);
}
// 初始化陀螺儀
function initDevices() {
Devices = new THREE.DeviceOrientationControls(Camera);
}
/* 窗口改變事件 */
function windowChange() {
initCamera();
Renderer.setSize(CanvasBody.clientWidth, CanvasBody.clientHeight);
initDevices();
initControls();
}
/* 控制陀螺儀 */
function controlDevice(event) {
if (isDeviceing === 0) {
isDeviceing = 1;
onDevice.value = "關閉陀螺儀";
} else {
isDeviceing = 0;
onDevice.value = "開啟陀螺儀";
}
}
/* 動畫 */
function animate(time) {
FpsStats.begin();
Renderer.clear();
isDeviceing === 0 ? Controls.update() : Devices.update();
Renderer.render(Scene, Camera);
FpsStats.end();
AnimateFrame = requestAnimationFrame(animate);
}
/* 初始化 */
function init() {
// 初始化
initScene();
initCamera();
initRenderer();
initFpsStats();
initControls();
initDevices();
// 初始化綁定陀螺儀
Devices.connect();
_window.addEventListener("resize", windowChange, false);
onDevice.addEventListener("click", controlDevice, false);
AnimateFrame = requestAnimationFrame(animate);
}
init();
/* 場景內物體 */
(function () {
var r = Math.sqrt(5000 * 1827 / 4 / Math.PI);
var texture = THREE.ImageUtils.loadTexture("http://cdn.attach.w3cfuns.com/notes/pics/201606/14/141100b7m85b4k8kb3337z.jpg", {}, function () {
var geometry = new THREE.SphereGeometry(r, 100, 100);
var material = new THREE.MeshLambertMaterial({
map: texture,
side: THREE.DoubleSide
});
var mesh = new THREE.Mesh(geometry, material);
Scene.add(mesh);
mesh.position.set(0, 0, 0);
var al = new THREE.AmbientLight(0xffffff);
Scene.add(al);
});
})();
})(document.getElementById("CanvasBody"), window);
</script>
</body>
</html>
⑸ 如何用threejs添加一個背景
如果你是指給場景設置背景,直接load個texture(可以是普通的texture,也可以是天空盒子那樣的cubetexture),然後scene.background=texture
⑹ threejs如何讓材質同時擁有高光和凹凸效果
map為默認材質色,添來加自normalMap法線貼圖產生凹凸視覺, 配合roughness數值產生高光。
材質代碼:
let map_d=new THREE.TextureLoader().load("常規貼圖.jpg");
let map_n=new THREE.TextureLoader().load("法線貼圖.jpg");
let material=new THREE.MeshStandardMaterial({
map:map_d,
normalMap:map_n,
roughness:0.1
});
let geometry = new THREE.CircleBufferGeometry( 5, 32 );
let circle = new THREE.Mesh( geometry, material );
scene.add( circle );
⑺ three.js 給模型添加標注
1. 需要有一個被選擇的mesh,通過raycaster獲取
2. 創建先和一個平面
3. 將線和標注的面放在獲取的mesh上
var mouse =new THREE.Vector2();
var raycaster =new THREE.Raycaster();
mouse.x = (event.clientX / domElement.width) *2 -1;
mouse.y = -(event.clientY / domElement.height) *2 +1;
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects(scene.children, false); //
selectedObject = intersects[0].object; // 被選中的標注對象
//
var startP,endP;// 這里也是通過raycaster獲取到的
var color = parameters.hasOwnProperty("color") ? parameters.color :0x0000ff;
var lineMat =new THREE.LineBasicMaterial({
"color": 0xff0000
});
var lineGeo =new THREE.Geometry();
lineGeo.vertices.push(startPos);
lineGeo.vertices.push(endPos);
var line =new THREE.Line(lineGeo, lineMat);
// 初始化一個sprite,這是一個始終面向相機的平面,
var sprite = new textSprite(這並不是一個構造函數,不想寫那麼多,自行去官網查看)
.......
sprite.scale.set(_spriteScale, _spriteScale, _spriteScale); // 設置的是sprite的大小派脊野
selectedObject.add(line); // 添加
line.worldToLocal(_endPos); // 設置點
sprite.position.(_endPos); // 設置sprite的位置
line.add(sprite); 添加並進行關聯
注: sprite可以用於進行塵喊標注熱點等操作,具體實現較為簡單,同時因為也算是mesh,所以sprite可以設置texture,使用圖片作為背景等,也可以野帶把一個canvas,把需要的文字圖片等都加入進來.
⑻ 用three.js,導入的js模型或者obj模型都是黑色的。究竟是怎麼回事。
轉成js格式裡面之後 這個文件裡面貼圖文件名後綴是.JPG 要把你用的貼圖後綴名也改成.JPG 或者js文件裡面改成.jpg 應該就能對應上了
⑼ threejs透明貼圖如何不影響內部材質
在Three.js中,如果要實現不影響內部材質的透明孫旁擾貼圖,則需要對渲染器的混合模則旦式進行設置。具體操作如下:
1. 設置材質的混合模式。可以通過設置material.blending參數來完成。例如將blending設置為THREE.NormalBlending表示材質使用正常的混合模式。如果該參數設置為THREE.CustomBlending,則需要進一步設置material.blendSrc和material.blendDst參數來指定混合源和混合目啟並標。
2. 通過調整渲染器的渲染順序來避免內部材質的透明被多次覆蓋。可以通過設置material.depthTest和material.depthWrite參數來實現。通常情況下,需要將這兩個參數都設置為true,以確保在深度測試過程中材質的深度值得到正確的比較和保存。
3. 對於透明貼圖本身,需要將其載入為一個帶有alpha通道的紋理貼圖,並將material.opacity屬性設置為小於1的數值,以表明材質是半透明的。
綜上所述,通過設置合適的混合模式、渲染順序和透明度等參數,就可以在Three.js中實現不影響內部材質的透明貼圖了。
⑽ Three.js 實現VR看房
准備工作:
1、three.js https://threejs.org/build/three.js
2、搭建項目環境 我使用的live-server
3、720°全景圖
目錄結構
mian.js
; (function () {
// 在THREEjs中,渲染一個3d世界的必要因素是場景(scene)、相機(camera)、渲染器(renderer)。渲染出一個3d世界後,可以往裡面增加各種各樣的物體、光源等,形成一個3d世界。
// 創建場景
const scene = new THREE.Scene()
// 創建透視攝像銷卜機
// new THREE.PrespectiveCamera('視角', '指投影窗口長寬比例', '表示重距離攝像機多遠的位置開始渲染', '表示距離攝像機多遠的位置截止渲染');
// 正交攝像機是一個矩形可視區域,物體只有在這個區域內才是可見的物體無論距離攝像機是遠或事近,物體都會被渲染成一個大小。一般應用場景是2.5d游戲如跳一跳、機械模型
// 透視攝像機是最常用的攝像機類型,模擬人眼的視覺,近大遠小(透視)。Fov表示的是視角,Fov越大,表示眼睛睜猜斗鉛得越大,離得越遠,看得更多。如果是需要模擬現實,基本都是用這個相機
const camera = new THREE.PerspectiveCamera(90, window.innerWidth / window.innerHeight, 1, 1000)
// 創建ThreeJs渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true })
// 設置渲染器場景的大小
renderer.setSize(window.innerWidth, window.innerHeight)
// 渲染器添加到頁面
document.body.appendChild(renderer.domElement)
// 上面的確是把3d世界畫出來了,只是沒有什麼東西。在three.js中,我們需要增加光源和mesh
// mesh即是網格。在計算機里,3D世界是由點組成的,無數的面拼接成各種形狀的物體。這種模型叫做網格模型。一條線是兩個點組成,一個面是3個點組成,一個物體由多個3點組成的面組成
// 而網格(mesh)又是由幾何體(geometry)和材質(material)構成的
// 我們所能想像到的幾何體,框架都自帶了,我們只需要調用對應的幾何體構造函數即可創建。幾何體的創建方法都是new,如BoxBuffer:const geometry = new THREE.BoxBufferGeometry( 1, 1, 1 );
// 創建的時候,一般定義了渲染一個 3D 物體所需要的基本數據:Face 面、Vertex 頂點等信穗好息。THREE.xxxGeometry指的是框架自帶的幾何體,不同幾何體所需要的參數有所不同,大概是width、height、radius、depth、segment、detail、angle等屬性
// 更多geometry相關api
// BufferGeometry和Geometry有什麼不同?就實現的效果來說它們都是一樣,但是BufferGeometry的多了一些頂點屬性,且性能較好。對於開發者來說,Geometry對象屬性少體驗更好。THREE解析幾何體對象的時候,如果是Geometry,則會把對象轉換成ufferGeometry對象,再進行下一步渲染
// 創建幾何模型
// THREE.BoxGeometry('x軸長', 'y軸長', 'z軸長')
const geometry = new THREE.SphereGeometry(50, 256, 256);
// 創建貼圖 720°圖片,需要硬體支持 這里的圖是借用網路上面的
const texture = new THREE.TextureLoader().load('https://qhyxpicoss.kujiale.com/r/2019/07/01/_3000x4000.jpg?x-oss-process=image/resize,m_fill,w_1600,h_920/format,webp')
//創建材質
const material = new THREE.MeshBasicMaterial({ map: texture })
// 渲染球體的雙面
material.side = THREE.DoubleSide;
// 創建網格對象
const mesh = new THREE.Mesh(geometry, material)
// 網格對象填加到場景
scene.add(mesh)
// 攝像機放球體中心
camera.position.set(-0.3, 0, 0)
// 控制器(如果報錯去github自己拷貝一個OrbitControls.js https://github.com/mrdoob/three.js/blob/dev/examples/js/controls/OrbitControls.js )
const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.addEventListener("change", () => {
renderer.render(scene, camera);
});
controls.minDistance = 1;
controls.maxDistance = 2000;
controls.enablePan = false;
// 調整max
controls.minDistance = 1 // controls.maxDistance = 200;
controls.maxDistance = 2
function animate () {
requestAnimationFrame(animate)
renderer.render(scene, camera)
}
animate()
window.onresize = function () {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
}
})()