让你的three.js动起来

让你的three.js动起来

简介

本节主要是给实例添加动画效果,以及加了一些小插件用以实现帧率检测、gui可视化配置、动态监听屏幕大小变化刷新和鼠标操控功能。

引入的插件js:

  • three.js
  • dat.gui.js
  • Stats.js
  • TrackballControls.js

实际效果:

在这里插入图片描述

关键代码:

动画效果:

动画效果主要使用的是requestAnimationFrame方法,通过这个函数,你可以向浏览器提供一个回调函数。 你无须定义回调间隔,浏览器将自行决定最佳回调时机。你需要做的是在这个回调函数里完成一帧绘制操作(即在这里再次执行一遍你的渲染函数),然后将剩下的工作交给浏览器,它负责使场景绘制尽量高效和平顺地进行。

帧率检测:

主要运用的是Stats插件,主要涉及的点是

  • 引用该js,
  • 完成方法的初始化操作,
  • 最后在渲染函数里添加触发update的事件。
gui可视化配置:

主要运用的是dat.gui插件,主要涉及的点是

  • 引用该js,
  • 并且完成方法的初始化操作,
  • 和要可视化配置的组件进行变量绑定,
  • 最后在渲染函数里将可视化的参数设置到组件的属性中。
动态监听屏幕大小变化刷新

主要应用的是浏览器的resize方法

  • 绑定window的监听resize方法,
  • 在resize的回调函数里变更camera的aspect和updateProjectionMatrix()方法
  • 在resize的回调函数里重新setSize实例的尺寸。
鼠标操控

主要运用的是TrackballControls插件,主要涉及的点是

  • 引用该js,
  • 完成方法的初始化操作,
  • 最后在渲染函数里添加触发update的事件。

完整代码:

// 初始化检测动画运行帧数方法
let stats = new Stats()
stats.showPanel(0)
document.body.appendChild(stats.dom)

// 初始化GUI插件
let controls = new function () {
	this.rotationSpeed = 0.02;
	this.bouncingSpeed = 0.03;
};
let gui = new dat.GUI()
gui.add(controls, 'rotationSpeed', 0, 0.5)
gui.add(controls, 'bouncingSpeed', 0, 0.5)

//容器
const container = document.getElementById('container')
let scale = window.innerWidth / window.innerHeight
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 45, scale, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0x000000))
renderer.setSize(window.innerWidth, window.innerHeight)

// 设置渲染器支持阴影渲染功能
renderer.shadowMap.enabled = true;
// 坐标轴大小
var axes = new THREE.AxesHelper(20)
scene.add(axes)
// 创建地面
var planeGeometry = new THREE.PlaneGeometry(60, 20);

// 将材质替换为可对光源产生反应的:MeshLambertMaterial
var planeMaterial = new THREE.MeshLambertMaterial({
	color: 0xAAAAAA
});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
// r旋转地面
plane.rotation.x = -0.5 * Math.PI;
plane.position.set(15, 0, 0);

// 设置平面可接受阴影
plane.receiveShadow = true;
// 添加地面到场景中
scene.add(plane);
// 添加方块
var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
var cubeMaterial = new THREE.MeshLambertMaterial({
	color: 0xFF0000
});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
// 设置方块位置
cube.position.set(-4, 3, 0);
// 设置立方体可投射阴影
cube.castShadow = true;


// 添加方块到场景中
scene.add(cube);
// 创建球体
var sphereGeometry = new THREE.SphereGeometry(4, 20, 20);
var sphereMaterial = new THREE.MeshLambertMaterial({
	color: 0x7777FF
});
var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
// 设置球体位置
sphere.position.set(20, 4, 2);


// a添加球体到场景中
scene.add(sphere);

// 设置球体可投射阴影
sphere.castShadow = true;

// 放置相机位置
camera.position.set(-30, 40, 30);
camera.lookAt(scene.position);

// 设置光源
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;
scene.add(spotLight);

// 添加canvas节点
container.appendChild(renderer.domElement);

// 添加鼠标放大缩小移动插件
let trackballControls = initTrackballControls(camera, renderer)
let clock = new THREE.Clock()
function initTrackballControls(camera, renderer) {
    var trackballControls = new THREE.TrackballControls(camera, renderer.domElement);
    trackballControls.rotateSpeed = 1.0;
    trackballControls.zoomSpeed = 1.2;
    trackballControls.panSpeed = 0.8;
    trackballControls.noZoom = false;
    trackballControls.noPan = false;
    trackballControls.staticMoving = true;
    trackballControls.dynamicDampingFactor = 0.3;
    trackballControls.keys = [65, 83, 68];

    return trackballControls;
}

// 渲染函数
let step = 0
function renderScene() {
	// 更新鼠标控制插件
	trackballControls.update(clock.getDelta())
	// 帧数更新
	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 :
	 * 通过这个函数,你可以向浏览器提供一个回调函数。
	 * 你无须定义回调间隔,浏览器将自行决定最佳回调时机。
	 * 你需要做的是在这个回调函数里完成一帧绘制操作,
	 * 然后将剩下的工作交给浏览器,
	 * 它负责使场景绘制尽量高效和平顺地进行。
	 */
	requestAnimationFrame(renderScene)
	// 渲染
	renderer.render(scene, camera)
}

// 渲染函数调用
renderScene();

// 定义 resize方法,屏幕尺寸变更时触发
window.addEventListener('resize', onResize, false)
function onResize() {
	// aspect属性,这个属性表示屏幕的长宽比
	camera.aspect = window.innerWidth / window.innerHeight
	camera.updateProjectionMatrix()
	renderer.setSize(window.innerWidth, window.innerHeight)
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis高可用高性能缓存的应用系列03 - 缓存过期淘汰策略LRU、LFU

概述 Redis高可用高性能缓存的应用系列的第3篇,主要介绍Redis缓存过期淘汰策略和内存淘汰策略回收的LRU和LFU的知识点进行说明。 Redis过期键删除策略 Redis设置key时,都会设置一个过期时间,那么当过期时间到了都是怎么处理的?…

不用但一定要懂 ---- iOS 之 响应链、传递链 与 手势识别

iOS 事件的主要由:响应连 和 传递链 构成。一般事件先通过传递链,传递下去。响应链,如果上层不能响应,那么一层一层通过响应链找到能响应的UIResponse。 响应链:由最基础的view向系统传递,first view ->…

初谈 ChatGPT

引子 最近,小编发现互联网中的大 V 突然都在用 ChatGPT 做宣传:“ChatGPT不会淘汰你,能驾驭ChatGPT的人会淘汰你”、“带领一小部分人先驾驭ChatGPT”。 确实,ChatGPT这个新生事物,如今被视为蒸汽机、电脑、iPhone 般的…

EfficientNet V2

目录 1. EfficientNet V1存在的问题 2. EfficientNet V2 的亮点 3. EfficientNet V2 网络架构 1. EfficientNet V1存在的问题 针对EfficientNet V1 ,作者提出了以下的三个缺点 当训练图像的size很大时,网络中传递的特征图尺寸就会很大,这…

(链表专题) 234. 回文链表——【Leetcode每日一题】

234. 回文链表 给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。 示例 1: 输入:head [1,2,2,1] 输出:true 示例 2: 输入&…

Vue:组件化开发

一、组件的使用 1、创建组件(结构HTML 交互JS 样式CSS) Vue.extend({该配置项和new Vue的配置项几乎相同,略有差别}) 区别:①创建vue组件的时候,配置项中不能使用el配置项。(但是需要使用template配置项来配置模板语句) ②配置项中的da…

黑马程序员微服务技术栈教程 - 1. SpringCloud 微服务治理

教程链接:https://www.bilibili.com/video/BV1LQ4y127n4 黑马的资料下载链接:https://pan.baidu.com/s/1zRmwSvSvoDkWh0-MynwERA&pwd1234 目录认识微服务单体架构分布式架构微服务微服务结构微服务技术对比SpringCloud总结 🎀服务拆分及远…

实时翻译器-实时自动翻译器

自动翻译器——让语言不再是障碍。 在当今全球化的背景下,语言已不再是跨文化交流的障碍。而自动翻译技术作为突破语言壁垒的有效手段,越来越受到关注和需求。我们的自动翻译器就是一个高效、准确的翻译工具,它能够根据用户输入的内容自动识…

【DS】河南省第十三届ICPC大学生程序设计竞赛 J-甜甜圈

明天就要省赛了,感觉已经寄了捏 J-甜甜圈_河南省第十三届ICPC大学生程序设计竞赛(重现赛) (nowcoder.com) 题意: 思路: 直接模拟复杂度太高,因此考虑用DS优化 我们考虑用树状数组维护 在用线段树和树状…

MYSQL Row 752 was cut by GROUP_CONCAT()

因为group_concat有个最大长度的限制,GROUP_CONCAT函数返回的结果大小被MySQL默认限制为1024(字节)的长度。超过最大长度就会被截断掉 解决方法:更改配置文件,修改长度。 https://blog.csdn.net/zzddada/article/details/115082236 concat…

网络的基本概念

作者:爱塔居 专栏:JavaEE 作者简介:大三学生,希望和大家一起进步 文章简介:主要概述IP地址、端口号、协议、协议分层、封装、分用、客户端、服务器、请求、响应、两台主机之间的网络通信流程。 文章目录 目录 文章目录…

Yolo V7详解及openvino部署

论文: https://arxiv.org/abs/2207.02696 代码: https://github.com/WongKinYiu/yolov7 Anchor Anchor是一种用于目标检测的先验框(prior box)生成方法,由Ren等人在2015年提出。Anchor可以在不同尺度和不同纵横比下生成多个先验框,并通过与真实目标框的…

java equals和==的区别

目录一、equals1.前言2.重写equals方法二、三、equals和的区别一、equals 1.前言 **当用equals来比较两个引用数据类型时默认比较的是它们的地址值,比如创建两个成员变量完全相同对象A和对象B两个进行比较,比较的是两个对象的地址值是否相等&#xff0c…

〖Python网络爬虫实战⑫〗- XPATH语法介绍

订阅:新手可以订阅我的其他专栏。免费阶段订阅量1000python项目实战 Python编程基础教程系列(零基础小白搬砖逆袭) 说明:本专栏持续更新中,目前专栏免费订阅,在转为付费专栏前订阅本专栏的,可以免费订阅付费…

【三十天精通Vue 3】第二天 Vue 3带来的新特性

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: 三十天精通 Vue 3 文章目录引言一、 Vue 3 组件化架构1.1 Composition API1.2 Vuex 3 更新1.3…

OpenGL编程指南-freeglut安装(Windows平台)

OpenGL编程指南-freeglut安装(Windows平台) 1、前言 学习OpenGL编程首先需要可以跟着书中的示例代码进行学习。书中使用GLUT作为示例代码的演示,GLUT于1998年作者不在维护并不开源,freeglut是一个完美的代替方案。以后我们将会通…

23年5月高项学习笔记12 —— 干系人管理

过程: 1. 识别干系人:定期识别干系人,分析和记录他们的利益,参与度、相互依赖性、影响力和对项目的潜在的影响 输入:立项管理文件、沟通管理计划、干系人参与计划、需求文件、变更日志、问题日志、协议(协…

MySQL事物(基础篇)

MySQL事务事物的基本概念事物的ACID属性事务的使用事务隔离级别MVCC&ReadViewMySQL是否还存在幻读事物的基本概念 Transaction作为关系型数据库的核心组成,在数据安全方面有着非常重要的作用,本文会一步步解析事务的核心特性,以获得对事…

STM32CubeMx+HAL库实现USB CDC+MSC复合设备

之前的文章中介绍过STM32的USB应用,包括虚拟串口(CDC)和大容量存储设备(MSC)。今天来介绍USB实现CDC和MSC复合设备的方法。 硬件:STM32F407VET6 软件:STM32CubeMx v6.5F4库v1.27.1 编译环境&a…

自动驾驶概述

自动驾驶是指利用计算机视觉、机器学习、传感器等技术,使汽车或其他交通工具能够在没有人类干预的情况下,完成自主导航和行驶任务。自动驾驶技术可以提高交通安全、减少交通拥堵、提高车辆利用率等,并对未来的城市交通和交通工具设计产生深远…