目录
1.创建3D场景:并添加一个长方体几何对象
2.添加透视投影相机:
3.创建渲染器对象
4、添加光源
5、使用相机控件轨道控制器
6、使用平行光与环境光
7、循环动画函数(自带的requestAnimationFrame)
1、渲染循环实现旋转动画
2、计算两帧时间间隔
3、渲染循环+OrbitControls(相机)
8、canvas画布宽高度动态变化
9、stats查看threejs渲染帧率
1、案例源码
2、创建大量物体,测试性能
// 引入three.js
import * as THREE from 'three';
/**
* 创建3D场景对象Scene
*/
const scene = new THREE.Scene();
/**
* 创建网格模型
*/
//创建一个长方体几何对象Geometry
const geometry = new THREE.BoxGeometry(50, 50, 50);
//材质对象Material
const material = new THREE.MeshBasicMaterial({
color: 0x0000ff, //设置材质颜色
});
const mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
//设置网格模型在三维空间中的位置坐标,默认是坐标原点
mesh.position.set(0,10,0);
scene.add(mesh); //网格模型添加到场景中
// width和height用来设置渲染后,输出的画布宽高度。
const width = 800; //宽度
const height = 500; //高度
/**
* 透视投影相机设置
*/
// 30:视场角度, width / height:Canvas画布宽高比, 1:近裁截面, 3000:远裁截面
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
camera.position.set(292, 223, 185); //相机在Three.js三维坐标系中的位置
camera.lookAt(0, 0, 0); //相机观察目标指向Three.js坐标系原点
/**
* 创建渲染器对象
*/
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height); //设置three.js渲染区域的尺寸(像素px)
renderer.render(scene, camera); //执行渲染操作
//three.js执行渲染命令会输出一个canvas画布,也就是一个HTML元素,你可以插入到web页面中
//document.body.appendChild(renderer.domElement);
document.getElementById('webgl').appendChild(renderer.domElement);
/**
* 光源设置
*/
//点光源
const pointLight = new THREE.PointLight(0xffffff, 1.0);
//点光源位置
// pointLight.position.set(400, 0, 0);//点光源放在x轴上
pointLight.position.set(400, 200, 300);//偏移光源位置,观察渲染效果变化
scene.add(pointLight); //点光源添加到场景中
// 设置相机控件轨道控制器OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
// 如果OrbitControls改变了相机参数,重新调用渲染器渲染三维场景
controls.addEventListener('change', function () {
renderer.render(scene, camera); //执行渲染操作
// 浏览器控制台查看相机位置变化
console.log('camera.position',camera.position);
});//监听鼠标、键盘事件
/**
* 光源设置
*/
// //点光源
// const pointLight = new THREE.PointLight(0xffffff, 1.0);
// //点光源位置
// pointLight.position.set(400, 200, 300);
// scene.add(pointLight); //点光源添加到场景中
//环境光:没有特定方向,整体改变场景的光照明暗
const ambient = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambient);
// 平行光
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
// 设置光源的方向:通过光源position属性和目标指向对象的position属性计算
directionalLight.position.set(100, 60, 50);
// 方向光指向对象网格模型mesh,可以不设置,默认的位置是0,0,0
// directionalLight.target = mesh;
scene.add(directionalLight);
// DirectionalLightHelper:可视化平行光
const dirLightHelper = new THREE.DirectionalLightHelper(directionalLight, 5,0xff0000);
scene.add(dirLightHelper);
// 渲染循环
function render() {
renderer.render(scene, camera); //执行渲染操作
mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度
requestAnimationFrame(render);//请求再次执行渲染函数render,渲染下一帧
}
render();
// 渲染循环
const clock = new THREE.Clock();
function render() {
const spt = clock.getDelta()*1000;//毫秒
console.log('两帧渲染时间间隔(毫秒)',spt);
console.log('帧率FPS',1000/spt);
renderer.render(scene, camera); //执行渲染操作
mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度
requestAnimationFrame(render);//请求再次执行渲染函数render,渲染下一帧
}
render();
// 引入three.js
import * as THREE from 'three';
// 引入轨道控制器扩展库OrbitControls.js
import {
OrbitControls
} from 'three/addons/controls/OrbitControls.js';
/**
* 创建3D场景对象Scene
*/
const scene = new THREE.Scene();
/**
* 创建网格模型
*/
//创建一个长方体几何对象Geometry
const geometry = new THREE.BoxGeometry(100, 100, 100);
// 漫反射网格材质;MeshLambertMaterial
const material = new THREE.MeshLambertMaterial({
color: 0x00ffff, //设置材质颜色
transparent: true, //开启透明
opacity: 0.5, //设置透明度
});
const mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
scene.add(mesh); //网格模型添加到场景中
// AxesHelper:辅助观察的坐标系
const axesHelper = new THREE.AxesHelper(100);
scene.add(axesHelper);
/**
* 光源设置
*/
// 平行光
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(100, 60, 50);
scene.add(directionalLight);
//环境光
const ambient = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambient);
// width和height用来设置Three.js输出的Canvas画布尺寸(像素px)
const width = 800; //宽度
const height = 500; //高度
/**
* 透视投影相机设置
*/
// 30:视场角度, width / height:Canvas画布宽高比, 1:近裁截面, 3000:远裁截面
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
camera.position.set(292, 223, 185); //相机在Three.js三维坐标系中的位置
camera.lookAt(0, 0, 0); //相机观察目标指向Three.js坐标系原点
/**
* 创建渲染器对象
*/
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height); //设置three.js渲染区域的尺寸(像素px)
// renderer.render(scene, camera); //执行渲染操作
//three.js执行渲染命令会输出一个canvas画布,也就是一个HTML元素,你可以插入到web页面中
document.body.appendChild(renderer.domElement);
// 渲染循环
function render() {
renderer.render(scene, camera); //执行渲染操作
mesh.rotateY(0.01); //每次绕y轴旋转0.01弧度
requestAnimationFrame(render); //请求再次执行渲染函数render,渲染下一帧
}
render();
// 设置相机控件轨道控制器OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
// // 如果OrbitControls改变了相机参数,重新调用渲染器渲染三维场景
// controls.addEventListener('change', function () {
// renderer.render(scene, camera); //执行渲染操作
// }); //监听鼠标、键盘事件
// onresize 事件会在窗口被调整大小时发生
window.onresize = function () {
// 重置渲染器输出画布canvas尺寸
renderer.setSize(window.innerWidth, window.innerHeight);
// 全屏情况下:设置观察范围长宽比aspect为窗口宽高比
camera.aspect = window.innerWidth / window.innerHeight;
// 渲染器执行render方法的时候会读取相机对象的投影矩阵属性projectionMatrix
// 但是不会每渲染一帧,就通过相机的属性计算投影矩阵(节约计算资源)
// 如果相机的一些属性发生了变化,需要执行updateProjectionMatrix ()方法更新相机的投影矩阵
camera.updateProjectionMatrix();
};
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
//引入性能监视器stats.js,显示帧率
import Stats from 'three/addons/libs/stats.module.js';
//创建stats对象
const stats = new Stats();
//Stats.domElement:web页面上输出计算结果,一个div元素
document.body.appendChild(stats.domElement);
// 三维场景
const scene = new THREE.Scene();
// 创建网格模型对象
const geometry = new THREE.BoxGeometry(100, 100, 100);
// 漫反射网格材质;MeshLambertMaterial
const material = new THREE.MeshLambertMaterial({
color: 0x00ffff, //设置材质颜色
transparent: true, //开启透明
opacity: 0.5, //设置透明度
});
const mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
scene.add(mesh); //网格模型添加到场景中
//辅助观察的坐标系
const axesHelper = new THREE.AxesHelper(100);
scene.add(axesHelper);
//光源设置
const pointLight = new THREE.PointLight(0xffffff, 1.0);
pointLight.position.set(400, 200, 300);
scene.add(pointLight);
const ambient = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambient);
//渲染器和相机
const width = window.innerWidth;
const height = window.innerHeight;
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
camera.position.set(292, 223, 185);
camera.lookAt(0, 0, 0);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);
// 渲染循环
function render() {
stats.update();//渲染循环中执行stats.update()来刷新时间
renderer.render(scene, camera);
mesh.rotateY(0.01);
requestAnimationFrame(render);
}
render();
const controls = new OrbitControls(camera, renderer.domElement);
// 画布跟随窗口变化
window.onresize = function () {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
};
import * as THREE from 'three';
import {
OrbitControls
} from 'three/addons/controls/OrbitControls.js';
//引入性能监视器stats.js,显示帧率
import Stats from 'three/addons/libs/stats.module.js';
//创建stats对象
const stats = new Stats();
//Stats.domElement:web页面上输出计算结果,一个div元素
document.body.appendChild(stats.domElement);
// 三维场景
const scene = new THREE.Scene();
// 随机创建大量的模型,测试渲染性能
const num = 1000; //控制长方体模型数量,你可以一直增加或减少看看帧率变化,电脑性能不同结果不同
for (let i = 0; i < num; i++) {
const geometry = new THREE.BoxGeometry(5, 5, 5);
const material = new THREE.MeshLambertMaterial({
color: 0x00ffff
});
const mesh = new THREE.Mesh(geometry, material);
// 随机生成长方体xyz坐标
const x = (Math.random() - 0.5) * 200
const y = (Math.random() - 0.5) * 200
const z = (Math.random() - 0.5) * 200
mesh.position.set(x, y, z)
scene.add(mesh); // 模型对象插入场景中
}
//辅助观察的坐标系
const axesHelper = new THREE.AxesHelper(100);
scene.add(axesHelper);
//光源设置
const pointLight = new THREE.PointLight(0xffffff, 1.0);
pointLight.position.set(400, 200, 300);
scene.add(pointLight);
const ambient = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambient);
//渲染器和相机
const width = window.innerWidth;
const height = window.innerHeight;
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
camera.position.set(292, 223, 185);
camera.lookAt(0, 0, 0);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);
// 渲染循环
function render() {
stats.update(); //渲染循环中执行stats.update()来刷新时间
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
const controls = new OrbitControls(camera, renderer.domElement);
// 画布跟随窗口变化
window.onresize = function () {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
};