Three——三、动画执行、画布大小、渲染帧率和相机适配体验

news2024/9/24 5:31:11

动画渲染循环

threejs 可以借助 HTML5 的 API 请求动画帧 window.requestAnimationFrame 实现动画渲染。

请求动画帧window.requestAnimationFrame(实现周期性循环执行)

// requestAnimationFrame实现周期性循环执行
// requestAnimationFrame默认每秒钟执行60次,但不一定能做到,要看代码的性能
let i = 0;
function render() {
  i += 1;
  console.log("执行次数" + i);
  requestAnimationFrame(render); //请求再次执行函数render
}
render();

旋转动画

原理及一张张照片连起来依次显示,只要帧率变高,人眼就看不出来卡顿从而达到视频效果。

// 必要的渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);

// 渲染函数
const render = () => {
  renderer.render(scene, camera); //执行渲染操作
  mesh.rotateY(0.01); //每次绕y轴旋转0.01弧度
  requestAnimationFrame(render); //请求再次执行渲染函数render,渲染下一帧
};
render();

实际效果:请添加图片描述

计算两帧渲染时间间隔和帧率

// 计算两帧渲染时间间隔和帧率
const clock = new THREE.Clock();

// 动画渲染循环
const 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();

请添加图片描述

Canvas 画布布局和全屏

Threejs 渲染的结果是一个 canvas 画布,画布也是 HTML 元素之一,布局和普通前端的习惯是一样的
通过renderer.domElement属性可以访问 Threejs 的渲染结果,也就是 HTML 中的 canvas 画布。

非全屏局部布局

只需要把 renderer.domElement 部分插入到 web 页上的任意一个元素都可以实现非全屏局部布局
例:

<div class="container" ref="container"></div>
let container = document.querySelector(".container");
let width = 500;
let height = 500;
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);

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);
container.appendChild(renderer.domElement);

全屏渲染

所谓的全屏渲染那就是把宽高改成当前窗口高度宽度即可

const width = window.innerWidth; //窗口文档显示区的宽度作为画布宽度
const height = window.innerHeight; //窗口文档显示区的高度作为画布高度
const renderer = new THREE.WebGLRenderer();
document.body.appendChild(renderer.domElement);

画布宽高动态变化

调整窗口大小时,canvas 布局会动态进行缩放

window.addEventListener("resize", () => {
  // 更新摄像头
  camera.aspect = window.innerWidth / window.innerHeight;
  // 如果相机的一些属性发生了变化,需要执行updateProjectionMatrix ()方法更新相机的投影矩阵
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
});

stats 查看 threejs 的渲染帧率

通过 stats.js 库可以查看 three.js 当前的渲染性能,具体说就是计算 three.js 的渲染帧率(FPS),所谓渲染帧率(FPS),简单说就是 three.js 每秒钟完成的渲染次数,一般渲染达到每秒钟 60 次为最佳状态。

引入 Stats

// 性能监视器stats.js
import Stats from "three/addons/libs/stats.module.js";

Stats 使用

//创建stats对象
const stats = new Stats();
//stats.domElement:web页面上输出计算结果,一个div元素,
document.body.appendChild(stats.domElement);
// 渲染函数
function render() {
  //requestAnimationFrame循环调用的函数中调用方法update(),来刷新时间
  stats.update();
  stats.setMode(1);
  renderer.render(scene, camera); //执行渲染操作
  requestAnimationFrame(render); //请求再次执行渲染函数render,渲染下一帧
}
render();

效果:
请添加图片描述

stats 方法 setMode(mode)

可以通过setMode()方法的参数 mode 的数值设置首次打开页面,测试结果的显示模式,鼠标单击可以更换不同的显示模式。

// stats.domElement显示:渲染帧率  刷新频率,一秒渲染次数
stats.setMode(0); //默认模式
//stats.domElement显示:渲染周期 渲染一帧多长时间(单位:毫秒ms)
stats.setMode(1);

性能测试

添加多个长方形对性能进行测试

// 随机创建大量的模型,测试渲染性能
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); // 模型对象插入场景中
}

效果对比:
请添加图片描述

请添加图片描述

阵列立方体和相机适配体验

咱们接下来换个材质 MeshBasicMaterial
通过 for 循环在 x 轴循环一列模型

const geometry = new THREE.BoxGeometry(100, 100, 100);
// 材质
const material = new THREE.MeshBasicMaterial({
  color: 0x00ffff,
  transparent: true, //开启透明
  opacity: 0.5, //设置透明度
});

// 网络模型
for (let i = 0; i < 10; i++) {
  mesh = new THREE.Mesh(geometry, material);
  mesh.position.set(i * 200, 20, 0);
  scene.add(mesh);
}

这里需要注意一下:图形循环增加,需要将透视的数值改的小一些

// 透视投影相机PerspectiveCamera
// 支持的参数:fov, aspect, near, far
camera = new THREE.PerspectiveCamera(
  60,
  clientWidth / clientHeight,
  0.001, // 这里数值调小一些
  6000
);

效果如下:
请添加图片描述

双层 for 循环创建阵列模型

// 几何体
const geometry = new THREE.BoxGeometry(100, 100, 100);
// 材质
const material = new THREE.MeshBasicMaterial({
  color: 0x00ffff,
  transparent: true, //开启透明
  opacity: 0.5, //设置透明度
});

// 网络模型
for (let i = 0; i < 10; i++) {
  for (let j = 0; j < 10; j++) {
    mesh = new THREE.Mesh(geometry, material);
    mesh.position.set(i * 200, 20, j * 200);
    scene.add(mesh);
  }
}

请添加图片描述

相机位置拉远,可以看到更大的观察范围

const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
// camera.position.set(292, 223, 185);
//在原来相机位置基础上拉远,可以观察到更大的范围
camera.position.set(800, 800, 800);
camera.lookAt(0, 0, 0);

超出视锥体远裁界面的范围的会被剪裁掉

// const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 8000);
// camera.position.set(292, 223, 185);
// 超出视锥体远裁界面的范围的会被剪裁掉,不渲染  可以调整far参数适配
camera.position.set(2000, 2000, 2000);
camera.lookAt(0, 0, 0);

请添加图片描述

改变相机观察目标

// const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 8000);
camera.position.set(2000, 2000, 2000);
// camera.lookAt(0, 0, 0);
// 改变相机观察目标点
camera.lookAt(1000, 0, 1000);

注意相机控件 OrbitControls 会影响 lookAt 设置,注意手动设置 OrbitControls 的目标参数

// 设置相机控件轨道控制器OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
// 相机控件.target属性在OrbitControls.js内部表示相机目标观察点,默认0,0,0
// console.log('controls.target', controls.target);
controls.target.set(1000, 0, 1000);
controls.update(); //update()函数内会执行camera.lookAt(controls.targe)

改变前:
请添加图片描述

改变后:
请添加图片描述

透视投影相机的投影规律是远小近大,通过相机观察阵列立方体大小变化,可以看到距离相机越远,立方体的渲染视觉效果越小。

关于 for 的改变

增加相机视角 fov,视锥体范围更大,意味着可以看到渲染范围更大,远小近大的视觉效果更明显。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/488453.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DJI RTK无人机采集后的文件分析:nav、bin、event、MRK文件

NAV文件&#xff1a; NAV文件是导航数据文件。它们通常存储有关飞行路径、GPS坐标、高度和其他相关数据的信息。这些数据可用于图像的地理参照、飞行分析或故障排除。 EVENT文件&#xff1a; EVENT文件记录了飞行过程中发生的各种事件&#xff0c;如无人机何时起飞&#xff0c…

在线办公大势所趋,细说3种主流云办公方式优劣

文章目录 前言在线协作&#xff1a;WPS优势方面部分缺点 远程控制&#xff1a;ToDesk优势方面部分缺点 云桌面&#xff1a;阿里云桌面优势方面部分缺点 总结 前言 云办公会不会在未来五到十年成为普遍现象&#xff1f;当我们在疫情期间不得不加入远程办公行列时&#xff0c;其…

DC-DC 自举电容

背景&#xff1a; 最近在调试一个DC-DC电路&#xff0c;16V/20A的芯片&#xff0c;功率算是中等偏上。 DCDC工作不正常&#xff0c;空载有输出&#xff0c;接负载后&#xff0c;电压马上掉落到大概2.3V&#xff0c;一开始以为是电感选取不对&#xff0c;瞬态响应不足&#xf…

Ribbon、LocdBalance和openFeign的实战

Ribbon 使用RestTemplate时&#xff0c;如果不加LoadBalance&#xff0c;调用不通&#xff0c;需要使用LoadBalance作为负载均衡 手写一个客户端的负载均衡器 GetMapping("order/create2")public String createOrder2(){List<ServiceInstance> instances d…

Ant Design Pro---【01 环境安装+UMI入门】

入门基础 web 技术 web 技术是指通过 JavaScript&#xff0c;HTML&#xff0c;css 来构建网站的技术&#xff0c;mdn 提供了相当方便的文档来帮助我们学习这些知识。 Node.js 前端开发基础环境 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时&#xff0c;Node.js 的…

95后阿里P7晒出工资单:狠补了这个,真香···

最近一哥们跟我聊天装逼&#xff0c;说他最近从阿里跳槽了&#xff0c;我问他跳出来拿了多少&#xff1f;哥们表示很得意&#xff0c;说跳槽到新公司一个月后发了工资&#xff0c;月入5万多&#xff0c;表示很满足&#xff01;这样的高薪资着实让人羡慕&#xff0c;我猜这是税后…

分布式事务 --- 理论基础、Seata架构、部署

一、分布式事务问题 1.1、本地事务 本地事务&#xff0c;也就是传统的单机事务。在传统数据库事务中&#xff0c;必须要满足四个原则&#xff1a; 1.2、分布式事务 分布式事务&#xff0c;就是指不是在单个服务或单个数据库架构下&#xff0c;产生的事务&#xff0c;例如&am…

[OtterCTF 2018]之Misc篇(NSSCTF)刷题记录⑦

NSSCTF-Misc篇-[OtterCTF 2018] [OtterCTF 2018]General Info[OtterCTF 2018]Play Time[OtterCTF 2018]Silly Rick[OtterCTF 2018]What the password?[OtterCTF 2018]Name Game[OtterCTF 2018]Hide And Seek[OtterCTF 2018]Name Game 2[OtterCTF 2018]Path To Glory[OtterCTF …

软光敏算法学习之二

《监控设备日夜模式的切换方法、系统、设备及存储介质》专利学习笔记 一、主要原理&#xff1a; 在夜模式下时&#xff0c;判断摄像头的传感器感知的光强度是否大于第一切换阈值&#xff1b;如果所述光强度大于第一切换阈值&#xff0c;则判断摄像头拍摄的图像中符合红外响应特…

【源码解析】Spring Cloud Gateway的断言和过滤器源码解析

路由断言(Route Predicate)工厂 Spring Cloud Gateway包括许多内置的路由断言(Route Predicate)工厂&#xff0c;所有这些Predicate都与HTTP请求的不同属性匹配。多个Route Predicate工厂可以进行组合。 官方文档&#xff1a;https://docs.spring.io/spring-cloud-gateway/do…

TCP协议结构

文章目录 TCP---传输控制协议TCP报文结构 TCP—传输控制协议 缓冲区的意义 TCP协议是自带发送和接收缓冲区的&#xff0c;相当于malloc了两段内存空间。 系统调用接口send,write等并不是直接把数据发送到网络上&#xff0c;而是把数据拷贝到TCP的发送缓冲区&#xff0c;至此应…

Java读取Properties配置文件的6种方式

Java读取Properties的方式 项目结构&#xff1a;经典的maven项目结构 配置文件1和2内容一致&#xff1a; jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urlmysql://localhost:3306/database?useUnicodetrue&characterEncodingutf-8&serverTimezoneAsia/Shanghai jdbc.…

Axios二次封装

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、Axios是什么&#xff1f;二、为什么要对Axios进行二次封装三、Axios二次封装1.首先&#xff0c;安装 Axios&#xff1a;2.创建一个名为 http.js 的文件&#xf…

AI 工具合辑盘点(三)持续更新

人工智能技术的发展已经改变了我们的生活&#xff0c;越来越多的AI工具正在被广泛应用于各个领域。ChatGPT这样的代表性AI模型正在大放异彩&#xff0c;为我们带来了无数的便利和惊喜。在本文中&#xff0c;我们将介绍一系列优秀的AI工具&#xff0c;这些工具可以帮助你完成各种…

课程教学大纲系统的设计与实现

技术栈&#xff1a; Nginx、MySQL、Maven、SpringBoot、Spring、SpringMVC、MyBatis、HikariCP、fastjson、slf4j、Vue、NodeJS系统功能&#xff1a; 本系统分教师和管理员两种角色&#xff0c;不同角色可操作的功能不尽相同&#xff0c;各个角色具体功能如下&#xff1a;教师 …

Python实现哈里斯鹰优化算法(HHO)优化随机森林回归模型(RandomForestRegressor算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 2019年Heidari等人提出哈里斯鹰优化算法(Harris Hawk Optimization, HHO)&#xff0c;该算法有较强的全…

SpringCloud------Eureka单机版整合生产以及消费(四)

SpringCloud------Eureka&#xff08;四&#xff09; Eureka 读音&#xff1a;有瑞卡 Eureka基础知识 单机构架步骤 集群构建步骤 autuator微服务信息完善 服务发现Discovery eureka自我保护 服务注册与发现 包括&#xff1a; Eureka Zookeeper Consul Nacos 【分布式的CAP理…

FlinkCDC初体验

一、CDC简介 1.1 什么是CDC&#xff1f; CDC是 Change Data Capture(变更数据获取 )的简称。 核心思想是&#xff0c;监测并捕获数据库的 变动&#xff08;包括数据或数据表的插入 、 更新 以及 删除等&#xff09;&#xff0c;将这些变更按发生的顺序完整记录下 来&#xff0c…

【Flask】Python基于Flask应用

Flask介绍 Flask 是一款发布于2010年非常流行的 Python Web 框架。 特点 微框架、简洁&#xff0c;给开发者提供了很大的扩展性。Flask和相应的插件写得很好&#xff0c;用起来很爽。 开发效率非常高&#xff0c;比如使用 SQLAlchemy 的 ORM 操作数据库可以节省开发者大量书…

【LeetCode】数据结构题解(5)[分割链表]

分割链表 1.题目来源2.题目描述3.解题思路4.代码展示 所属专栏&#xff1a;玩转数据结构题型 博主首页&#xff1a;初阳785 代码托管&#xff1a;chuyang785 感谢大家的支持&#xff0c;您的点赞和关注是对我最大的支持&#xff01;&#xff01;&#xff01; 博主也会更加的努力…