1、安装
"three": "^0.155.0", //主体 主要是这个
"three-obj-mtl-loader": "^1.0.3", // 加载外部模型
"dat-gui": "^0.5.0",//gui 设置
"@tweenjs/tween.js": "^21.0.0", //动画
2、官网
https://threejs.org/manual/#zh/textures
3、引入使用
import * as THREE from "three";
4、简单例子
1.太阳-地球-月亮
模拟场景与场景之间的联系
<html> <head> <meta charset="utf-8" /> <title>太阳系 three.js app</title> <style> html, body { margin: 0; height: auto; overflow-y: auto; } #c { width: 100%; height: 100%; display: block; } </style> </head> <body> <canvas id="c"></canvas> <div id="ui"></div> <script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js" ></script> <script type="importmap"> { "imports": { "three": "https://unpkg.com/three@0.155.0/build/three.module.js", "three/addons/": "https://unpkg.com/three@0.155.0/examples/jsm/" } } </script> <script type="module"> //导入 import * as THREE from "three"; import { GUI } from "three/addons/libs/lil-gui.module.min.js"; // function resizeRendererToDisplaySize(renderer) { // const canvas = renderer.domElement; // const width = canvas.clientWidth; // const height = canvas.clientHeight; // const needResize = canvas.width !== width || canvas.height !== height; // if (needResize) { // renderer.setSize(width, height, false); // } // return needResize; // } // 响应式处理 function resizeRendererToDisplaySize(renderer) { // const canvas = renderer.domElement; const canvas = document.querySelector("#c"); const pixelRatio = window.devicePixelRatio; const width = (canvas.clientWidth * pixelRatio) | 0; const height = (canvas.clientHeight * pixelRatio) | 0; const needResize = canvas.width !== width || canvas.height !== height; if (needResize) { renderer.setSize(width, height, false); } return needResize; } function main() { const canvas = document.querySelector("#c"); //创建渲染器 const renderer = new THREE.WebGLRenderer({ antialias: true, canvas }); const gui = new GUI(); // 创建相机 const fov = 40; const aspect = 2; // the canvas default const near = 0.1; const far = 1000; const camera = new THREE.PerspectiveCamera(fov, aspect, near, far); camera.position.set(0, 50, 0); camera.up.set(0, 0, 1); camera.lookAt(0, 0, 0); // 创建场景 const scene = new THREE.Scene(); // 创建灯光 { const color = 0xffffff; const intensity = 500; const light = new THREE.PointLight(color, intensity); scene.add(light); } // 要更新旋转角度的对象数组 const objects = []; // 创建场景图 const solarSystem = new THREE.Object3D(); scene.add(solarSystem); objects.push(solarSystem); // 创建地球场景 const earthOrbit = new THREE.Object3D(); earthOrbit.position.x = 10; // scene.add(earthOrbit); solarSystem.add(earthOrbit); objects.push(earthOrbit); // 创建月球场景 const moonOrbit = new THREE.Object3D(); moonOrbit.position.x = 2; // scene.add(moonOrbit); earthOrbit.add(moonOrbit); objects.push(moonOrbit); // 一球多用 const radius = 1; const widthSegments = 6; const heightSegments = 6; const sphereGeometry = new THREE.SphereGeometry( radius, widthSegments, heightSegments ); // 地球 // const textGeometry = new THREE.TextGeometry(text, { // font: font, // size: size, // height: height, // curveSegments: curveSegments, // bevelEnabled: bevelEnabled, // bevelThickness: bevelThickness, // bevelSize: bevelSize, // }); // const textMesh = new THREE.Mesh( // textGeometry, // new THREE.MeshPhongMaterial({ // side: THREE.DoubleSide, // emissive: 0xffff00, // }) // ); // scene.add(textMesh); { // 创建一个太阳 const sunMaterial = new THREE.MeshPhongMaterial({ side: THREE.DoubleSide, emissive: 0xffff00, }); const sunMesh = new THREE.Mesh(sphereGeometry, sunMaterial); sunMesh.scale.set(5, 5, 5); // 扩大太阳的大小 // scene.add(sunMesh); solarSystem.add(sunMesh); objects.push(sunMesh); // 创建地球 const earthMaterial = new THREE.MeshPhongMaterial({ color: 0x2233ff, emissive: 0x112244, }); const earthMesh = new THREE.Mesh(sphereGeometry, earthMaterial); // earthMesh.position.x = 10; // scene.add(earthMesh); // 将地球变为太阳的子节点 // sunMesh.add(earthMesh); earthOrbit.add(earthMesh); objects.push(earthMesh); // 创建月球 const moonMaterial = new THREE.MeshPhongMaterial({ color: 0x888888, emissive: 0x222222, }); const moonMesh = new THREE.Mesh(sphereGeometry, moonMaterial); moonMesh.scale.set(0.5, 0.5, 0.5); moonOrbit.add(moonMesh); objects.push(moonMesh); class AxisGridHelper { constructor(node, units = 10) { const axes = new THREE.AxesHelper(); axes.material.depthTest = false; axes.renderOrder = 2; // 在网格渲染之后再渲染 node.add(axes); const grid = new THREE.GridHelper(units, units); grid.material.depthTest = false; grid.renderOrder = 1; node.add(grid); this.grid = grid; this.axes = axes; this.visible = false; } get visible() { return this._visible; } set visible(v) { this._visible = v; this.grid.visible = v; this.axes.visible = v; } } function makeAxisGrid(node, label, units) { const helper = new AxisGridHelper(node, units); gui.add(helper, "visible").name(label); } // makeAxisGrid(solarSystem, "solarSystem", 25); // makeAxisGrid(sunMesh, "sunMesh"); // makeAxisGrid(earthOrbit, "earthOrbit"); // makeAxisGrid(earthMesh, "earthMesh"); // makeAxisGrid(moonOrbit, "moonOrbit"); // makeAxisGrid(moonMesh, "moonMesh"); } function render(time) { time *= 0.001; // convert time to seconds objects.forEach((obj) => { obj.rotation.y = time; // const axes = new THREE.AxesHelper(); // axes.material.depthTest = false; // axes.renderOrder = 1; // obj.add(axes); }); if (resizeRendererToDisplaySize(renderer)) { camera.aspect = canvas.clientWidth / canvas.clientHeight; camera.updateProjectionMatrix(); } renderer.render(scene, camera); requestAnimationFrame(render); } requestAnimationFrame(render); } main(); </script> </body> </html>
效果:
2.八大行星
外部模型的加载使用
<html> <head> <meta charset="utf-8" /> <title>太阳系八大行星 three.js app</title> <style> html, body { margin: 0; height: auto; overflow-y: auto; } #c { width: 100%; height: 100%; display: block; } </style> </head> <body> <canvas id="c"></canvas> <div id="ui"></div> <script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js" ></script> <script type="importmap"> { "imports": { "three": "https://unpkg.com/three@0.155.0/build/three.module.js", "three/addons/": "https://unpkg.com/three@0.155.0/examples/jsm/" } } </script> <script type="module"> //导入 import * as THREE from "three"; import { GUI } from "three/addons/libs/lil-gui.module.min.js"; import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js"; import { OrbitControls } from "three/addons/controls/OrbitControls.js"; // 响应式处理 function resizeRendererToDisplaySize(renderer) { // const canvas = renderer.domElement; const canvas = document.querySelector("#c"); const pixelRatio = window.devicePixelRatio; const width = (canvas.clientWidth * pixelRatio) | 0; const height = (canvas.clientHeight * pixelRatio) | 0; const needResize = canvas.width !== width || canvas.height !== height; if (needResize) { renderer.setSize(width, height, false); } return needResize; } function main() { const canvas = document.querySelector("#c"); //创建渲染器 const renderer = new THREE.WebGLRenderer({ antialias: true, canvas }); const gui = new GUI(); // 创建相机 const fov = 40; const aspect = 2; // the canvas default const near = 0.1; const far = 1000; const camera = new THREE.PerspectiveCamera(fov, aspect, near, far); camera.position.set(0, 50, 0); camera.lookAt(0, 0, 0); // 旋转相机 const controls = new OrbitControls(camera, canvas); controls.target.set(0, 5, 0); controls.update(); // 创建场景 const scene = new THREE.Scene(); // 创建灯光 { const color = 0xffffff; const intensity = 500; const light = new THREE.PointLight(color, intensity); scene.add(light); } // 要更新旋转角度的对象数组 const objects = []; // 创建场景图 const solarSystem = new THREE.Object3D(); scene.add(solarSystem); objects.push(solarSystem); // 创建水星场景 const mercurySystem = new THREE.Object3D(); mercurySystem.position.x = 3.5; solarSystem.add(mercurySystem); objects.push(mercurySystem); // 创建维纳斯场景 const venusSystem = new THREE.Object3D(); venusSystem.position.x = 6; solarSystem.add(venusSystem); objects.push(venusSystem); // 创建地球场景 const earthOrbit = new THREE.Object3D(); earthOrbit.position.x = 10; solarSystem.add(earthOrbit); objects.push(earthOrbit); // 创建金星场景 const marsOrbit = new THREE.Object3D(); marsOrbit.position.x = 13; solarSystem.add(marsOrbit); objects.push(marsOrbit); // 创建jupiter场景 const jupiterOrbit = new THREE.Object3D(); jupiterOrbit.position.x = 15; solarSystem.add(jupiterOrbit); objects.push(jupiterOrbit); // 创建saturn场景 const saturnOrbit = new THREE.Object3D(); saturnOrbit.position.x = 20; solarSystem.add(saturnOrbit); objects.push(saturnOrbit); // 创建uranus场景 const uranusOrbit = new THREE.Object3D(); uranusOrbit.position.x = 24; solarSystem.add(uranusOrbit); objects.push(uranusOrbit); // 创建neptune场景 const neptuneOrbit = new THREE.Object3D(); neptuneOrbit.position.x = 29; solarSystem.add(neptuneOrbit); objects.push(neptuneOrbit); { //载入太阳 const loader = new GLTFLoader(); // 一球多用 const radius = 1; const widthSegments = 6; const heightSegments = 6; const sphereGeometry = new THREE.SphereGeometry( radius, widthSegments, heightSegments ); const sunMaterial = new THREE.MeshPhongMaterial({ side: THREE.DoubleSide, emissive: 0xffff00, }); const sunMesh = new THREE.Mesh(sphereGeometry, sunMaterial); const mercuryMesh = new THREE.Mesh(sphereGeometry, sunMaterial); const venusMesh = new THREE.Mesh(sphereGeometry, sunMaterial); const earthMesh = new THREE.Mesh(sphereGeometry, sunMaterial); const marsMesh = new THREE.Mesh(sphereGeometry, sunMaterial); const jupiterMesh = new THREE.Mesh(sphereGeometry, sunMaterial); const saturnMesh = new THREE.Mesh(sphereGeometry, sunMaterial); const uranusMesh = new THREE.Mesh(sphereGeometry, sunMaterial); const neptuneMesh = new THREE.Mesh(sphereGeometry, sunMaterial); const modelList = [ { path: "model/sun.glb", scale: [0.2, 0.2, 0.2], fatherObj: solarSystem, mesh: sunMesh, }, { path: "model/mercury_enhanced_color.glb", scale: [0.5, 0.5, 0.5], fatherObj: mercurySystem, mesh: mercuryMesh, }, { path: "model/venus.glb", scale: [1, 1, 1], fatherObj: venusSystem, mesh: venusMesh, }, { path: "model/earth.glb", scale: [1, 1, 1], fatherObj: earthOrbit, mesh: earthMesh, }, { path: "model/mars.glb", scale: [15, 15, 15], fatherObj: marsOrbit, mesh: marsMesh, }, { path: "model/jupiter.glb", scale: [1, 1, 1], fatherObj: jupiterOrbit, mesh: jupiterMesh, }, { path: "model/saturn.glb", scale: [0.01, 0.01, 0.01], fatherObj: saturnOrbit, mesh: saturnMesh, }, { path: "model/uranus.glb", scale: [1, 1, 1], fatherObj: uranusOrbit, mesh: uranusMesh, }, { path: "model/neptune.glb", scale: [1, 1, 1], fatherObj: neptuneOrbit, mesh: neptuneMesh, }, ]; modelList.forEach((item) => { loader.load( item.path, function (gltf) { gltf.scene.traverse(function (child) { if (child.isMesh) { child.frustumCulled = false; //模型阴影 child.castShadow = true; //模型自发光 child.material.emissive = child.material.color; child.material.emissiveMap = child.material.map; } }); gltf.scene.scale.set(...item.scale); item.fatherObj.add(gltf.scene); // sunMesh.add(gltf.scene) objects.push(gltf.scene); }, undefined, function (error) { console.error(error); } ); //不使用模型 使用球体 // item.fatherObj.add(item.mesh); // // sunMesh.add(gltf.scene) // objects.push(item.mesh); }); class AxisGridHelper { constructor(node, units = 10) { const axes = new THREE.AxesHelper(); axes.material.depthTest = false; axes.renderOrder = 2; // 在网格渲染之后再渲染 node.add(axes); const grid = new THREE.GridHelper(units, units); grid.material.depthTest = false; grid.renderOrder = 1; node.add(grid); this.grid = grid; this.axes = axes; this.visible = false; } get visible() { return this._visible; } set visible(v) { this._visible = v; this.grid.visible = v; this.axes.visible = v; } } function makeAxisGrid(node, label, units) { const helper = new AxisGridHelper(node, units); gui.add(helper, "visible").name(label); } // makeAxisGrid(solarSystem, "solarSystem", 25); // makeAxisGrid(sunMesh, "sunMesh"); // makeAxisGrid(earthOrbit, "earthOrbit"); // makeAxisGrid(earthMesh, "earthMesh"); // makeAxisGrid(moonOrbit, "moonOrbit"); // makeAxisGrid(moonMesh, "moonMesh"); } function render(time) { time *= 0.001; // convert time to seconds objects.forEach((obj, index) => { obj.rotation.y = time; // obj.rotation.x = time; // const axes = new THREE.AxesHelper(); // axes.material.depthTest = false; // axes.renderOrder = 1; // obj.add(axes); }); if (resizeRendererToDisplaySize(renderer)) { camera.aspect = canvas.clientWidth / canvas.clientHeight; camera.updateProjectionMatrix(); } renderer.render(scene, camera); requestAnimationFrame(render); } requestAnimationFrame(render); } main(); </script> </body> </html>
效果:
今ならできます。
标签:
three.js
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
2018-09-12 linux vue项目+npm run build + nginx
2018-09-12 linux 配置vue环境
2018-09-12 pygame 简单播放音乐程序