<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
body { margin: 0; }
canvas { display: block; }
</style>
</head>
<body>
<script src="./main.js"></script>
</body>
</html>
index.html
main.js
package.json
现在支持上传本地图片了!
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
//引入性能监视器stats.js
import Stats from 'three/addons/libs/stats.module.js';
// 引入dat.gui.js的一个类GUI
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
// 画布尺寸
const width = window.innerWidth;
const height = window.innerHeight;
const obj = {
isRotate: true
};
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000); // 视场角度fov; 画布宽高比; 近裁截面; 远裁截面
const renderer = new THREE.WebGLRenderer({
antialias: true,
});
const geometry = new THREE.BoxGeometry(100, 100, 100); // 形状
const material = new THREE.MeshPhongMaterial({ // MeshPhongMaterial高光网格材质
color: '#049ef4',
transparent: true,
opacity: 0.6,
shininess: 10, // 高光部分的亮度
specular: "#ccc", // 高光部分的颜色
}); // 材质(分为是否受光照影响)
const mesh = new THREE.Mesh(geometry, material); // 网格模型
const axesHelper = new THREE.AxesHelper(150); // 坐标系
const pointLight = new THREE.DirectionalLight('#fff', 1); // 光源
const pointLightHelper = new THREE.PointLightHelper(pointLight, 10); // 光源辅助观察
const controls = new OrbitControls(camera, renderer.domElement); // 相机控件轨道控制器
const stats = new Stats(); // 性能监视器
const gui = new GUI(); // 可视化改变三维场景
// 添加分组
const methFolder = gui.addFolder('网格');
const matFolder = gui.addFolder('材质');
const pointLightFolder = gui.addFolder('光源');
const animateFolder = gui.addFolder('动画');
// methFolder.close();
// matFolder.close();
// pointLightFolder.close();
// animateFolder.close();
// 修改GUI界面默认的style属性
gui.domElement.style.right = '0px';
// 创建交互页面: .add(控制对象,对象具体属性,其他参数)
methFolder.add(mesh.position, 'x', -100, 100).name('网格 x 坐标');
methFolder.add(mesh.position, 'y', -100, 100).name('网格 y 坐标');
methFolder.add(mesh.position, 'z', -100, 100).name('网格 z 坐标');
matFolder.add(material, 'shininess', 0, 100).name('高光部分的亮度');
matFolder.addColor(material.specular, 'r', 0, 255).name('高光部分的 r 值颜色');
matFolder.addColor(material.specular, 'g', 0, 255).name('高光部分的 g 值颜色');
matFolder.addColor(material.specular, 'b', 0, 255).name('高光部分的 b 值颜色');
pointLightFolder.add(pointLight, 'intensity', 0, 2.0);
animateFolder.add(obj, "isRotate").name('旋转动画');
pointLight.decay = 0.0; // 设置光源不随距离衰减,默认为2.0
pointLight.position.set(-500, 400, 500);
mesh.position.set(200, 100, 100);
scene.add(mesh);
scene.add(axesHelper);
scene.add(pointLight);
scene.add(pointLightHelper);
camera.position.set(-300, 200, 200); // x,y,z
camera.lookAt(mesh.position); // 相机视角: 指向mesh设置的位置(中心点)
renderer.setSize(width, height);
renderer.setClearColor(0x444444, 1);
renderer.render(scene, camera); // 执行渲染操作
document.body.appendChild(renderer.domElement); // 通过.domElement获得.render渲染方法生成的canvas画布
document.body.appendChild(stats.domElement);
window.onresize = () => {
const newWidth = window.innerWidth;
const newHeight = window.innerHeight;
renderer.setSize(newWidth, newHeight); // 更新渲染器尺寸
camera.aspect = newWidth / newHeight; // 更新相机比例
camera.updateProjectionMatrix(); // 如果相机的一些属性发生了变化,需要执行updateProjectionMatrix ()方法更新相机的投影矩阵
}
const render = () => {
stats.update();
renderer.render(scene, camera);
if(obj.isRotate) {
mesh.rotateX(0.01);
mesh.rotateY(0.01);
}
requestAnimationFrame(render); // 实现周期性循环执行;默认每秒钟执行60次,但不一定能做到,要看代码的性能.
}
render();
// 不同硬件设备的屏幕的设备像素比window.devicePixelRatio值可能不同
// console.log('查看当前屏幕设备像素比',window.devicePixelRatio);
{
"dependencies": {
"three": "0.173.0"
}
}
预览