- 提 供
- 3D显示功能
- 编 写
- JavaScript
- 中文名
- three.js
- 属 性
- 3D 引擎
-
Three.js 中文文档和在线演示实例
2016-06-16 19:40:24Three.js是当下最流行的网页3D渲染JS引擎,其主要是对WebGL编程以面向对象方式进行的封装。 踏得网专注于HTML5技术生态链的资源开发,鉴于网络上Three.js方面的资料比较散乱,且良莠不齐, 因此我们把Three.js的官方...Three.js是当下最流行的网页3D渲染JS引擎,其主要是对WebGL编程以面向对象方式进行的封装。
但由于Three.js英文文档还在开发中(本身就比较简陋且有不少拷贝错误),而网络上Three.js方面的资料比较散乱且良莠不齐,部分中文文档翻译低级错误频出,
因此我们把Three.js的官方文档、示例和踏得网已有资源整合起来,提供在线中文文档(http://techbrood.com/threejs/docs)。
以及方便的调试学习环境。
(2020.10月更新)我们近期推出了基于Three.js的轻量级在线3D展示开发工具:Stone,通过该工具可以实现无编码、免下载构建3D沉浸式展示场景。欢迎试用和洽谈合作。
在踏得网2016HTML5动画中,有很多也是用Three.js所实现,供参考学习。
-
【Three.js】十一、three.js使用Tween.js
2019-09-29 14:06:27【Three.js】十一、three.js使用Tween.js tween.js是一个轻量级js库,可用来实现一些动画效果。github地址:https://github.com/tweenjs/tween.js/. cnpm安装方式:cnpm install @tweenjs/tween.js -S 使用方法...【Three.js】十一、three.js使用Tween.js
tween.js是一个轻量级js库,可用来实现一些动画效果。github地址:https://github.com/tweenjs/tween.js/.
cnpm安装方式:cnpm install @tweenjs/tween.js -S
使用方法:
1.创建补间let size1 = {width: 10, height: 10, depth: 10}; let tween = new TWEEN.Tween(size1);
2.指定动画的最终状态
tween.to({width: 5, height: 5, depth: 5}, 1000); // 指定动画时间1s
3.指定onUpdate
tween.onUpdate(() => { // 给相关变化属性赋值 });
4.开始动画
tween.start();
5.调用Tween.update()
function animate() { requestAnimationFrame(animate); // [...] TWEEN.update(); // [...] }
*官方文档:https://github.com/tweenjs/tween.js/blob/master/docs/user_guide_zh-CN.md
示例:
import '../../stylus/index.styl' import TWEEN from '@tweenjs/tween.js' import * as THREE from 'three' import {initStats,initThree,initTrackballControls} from "../../util/util" function init() { let stats = initStats(); let {camera, renderer, scene} = initThree(); let trackballControls = initTrackballControls(camera, renderer); let light = new THREE.DirectionalLight(0xffffff); light.position.set(-20, 40, 30); scene.add(light); let ambientLight = new THREE.AmbientLight(0xcccccc); scene.add(ambientLight); let boxGeometry = new THREE.BoxBufferGeometry(10,10,10); let boxMaterial = new THREE.MeshStandardMaterial({ color: 0xaa12233 }); let box = new THREE.Mesh(boxGeometry, boxMaterial); box.castShadow = true; scene.add(box); let size1 = {width: 10, height: 10, depth: 10}; let size2 = {width: 5, height: 5, depth: 5}; // 缩小 let tween1 = new TWEEN.Tween(size1).to({width: 5, height: 5, depth: 5}, 1000) .easing(TWEEN.Easing.Quadratic.Out) .onUpdate(() => { if (size1.width <= 5) { tween2.start(); } box.geometry = new THREE.BoxBufferGeometry(size1.width, size1.height, size1.depth); }); // 放大 let tween2 = new TWEEN.Tween(size2).to({width: 10, height: 10, depth: 10}, 1000) .easing(TWEEN.Easing.Quadratic.In) .onUpdate(() => { box.geometry = new THREE.BoxBufferGeometry(size2.width, size2.height, size2.depth); if (size2.width >= 10) { tween1.start(); } }); tween1.start(); let render = () => { stats.update(); trackballControls.update(); renderer.render(scene, camera); TWEEN.update(); requestAnimationFrame(render); } render(); } init();
完整示例参考(src/pages/three_animation_demo):https://github.com/MAXLZ1/threejs_demo -
【Three.js】一、第一个Three.js项目
2019-08-29 08:45:42【Three.js】一、第一个Three.js项目一、Three.js下载 一、Three.js下载 Three.js github:https://github.com/mrdoob/three.js【Three.js】一、第一个Three.js项目
一、Three.js下载
Three.js github:https://github.com/mrdoob/three.js。
一个WebGL程序包含三大基本对象:场景(sence)、摄像机(camera)、渲染器(renderer)。场景是一个容器,用来保存要渲染的物体与光源。射摄像机用来调整物体视角。渲染器的作用是基于摄像机定义的角度去渲染计算物体的位置。
二、一个Three简单例子
import './index.styl'; import * as THREE from 'three'; import Stats from 'stats-js'; // 检测动画运行时的帧数 import * as dat from 'dat.gui'; // 用于创建右上角控制器 window.onload = init(); var scence; var camera; var renderer; function init() { var stats = initStats(); var controls = new function () { this.rotationSpeed = 0.02; this.bouncingSpeed = 0.03; } var gui = new dat.GUI(); gui.add(controls, 'rotationSpeed', 0, 0.5); gui.add(controls, 'bouncingSpeed', 0, 0.5); // 创建场景 scence = new THREE.Scene(); // 创建相机 camera = new THREE.PerspectiveCamera( 45, window.innerWidth/window.innerHeight, 0.1, 1000); // 创建渲染器 renderer = new THREE.WebGLRenderer(); renderer.setClearColor(0xEEEEEE, 1.0); renderer.setSize(window.innerWidth, window.innerHeight); renderer.shadowMapEnabled = true; // 轴 var axes = new THREE.AxisHelper(20); scence.add(axes); var planeGeometry = new THREE.PlaneGeometry(60, 20, 1, 1); var planeMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff }); var plane = new THREE.Mesh(planeGeometry, planeMaterial); plane.rotation.x = -0.5*Math.PI; plane.position.x = 15; plane.position.y = 0; plane.position.z = 0; plane.receiveShadow = true; var cubeGeometry = new THREE.BoxGeometry(4,4,4); var cubeMaterial = new THREE.MeshLambertMaterial({ color: 0xff0000 }); var cube = new THREE.Mesh(cubeGeometry, cubeMaterial); cube.position.x = -4; cube.position.y = 5; cube.position.z = 0; cube.castShadow = true; var sphereGeometry = new THREE.SphereGeometry(4, 20, 20); var sphereMaterial = new THREE.MeshLambertMaterial({ color: 0x7777ff }); var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); sphere.position.x = 20; sphere.position.y = 4; sphere.position.z = 2; sphere.castShadow = true; var spotLight = new THREE.SpotLight(0xffffff); spotLight.position.set(-40, 40, -15); spotLight.castShadow = true; spotLight.shadow.mapSize = new THREE.Vector2(1024,1024); spotLight.shadow.camera.far = 130; spotLight.shadow.camera.near = 40; scence.add(plane); scence.add(cube); scence.add(sphere); scence.add(spotLight); var ambienLight = new THREE.AmbientLight(0x353535); scence.add(ambienLight); camera.position.x = -30; camera.position.y = 40; camera.position.z = 30; camera.lookAt(scence.position); document.getElementById('WebGL-output').appendChild(renderer.domElement); renderer.render(scence, camera); } function initStats(){ var stats = new Stats(); stats.showPanel(0); document.getElementById('Stats-output').appendChild(stats.domElement); return stats; }
上面代码创建了一个平面(plane)、一个立方体(cube)、一个球体(sphere),并建立了一个坐标轴(axes),spotLight是创建的光源,用来产生阴影,ambienLight用来定义环境光。关于坐标轴:红色是x轴,绿色是y轴、蓝色是z轴。
为了让立方体与小球产生动画效果,添加如下代码:var step = 0; function renderScence() { stats.update(); // 立方体旋转 cube.rotation.x += controls.rotationSpeed; cube.rotation.y += controls.rotationSpeed; cube.rotation.z += controls.rotationSpeed; // 小球跳动 step += controls.bouncingSpeed; sphere.position.x = 20 + (10 * Math.cos(step)); sphere.position.y = 2 + (10* Math.abs(Math.sin(step))); requestAnimationFrame(renderScence); renderer.render(scence, camera); }
将
renderer.render(scence, camera)
改为renderScence()
,小球会做一个循环的抛物运动而立方体则自动旋转:
完整示例:https://github.com/MAXLZ1/threejs_demo -
【Three.js】九、three.js模型加载器
2019-09-17 21:09:24【Three.js】九、three.js模型加载器【Three.js】九、three.js模型加载器
一、ObjectLoader
用于加载JSON资源的加载器。
1.1 ObjectLoader常用方法
1.1.1 .load ( url : String, onLoad : Function, onProgress : Function, onError : Function ) : null
从URL中进行加载,并将被解析的响应内容传递给onLoad。
参数 说明 url 文件的URL或者路径 onLoad 加载完成时将调用。回调参数为将要加载的object. onProgress 将在加载过程中进行调用。参数为XMLHttpRequest实例,实例包含total和loaded字节。 onError 在加载错误时被调用。 1.1.2 .parse ( json : Object, onLoad : Function ) : Object3D
解析一个JSON结构,并返回一个threejs对象. 内部使用.load进行加载, 但也可以直接用于解析先前加载的JSON结构。
参数 说明 json 必选参数,需要被解析的JSON源。 onLoad 当解析完成时被调用,其中参数被解析为object. 示例:
import '../../stylus/index.styl' import * as THREE from 'three' import * as dat from 'dat.gui' import {initTrackballControls, initThree, initStats} from "../../util/util" async function init() { let stats = initStats(); let {camera, scene, renderer} = initThree(); let gui = new dat.GUI(); let storage = {}; let objLoader = new THREE.ObjectLoader(); function load() { return new Promise((resolve, reject) => { objLoader.load('../../static/json/trousKnot.json', (obj) => { obj.position.set(20, 0, 0); scene.add(obj); resolve(obj); }, null, (err) => { reject(err); }); }) } let torusKnot = await load(); let controls = { save: function () { let json = torusKnot.toJSON(); storage.torusKnot = json; }, load: function () { if (storage.torusKnot) { let obj = objLoader.parse(storage.torusKnot); obj.position.set(-20, 0, 0); scene.add(obj); } } }; gui.add(controls, 'save'); gui.add(controls, 'load'); let trackballControls = initTrackballControls(camera, renderer); function render() { stats.update(); trackballControls.update(); requestAnimationFrame(render); renderer.render(scene, camera); } render(); } init();
所使用的json数据:
{ "metadata": { "version": 4.5, "type": "Object", "generator": "Object3D.toJSON" }, "geometries": [ { "uuid": "4562EC9C-1F70-4725-B796-B5A5C8FB0B64", "type": "TorusKnotGeometry", "radius": 10, "tube": 2, "tubularSegments": 64, "radialSegments": 40 } ], "materials": [ { "uuid": "794AD652-5479-42C5-9C05-4B1990722994", "type": "MeshNormalMaterial", "depthFunc": 3, "depthTest": true, "depthWrite": true, "stencilWrite": false, "stencilFunc": 519, "stencilRef": 0, "stencilMask": 255, "stencilFail": 7680, "stencilZFail": 7680, "stencilZPass": 7680 } ], "object": { "uuid": "21C4B19D-8989-40CD-8604-AC333BA3F960", "type": "Mesh", "layers": 1, "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,20,0,0,1], "geometry": "4562EC9C-1F70-4725-B796-B5A5C8FB0B64", "material": "794AD652-5479-42C5-9C05-4B1990722994" } }
上述例子展示一个从外部加载的圆环扭结几何体,并可通过右侧控制栏复制一个几何体(依次点击save、load)。
完整示例(src/pages/three_ObjectLoader_demo):https://github.com/MAXLZ1/threejs_demo
二、LegacyJSONLoader
JSONLoader在r99及之后版本被移除,取而代之的是LegacyJSONLoader,位于examples/js/loaders/deprecated/LegacyJSONLoader.js下
加载json资源。
2.1 LegacyJSONLoader常用方法
2.1.1 .load ( url : String, onLoad : Function, onProgress : Function, onError : Function ) : null
同ObjectLoader.load。
示例:
import '../../stylus/index.styl' import * as THREE from 'three' import * as dat from 'dat.gui' import {initTrackballControls, initThree, initStats} from "../../util/util" import {LegacyJSONLoader} from "../../libs/LegacyJSONLoader" function init() { let stats = initStats(); let {camera, scene, renderer} = initThree(); let spotLight = new THREE.SpotLight(0xffffff); spotLight.position.set(0, 200, 300); spotLight.shadow.camera.far = 1400; spotLight.shadow.mapSize.set(2048, 2048); spotLight.castShadow = true; scene.add(spotLight); let ambientLight = new THREE.AmbientLight(0xffffff, 0.2); scene.add(ambientLight); let planeGeometry = new THREE.PlaneBufferGeometry(1000, 1000, 1,1); let planeMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff }); let plane = new THREE.Mesh(planeGeometry, planeMaterial); plane.rotation.x = -0.5 * Math.PI; plane.receiveShadow = true; scene.add(plane); let jsonLoader = new LegacyJSONLoader(); jsonLoader.load('../../static/modules/house/house.json', (geo, mater) => { let house = new THREE.Mesh(geo, mater); house.castShadow = true; house.receiveShadow = true; house.position.set(0,2,15); scene.add(house); spotLight.target = house; }); let trackballControls = initTrackballControls(camera, renderer); function render() { stats.update(); trackballControls.update(); requestAnimationFrame(render); renderer.render(scene, camera); } render(); } init();
完整示例(src/pages/three_LegacyJSON_demo):https://github.com/MAXLZ1/threejs_demo三、OBJLoader
位于examples/js/loaders
加载.obj资源文件。与MTLLoader一起使用可为对象添加材质。
使用npm或cnpm安装
cnpm install three-obj-loader -S
npm install three-obj-loader -S3.1 OBJLoader常用方法
3.1.1 .load ( url : String, onLoad : Function, onProgress : Function, onError : Function ) : null
同ObjectLoader.load。
3.1.2 .setMaterials ( materials : MTLLoader.MaterialCreator ) : OBJLoader
设置由MTLLoader. materialcreator或MTLLoader. materialcreator的任何其他的材料。
3.1.3 .setPath ( path : String ) : OBJLoader
设置加载文件的基本路径或URL。
四、MTLLoader
位于examples/js/loaders下
加载.mtl资源文件。该文件保存了.obj中对象所使用的材质信息。
使用npm或cnpm安装
cnpm install three-mtl-loader -S
npm install three-mtl-loader -S4.1 MTLLoader常用方法
4.1.1 .load ( url : String, onLoad : Function, onProgress : Function, onError : Function ) : null
同ObjectLoader.load。
4.1.2 .setPath ( path : String ) : MTLLoader
同OBJLoader。
4.1.3 .setMaterialOptions ( options : Object ) : MTLLoader
设置材料属性。
- side: 设置材料渲染哪一面,同Material的side。
- wrap
- normalizeRGB
- ignoreZeroRGBs
- invertTrProperty
示例:
import '../../stylus/index.styl' import * as THREE from 'three' import {initTrackballControls, initThree, initStats} from "../../util/util"; import OBJLoader from 'three-obj-loader' import MTLLoader from 'three-mtl-loader' OBJLoader(THREE); async function init () { let stats = initStats(); let {camera, renderer, scene} = initThree(); let trackballControls = initTrackballControls(camera, renderer); camera.position.set(-20, 40, 50); let spotLight = new THREE.SpotLight(0xc2c2c2); spotLight.position.set(0, 100, 100); spotLight.castShadow = true; spotLight.shadow.mapSize.set(8000, 8000); scene.add(spotLight); let ambientLight = new THREE.AmbientLight(0xEEEEEE, .4); scene.add(ambientLight); let planeGeometry = new THREE.PlaneBufferGeometry(60, 40, 1,1); let planeMaterial = new THREE.MeshLambertMaterial({ color:0xffffff }); let plane = new THREE.Mesh(planeGeometry, planeMaterial); plane.rotation.x = - 0.5 * Math.PI; plane.position.set(0,0,0); plane.receiveShadow = true; scene.add(plane); let objLoader = new THREE.OBJLoader(); let mtlLoader = new MTLLoader(); objLoader.setPath('../../static/modules/store/'); mtlLoader.setPath('../../static/modules/store/'); mtlLoader.setMaterialOptions({ side: THREE.FrontSide, wrap: THREE.RepeatWrapping, normalizeRGB: false, ignoreZeroRGBs: false, invertTrProperty: true }); function loadObj (material) { return new Promise((resolve, reject) => { objLoader.setMaterials(material); objLoader.load('storeHouse.obj', (object) => { resolve(object); }, null, (error) => { reject(error); }); }); } function loadMTL () { return new Promise((resolve, reject) => { mtlLoader.load('storeHouse.mtl', (object) => { object.preload(); resolve(object); }, null, (error) => { reject(error); }); }); } let material = await loadMTL(); let obj = await loadObj(material); obj.rotation.y = -0.5 * Math.PI; // 设置阴影 for (let i in obj.children) { obj.children[i].castShadow = true; obj.children[i].receiveShadow = true; } scene.add(obj); function render(){ stats.update(); trackballControls.update(); requestAnimationFrame(render); renderer.render(scene, camera); } render(); } init();
注意为obj添加阴影的方式,直接设置obj.castShadow=true无效,需要为每个obj.children设置castShadow。
完整示例(src/pages/three_ObjLoader_demo):https://github.com/MAXLZ1/threejs_demo五、ColladaLoader
加载.dar资源。
5.1 ColladaLoader常用方法
5.1.1 .load ( url : String, onLoad : Function, onProgress : Function, onError : Function ) : null
同ObjectLoader.load。
5.1.2 .setPath ( path : String ) : MTLLoader
同OBJLoader。
使用示例:
import '../../stylus/index.styl' import * as THREE from 'three' import {initThree, initStats} from "../../util/util"; import {ColladaLoader} from "../../libs/loaders/ColladaLoader"; import {Vector3} from "../../libs/three.module"; async function init () { let stats = initStats(); let {camera, scene, renderer} = initThree(); camera.position.set(8, 10, 8); camera.lookAt(new Vector3(0,3,0)); let ambientLight = new THREE.AmbientLight(0xcccccc, 0.4); scene.add(ambientLight); let directionLight = new THREE.DirectionalLight(0xffffff, 0.8); directionLight.position.set(1,1,0).normalize(); scene.add(directionLight); let colladaLoader = new ColladaLoader(); let load = () => new Promise((resolve, reject) => { colladaLoader.setPath('../../static/modules/elf/'); colladaLoader.load('elf.dae', (object) => { resolve(object); }, null, (err) => { reject(err); }); }); let obj = (await load()).scene; scene.add(obj); function render(){ stats.update(); obj.rotation.z += 0.01; requestAnimationFrame(render); renderer.render(scene, camera); } render(); } init();
完整示例(src/pages/three_ColladaLoader_demo):https://github.com/MAXLZ1/threejs_demo下面几个加载器方法参考ColladaLoader。
六、BabylonLoader
加载.babylon资源,该加载器会加载一个完整场景,包括光源。
示例:
import '../../stylus/index.styl' import * as THREE from 'three' import {initTrackballControls, initThree, initStats} from "../../util/util"; import {BabylonLoader} from "../../libs/loaders/BabylonLoader"; import {MeshPhongMaterial} from "../../libs/three.module"; async function init () { let stats = initStats(); let {camera, scene, renderer} = initThree(); let trackballControls = initTrackballControls(camera, renderer); camera.position.set(0, 10, 100); let ambientLight = new THREE.AmbientLight(0xcccccc, 0.3); scene.add(ambientLight); let babylonLoader = new BabylonLoader(); babylonLoader.setPath('../../static/modules/babylon/'); let load = () => new Promise((resolve, reject) => { babylonLoader.load('skull.babylon', (object) => { resolve(object); }, null, (err) => { reject(err); }); }) ; let obj = await load(); obj.traverse((item) => { if (item.isMesh) { item.material = new MeshPhongMaterial({ color: 0xffffff * Math.random() }) } }); // 重新设置对象位置 obj.children.forEach( item => { if (item.type === 'Mesh') { item.position.set(0,0,0); } }); scene.add(obj); function render() { stats.update(); trackballControls.update(); obj.rotation.y += 0.005; requestAnimationFrame(render); renderer.render(scene, camera); } render(); } init();
完整示例(src/pages/three_BabylonLoader_demo):https://github.com/MAXLZ1/threejs_demo七、GLTFLoader
加载.gltf资源。
使用npm或cnpm安装
cnpm install three-gltf-loader -S
npm install three-gltf-loader -S示例:
import '../../stylus/index.styl' import * as THREE from 'three' import GLTFLoader from 'three-gltf-loader' import {initTrackballControls, initThree, initStats} from "../../util/util"; async function init () { let stats = initStats(); let {camera, renderer, scene} = initThree(); let trackballControls = initTrackballControls(camera, renderer); renderer.setClearColor(0xff0000, 0.2) let ambientLight = new THREE.AmbientLight(0xcccccc); scene.add(ambientLight); let directionLight = new THREE.DirectionalLight(0xffffff); directionLight.position.set(0,20,40); scene.add(directionLight); let gltfLoader = new GLTFLoader(); gltfLoader.setPath('../../static/modules/glTF/'); let load = () => new Promise((resolve, reject) => { gltfLoader.load('DamagedHelmet.gltf', (object) => { resolve(object); }, null, (error) => { reject(error); }); }); let obj = (await load()).scene; obj.scale.set(12,12,12); scene.add(obj); function render(){ stats.update(); trackballControls.update(); obj.rotation.y += 0.005; requestAnimationFrame(render); renderer.render(scene, camera); } render(); } init();
完整示例(src/pages/three_GLTFLoader):https://github.com/MAXLZ1/threejs_demo八、MMDLoader
加载.pmd、.pmx、.vmd、.vpd资源。
示例:
import '../../stylus/index.styl' import * as THREE from 'three' import {initTrackballControls, initThree, initStats} from "../../util/util"; const AmmoObj = require('../../libs/ammo'); import {MMDLoader} from "../../libs/loaders/MMDLoader"; import {MMDAnimationHelper} from "../../libs/animation/MMDAnimationHelper"; import {OutlineEffect} from '../../libs/OutlineEffect'; AmmoObj().then( function ( AmmoLib ) { Ammo = AmmoLib; init(); } ); async function init() { let stats = initStats(); let {camera, scene, renderer} = initThree({ color: 0xffffff }); let trackballControls = initTrackballControls(camera, renderer); let clock = new THREE.Clock(); let ambientLight = new THREE.AmbientLight(0xcccccc, 0.2); scene.add(ambientLight); let directionLight = new THREE.DirectionalLight(0xffffff, 0.6); directionLight.position.set(20, 40, 30); directionLight.castShadow = true; directionLight.shadow.mapSize.set(2048, 2048); directionLight.shadow.camera.near = 10; directionLight.shadow.camera.far = 70; directionLight.shadow.camera.left = -10; directionLight.shadow.camera.right = 10; directionLight.shadow.camera.top = 30; directionLight.shadow.camera.bottom = -10; scene.add(directionLight); // let helperLight = new THREE.DirectionalLightHelper(directionLight); // scene.add(helperLight); // // let lightShadow = new THREE.CameraHelper(directionLight.shadow.camera); // scene.add(lightShadow); let planeGeometry = new THREE.PlaneBufferGeometry(60,60, 1, 1); let planeMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff }); let plane = new THREE.Mesh(planeGeometry, planeMaterial); plane.rotation.x = -0.5 * Math.PI; plane.receiveShadow = true; scene.add(plane); let mmdLoader = new MMDLoader(); let load = () => new Promise((resolve, reject) => { mmdLoader.loadWithAnimation('../../static/modules/mmd/miku/miku_v2.pmd', ['../../static/modules/mmd/vmds/wavefile_v2.vmd'], (object) => { resolve(object); }, null, (error) => { reject(error); }); }); let obj = await load(); let {mesh, animation} = obj; directionLight.target = mesh; mesh.castShadow = true; scene.add(mesh); let helper = new MMDAnimationHelper(); helper.add( mesh, { animation, physics: true }); // let ikHelper = helper.objects.get( mesh ).ikSolver.createHelper(); // ikHelper.visible = false; // scene.add( ikHelper ); // // let physicsHelper = helper.objects.get(mesh).physics.createHelper(); // physicsHelper.visible = false; // scene.add( physicsHelper ); function render() { stats.update(); trackballControls.update(); helper.update(clock.getDelta()); requestAnimationFrame(render); renderer.render(scene, camera); } render(); }
完整示例(src/pages/three_MMDLoader_demo):https://github.com/MAXLZ1/threejs_demo九、PCDLoader
加载.pcd资源。
import '../../stylus/index.styl' import * as THREE from 'three' import * as gui from 'dat.gui' import {initTrackballControls, initThree, initStats} from '../../util/util' import {PCDLoader} from '../../libs/loaders/PCDLoader'; async function init() { let stats = initStats(); let {camera, scene, renderer} = initThree(); let trackballControls = initTrackballControls(camera, renderer); let loader = new PCDLoader(); camera.position.set(0.2, 0.5, -0.5); camera.up.y = -1; let load = () => new Promise((resolve, reject) => { loader.load('../../static/modules/pcd/Zaghetto.pcd', (points) => { if (points ){ resolve(points); } else { reject(new Error('文件加载失败')); } }); }); let points = await load(); points.material.color.set(0xfff000); scene.add(points); let center = points.geometry.boundingSphere.center; trackballControls.target.set( center.x, center.y, center.z ); trackballControls.update(); let render = () => { stats.update(); trackballControls.update(); requestAnimationFrame(render); renderer.render(scene,camera); }; render(); } init();
完整示例(src/pages/three_PCDLoader_demo):https://github.com/MAXLZ1/threejs_demo十、PDBLoader
加载.pdb资源。
import '../../stylus/index.styl' import * as THREE from 'three' import * as dat from 'dat.gui' import {initThree, initStats, initTrackballControls} from '../../util/util' import {PDBLoader} from '../../libs/loaders/PDBLoader' import {CSS2DObject, CSS2DRenderer} from '../../libs/CSS2DRenderer' const path = '../../static/modules/molecules/'; const MODULES = [ 'Al2O3.pdb', 'aspirin.pdb', 'buckyball.pdb', 'caf2.pdb', 'caffeine.pdb', 'cholesterol.pdb', 'cocaine.pdb', 'cu.pdb', 'cubane.pdb', 'diamond.pdb', 'ethanol.pdb', 'glucose.pdb', 'graphite.pdb', 'lsd.pdb', 'lycopene.pdb', 'nacl.pdb', 'nicotine.pdb', 'ybco.pdb' ]; async function init () { let stats = initStats(); let {camera, renderer, scene} = initThree(); camera.position.z = 1000; let trackballControls = initTrackballControls(camera, renderer); let light = new THREE.DirectionalLight( 0xffffff, 0.8 ); light.position.set( 1, 1, 1 ); scene.add( light ); let light2 = new THREE.DirectionalLight( 0xffffff, 0.5 ); light2.position.set( - 1, - 1, -1 ); scene.add( light2 ); let loader = new PDBLoader(); let offset = new THREE.Vector3(); let root = new THREE.Group(); let labelRenderer = new CSS2DRenderer(); labelRenderer.setSize( window.innerWidth, window.innerHeight ); labelRenderer.domElement.style.position = 'absolute'; labelRenderer.domElement.style.top = '0'; labelRenderer.domElement.style.pointerEvents = 'none'; document.body.appendChild( labelRenderer.domElement ); scene.add(root); let load = (url) => new Promise((resolve, reject) => { loader.load(url, (pdb) => { if (pdb) { let {geometryAtoms, geometryBonds, json} = pdb; let boxGeometry = new THREE.BoxBufferGeometry(1,1,1); let sphereGeometry = new THREE.IcosahedronBufferGeometry(1, 3); geometryAtoms.computeBoundingBox(); geometryAtoms.boundingBox.getCenter(offset).negate(); geometryAtoms.translate(offset.x, offset.y, offset.z); geometryBonds.translate(offset.x, offset.y, offset.z); let positions = geometryAtoms.getAttribute( 'position' ); let colors = geometryAtoms.getAttribute( 'color' ); let position = new THREE.Vector3(); let color = new THREE.Color(); // 创建原子 for (let i = 0; i < positions.count; i++) { position.set(positions.getX(i), positions.getY(i), positions.getZ(i)); color.setRGB(colors.getX(i), colors.getY(i), colors.getZ(i)); let material = new THREE.MeshPhongMaterial({color}); let obj = new THREE.Mesh(sphereGeometry, material); obj.position.copy(position); obj.position.multiplyScalar( 75 ); obj.scale.multiplyScalar( 25 ); root.add(obj); let atom = json.atoms[ i ]; let text = document.createElement( 'div' ); text.className = 'label'; text.style.color = 'rgb(' + atom[ 3 ][ 0 ] + ',' + atom[ 3 ][ 1 ] + ',' + atom[ 3 ][ 2 ] + ')'; text.textContent = atom[ 4 ]; let label = new CSS2DObject( text ); label.position.copy( obj.position ); root.add( label ); } positions = geometryBonds.getAttribute( 'position' ); let start = new THREE.Vector3(); let end = new THREE.Vector3(); // 创建原子间的键 for (let i = 0; i < positions.count; i+=2) { start.set(positions.getX(i), positions.getY(i), positions.getZ(i)); end.set(positions.getX(i + 1), positions.getY(i + 1), positions.getZ(i + 1)); start.multiplyScalar( 75 ); end.multiplyScalar( 75 ); let obj = new THREE.Mesh( boxGeometry, new THREE.MeshPhongMaterial( 0xffffff ) ); obj.position.copy( start ); obj.position.lerp( end, 0.5 ); obj.scale.set( 5, 5, start.distanceTo( end ) ); obj.lookAt( end ); root.add( obj ); } resolve(pdb); } else { reject(new Error(`${url}读取失败!`)); } }); }); await load(path+'caffeine.pdb'); let gui = new dat.GUI(); let controls = { modules: 'caffeine.pdb' }; gui.add(controls, 'modules', MODULES).onChange(async item => { while (root.children.length > 0) { let object = root.children[ 0 ]; object.parent.remove( object ); } await load(path + item); }); let render = () => { stats.update(); trackballControls.update(); requestAnimationFrame(render); renderer.render(scene, camera); labelRenderer.render(scene, camera); } render(); } init();
完整示例(src/pages/three_PDBLoader_demo):https://github.com/MAXLZ1/threejs_demo十一、SVGLoader
加载svg
import * as THREE from 'three' import {initTrackballControls, initThree, initStats} from "../../util/util"; import {SVGLoader} from '../../libs/loaders/SVGLoader' async function init () { let stats = initStats(); let {camera, scene, renderer} = initThree({ color: 0xffffff }); camera.position.set(0,0, 500); let trackballControls = initTrackballControls(camera, renderer); let loader = new SVGLoader(); let load = () => new Promise((resolve, reject) => { loader.load('../../static/modules/svg/tiger.svg', (data) => { let {paths} = data; let group = new THREE.Group(); group.scale.multiplyScalar( 0.25 ); group.position.x = - 70; group.position.y = 70; group.scale.y *= - 1; paths.forEach((item, index) => { let path = item; let fillColor = path.userData.style.fill; if (fillColor && fillColor !== 'none') { let material = new THREE.MeshBasicMaterial( { color: new THREE.Color().setStyle( fillColor ), opacity: path.userData.style.fillOpacity, transparent: path.userData.style.fillOpacity < 1, side: THREE.DoubleSide, depthWrite: false, wireframe: false } ); let shapes = path.toShapes( true ); for ( let j = 0; j < shapes.length; j ++ ) { let shape = shapes[ j ]; let geometry = new THREE.ShapeBufferGeometry( shape ); let mesh = new THREE.Mesh( geometry, material ); group.add( mesh ); } } let strokeColor = path.userData.style.stroke; if (strokeColor && strokeColor !== 'none' ) { let material = new THREE.MeshBasicMaterial( { color: new THREE.Color().setStyle( strokeColor ), opacity: path.userData.style.strokeOpacity, transparent: path.userData.style.strokeOpacity < 1, side: THREE.DoubleSide, depthWrite: false, wireframe: false } ); for ( let j = 0, jl = path.subPaths.length; j < jl; j ++ ) { let subPath = path.subPaths[ j ]; let geometry = SVGLoader.pointsToStroke( subPath.getPoints(), path.userData.style ); if ( geometry ) { let mesh = new THREE.Mesh( geometry, material ); group.add( mesh ); } } } }); scene.add(group); resolve(data); }); }); await load(); let render = () => { stats.update(); trackballControls.update(); requestAnimationFrame(render); renderer.render(scene, camera); }; render(); } init();
完整示例(src/pages/three_SVGLoader_demo):https://github.com/MAXLZ1/threejs_demo十二、TGALoader
加载.tga材质。
import '../../stylus/index.styl' import * as THREE from 'three' import {initTrackballControls, initThree, initStats} from "../../util/util" import {TGALoader} from "../../libs/loaders/TGALoader" function init () { let stats = initStats(); let {camera, renderer, scene} = initThree(); let trackballControls = initTrackballControls(camera, renderer); let light = new THREE.SpotLight(0xffffff); light.position.set(-50, 80, 70); scene.add(light); let ambientLight = new THREE.AmbientLight(0xdddddd, 0.5); scene.add(ambientLight); let loader = new TGALoader(); let texture = loader.load('../../static/modules/tga/crate_color8.tga', ); let boxGeometry = new THREE.BoxBufferGeometry(20,20, 20); let material = new THREE.MeshPhongMaterial({ map: texture, color: 0xffffff }); let box = new THREE.Mesh(boxGeometry, material); scene.add(box); let render = () => { stats.update(); trackballControls.update(); requestAnimationFrame(render); renderer.render(scene, camera); } render(); } init();
完整示例(src/pages/three_TGALoader_demo):https://github.com/MAXLZ1/threejs_demo十三、PRWMLoader
加载.prwm资源。
import '../../stylus/index.styl' import * as THREE from 'three' import * as dat from 'dat.gui' import {initTrackballControls, initThree, initStats} from "../../util/util"; import {PRWMLoader} from "../../libs/loaders/PRWMLoader"; async function init () { let stats = initStats(); let {camera, scene, renderer} = initThree(); let trackballControls = initTrackballControls(camera, renderer); camera.position.set(0, 0, 10); let loader = new PRWMLoader(); let load = (url) => new Promise((resolve, reject) => { loader.load(url, (bufferGeometry) => { let object = new THREE.Mesh( bufferGeometry, new THREE.MeshNormalMaterial() ); scene.add( object ); resolve(object); }); }); let obj = await load('../../static/modules/prwm/faceted-nefertiti.be.prwm'); let render = () => { stats.update(); trackballControls.update(); requestAnimationFrame(render); renderer.render(scene, camera); }; let gui = new dat.GUI(); let controls = { modules: 'faceted-nefertiti.be.prwm' }; gui.add(controls, 'modules', [ 'faceted-nefertiti.be.prwm', 'faceted-nefertiti.le.prwm', 'smooth-suzanne.be.prwm', 'smooth-suzanne.le.prwm', 'vive-controller.be.prwm', 'vive-controller.le.prwm' ]).onChange(async item => { scene.remove(obj); obj = await load(`'../../static/modules/prwm/${item}`); }); render(); } init();
完整示例(src/pages/three_PRWMLoader_demo):https://github.com/MAXLZ1/threejs_demo -
[微信小游戏+Three.JS]针对微信小游戏修改的three.js和weapp-adapter.js
2018-06-21 15:08:00最近在做一个微信3D小游戏 直接从github上下载的three.js,无法直接在微信小游戏中运行 下面是我修改,并经过测试完美的three.js和weapp-adapter.js Three.js(已经压缩,814K) ... -
【Three.js】五、three.js中的材质——Material
2019-09-04 21:41:47【Three.js】五、three.js中的材质——Material一、 three.js中的材质就是几何体表面的材料。 一、 -
【Three.js技术简介】什么是Three.js
2020-12-12 09:42:34(1)Three.js百度百科:https://baike.baidu.com/item/three.js/7896801?fr=aladdin (2)WebGL百度百科: https://baike.baidu.com/item/WebGL/592485?fr=aladdin (3)OpenGL百度百科:... -
Three.js初识:three.js的下载与使用
2020-02-26 22:36:47引用cdn: <script src="https://cdn.bootcss.com/three.js/92/three.js"></script> -
Three.js编辑器editor使用详解
2020-08-03 15:34:14Three.js编辑器editor使用详解官网下载Three.js压缩包其他的文件内容如下:了解过文件内容之后下一步: 官网下载Three.js压缩包 github官网源码包 解压后文件目录如下图: 其他的文件内容如下: Build目录:包含两... -
【Three.js】十、three.js场景中物体的选择
2019-09-28 21:46:58【Three.js】十、three.js动画 -
【Three.js】三、three.js之几何体与网格
2019-09-01 11:21:59【Three.js】three.js之几何体与网格 -
【Three.js】二、three.js中的场景——Scene
2019-08-29 23:20:34【Three.js】二、three.js中的场景——Scene -
【Three.js】搭建Three.js开发环境
2020-10-06 22:17:49Three.js是一个比较著名的3d引擎了,今天搭建了下它的开发环境。 一 官网 官网地址如下: https://threejs.org/ 二 下载源码包 在官网左侧直接点击download,就会把所有的源码下载下来。为方便使用,直接解压,... -
【Three.js】八、three.js几何体的组合与合并
2019-09-17 10:41:56【Three.js】七、three.js粒子、精灵、点云 -
AR.js打造高效WebAR(three.js+AR.js)
2018-03-11 23:29:22ar.js很棒的一处是结合three.js进行3D渲染。当然ar.js都是国外大牛封装开发的,我只是简单分享下向大家介绍下ar.js,并分享下ar.js开发的心得,同时也做了一个小demo。 我们先看一下demo的效果,fps能到60: ... -
【three.js-性能优化】three.js性能优化
2018-11-26 14:15:38转载:three.js性能优化 three.js是JavaScript编写的WebGL第三方库。提供了非常多的3D显示功能。在使用的时候,虽然three.js 做了优化,但是在使用不恰当的代码,也会产生性能损耗。帧率越低,给人感觉就越卡。这是... -
Three.js入门学习笔记11:Three.js-Group组合对象
2020-03-17 14:13:46http://www.yanhuangxueyuan.com/doc/Three.js/Group.html https://blog.csdn.net/ithanmang/article/details/80965712 http://www.yanhuangxueyuan.com/Three.js/ https://www.cnblogs.com/guxingy/p/11956390... -
【Three.js】七、three.js粒子、精灵、点云
2019-09-16 20:29:20【Three.js】七、three.js粒子、精灵、点云一、粒子(Sprite)二、点云(Points) 粒子(也叫精灵),可用来创建非常细小的物体,可以用来模拟雨、雪、烟等其他有趣的效果。 一、粒子(Sprite) 使用Three.... -
pixi.js + three.js
2019-01-30 15:53:00three.js 最好的webgl 3d渲染库之一, pixi.js 最好的webgl 2d渲染库之一,也许可以把之一去掉 两个库都很精简,如果把两个库结合起来,一定很爽很爽,你说是吧! 跳一跳three.js开发的。 欢乐球球three.js+pixi.... -
【three.js学习环境的配置】学习three.js前的环境配置
2019-05-30 14:15:262.【phpStudy】:用于存放three.js源码,作为本地的开发服务器。(也可用:wamp,xampp等) 3.【sublimeText 3】:用于编写代码。(也可用DW,visual studio Code ,webstorm等) 步骤: 1.phpStudy下载后解压安装... -
three.js 绘制墙_使用Three.js可视化地绘制3D
2020-08-14 16:17:59three.js 绘制地板Every developer has their favorite tools, languages, and technologies to work with. Sometimes it derives from another passion such as solving mathematical problems, white-hat hacking,... -
Threejs 官网 - Three.js 的图形用户界面工具(GUI Tools with Three.js)
2014-07-27 07:50:35Threejs 官网 - Three.js 的图形用户界面工具(GUI Tools with Three.js) -
three.js加载3D模型(.glb格式和.gltf格式)
2019-07-05 10:52:03要使用three.js实现在网页中加载3D模型进行实时展示的功能,首先要了解three.js 什么是three.js,Three.js是一款开源的主流3D绘图JS引擎,简单点,可以将它理解为three+js就可以了,three表示3D,js表示JavaScript... -
Three.js中Detector.js替换成了WebGL.js
2018-09-26 18:45:37Three.js 源码更新,删除了Detector.js ,采用新的WebGL.js了。 更新时间在2018年9月26日 //使用detector.js的检测代码 if ( ! Detector.webgl ) Detector.addGetWebGLMessage(); //使用webgl.js的检测代码 if ( ... -
three.js 源码注释(一)./Three.js
2014-08-26 08:01:57在Three.js文件中包含了THREE.js大部分的常量,主要分为以下几类CustomBlendingEquation,GLState,Materials,ShadowingTypes,Textures. 着色方式 绝大多数的3D物体是由多边形(polygon)所构成的,它们都必须经过某些... -
three.js ObjectControls.js
2018-10-31 19:25:03three.js ObjectControls.js three.js-object-controls Control object rotation, scale。 控制物体的旋转和缩放。 适合的场景是物体在坐标原点,绕Y轴左右旋转,绕X轴上下旋转,所以相机必须在Z轴上。 比较类似... -
Three.js - three.js加载资源的异步操作
2018-07-30 09:48:57js中的回调函数一般都是异步操作的,同样three.js中像加载模型数据,和一些其它的资源文件的加载也是通过回调函数的方式来获取的,所以它们也是异步的。在此之前,我还不知道怎么把那些回调函数改成同步操作。 因为... -
Three.js学习笔记 – “我和小伙伴都惊呆了”的特效和Three.js初探
2017-04-01 10:26:22Three.js学习笔记 – “我和小伙伴都惊呆了”的特效和Three.js初探 什么是Three.js three.js是JavaScript编写的WebGL第三方库。提供了非常多的3D显示功能。Three.js 是一款运行在浏览器中的 3D 引擎,你... -
Yomotsu 使用 THREE.js 创建的示例(Examples created by Yomotsu using THREE.js)
2014-08-02 19:49:55Yomotsu 使用 THREE.js 创建的示例(Examples created by Yomotsu using THREE.js) -
53 Three.js 使用THREE.PointCloud(新版本改名:THREE.Points)批量管理粒子
2018-01-18 00:05:23当我们如果大量使用粒子时,会很快遇到性能问题,因为每添加一个粒子就是一个模型,因为每个粒子对象分别由THREE.js进行管理,所以,three.js提供了另一种方式来处理大量粒子,那就是使用THREE.PointCloud。...