Three.js camera初探——转场动画实现

news2024/11/27 8:40:10

背景

首先简单介绍一下three.jsthree.js是用javascript写的基于webGL的第三方3D库,通过它可以在网页中进行3D建模,结合上TweenMax.js动画库,在网页中实现3D动画效果就变得很简单了。

这是three.js建模的简单流程图例:

用通俗的话来讲,首先可以用js创建各种形状的几何体,或者从外部导入建好的模型文件,然后为几何体添加材质(纹理、颜色等),就组成了一个网格模型mesh,我们可以创建很多的模型,塞进场景容器里,还要为场景加入灯光,通过“打光”照相机才能拍到场景里面的物体,当要拍摄动态场景时,就需要照相机不断的拍摄然后通过渲染器不停地渲染到屏幕上(渲染循环),最后屏幕展现的就是一个3D动态场景。

既然是通过照相机去拍摄场景,让我们在屏幕上可以看到,那么移动照相机用不同的角度拍摄这个世界,自然就可以看到不一样的世界了。

three.js中的camera

three.js中的camera分为两种,一种是正投影相机,一种是透视投影相机,两种的大致区别是:

(图片来自webGL中文网)

在透视投影下,同样大小的物体,在屏幕下远处的物体会比近处的物体小,而正投影下两者是一样大小的。

在本例demo中,我们用的是透视投影,实例化代码如下:

camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);

复制

四个参数分别表示视角,看到的窗口宽度和高度的比例,能看到的最近处的距离,和能看到的最远处的距离。视角越大,拍摄到的场景范围就越大,能看到的物体就显得越小。

接着便是camera位置的设置,在初始化camera时,一般都会先设置好它的3个属性,position/up/lookAt.以demo为例讲解一下这三个属性。在这之前,我们先了解一下three.js的坐标系,使用的是右手坐标系,如下图所示:

就是这么有气质的手势~~大拇指指向x轴正方向,食指指向y轴正方向,中指指向z轴正方向。

再回来看看camera的初始化代码:

camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 500;
camera.up.x = 0;
camera.up.y = 1;
camera.up.z = 0;
camera.lookAt({x : 0 ,y : 0, z : 0});

复制

  1. camera.position: 顾名思义,就是camera在坐标系中的所在位置,处于z轴正方向上离原点500处。
  2. camera.up:比较难理解,指的是camera“头顶”的方向和向量(0,1,0)同向,即和y轴正方向同向。画个图理解一下:

  1. camera.lookAt: 指的就是camera面向哪里,这里是直接面向原点。

另外,camera.up设置的方向必须与camera位置和lookAt的连线不能平行,否则拍不到场景,这个大家自己可以摆摆手势体会一下~

demo实现过程-计算

1.准备过程

在初始化three.js后,创建我们需要的物体,在这里我随机创建了几个正方体,它们的大小和位置都是随机的,面向屏幕的一面加载了一张图片纹理,作为正面,如下图所示:

如果从y轴正方向往y轴负方向看,示意图大致是这样子的(蓝色代表正方体,有粗线加箭头的一面代表正方体有图片的正面,黑色的圆柱体代表照相机,箭头指明拍摄方向):

接下来便是动画过程,需要注意的是,接下来的都是物体只绕y方向旋转,x/z方向只做位移,这样就把一个三维空间的运动转化为二维空间了~~

2.将照相机移到y轴上,旋转正方体和照相机使之正对,如下图所示:

在初始化时,我们便记录了正方体的坐标值(x,y,z),正方体从面向屏幕到面向y轴要旋转多少角度,我这里用了初中数学方法——反三角函数算出。如下图所示分别为四个象限物体需要旋转的角度值。

旋转了正方体后,照相机只要和正方体旋转同样的角度,并坐标中的y值移到和正方体同向,就可以拍摄到正方体正面了。

  1. 因为之前所说的正方体是大小不一的,需要移动照相机使得照相机和正方体的距离与正方体的大小保持一定的比例,这样看到每个正方体的大小才是一致的。所以需要计算照相机的位移,如下图:

我们已知正方体的边长a,假设照相机与正方体中心点的距离设置为3a,利用相似三角形边长等比例的原理得出照相机的该移到的地方(x2,z2)坐标,公式如下:

  1. 为了让正方体具备随机摆放的感觉,还可以让正方体再绕y方向随机转动一定角度,照相机再绕正方体的中心点旋转到正对正方体正面的位置:

计算方法如下:

如上图所示,照相机原来是在正方体中心和原点的连线上的坐标(x,z),绕正方体的中心点(rx,rz)旋转随机角度θ后得到的(x',z')的计算公式如下:

以上的角度计算过程,都可以用js中强大的Math函数搞定,包括Math.atan()\math.cos()等等,具体代码就不贴了。

demo实现过程-动画

上面过程中的第2、3步,直接调用TweenMax.js的动画库,控制camera.position/camera.rotation就可以了。但是第4步由于不能想css一样直接设定transform-origin为正方体中心点,所以必须自己实现。例如控制位移:


TweenMax.to(
    camera.position,  //指明控制的属性
    2, //动画时间
    {x:x2,y: mesh[index].position.y,z:z2,delay:0,ease:Cubic.easeIn} //需要移动的距离
);

复制

这里用到的是requestAnimationFrame()来实现,通过一点点地改变camera的旋转和位置的移动,直到达到角度θ。

var rate;  //旋转频率
function cameraRoAni(){
    var ani;
    //当物体的旋转角度大于0
    if (rotateMesh[index-1] > 0) {
        rotateRate = rotateRate + rate;
        if(rotateRate <= rotateMesh[index-1]){
            var newX = (camera.position.x - mesh[index-1].position.x)*Math.cos(-rate) - (camera.position.z - mesh[index-1].position.z)*Math.sin(-rate) +  mesh[index-1].position.x;
            var newZ = (camera.position.x - mesh[index-1].position.x)*Math.sin(-rate) + (camera.position.z - mesh[index-1].position.z)*Math.cos(-rate) +  mesh[index-1].position.z;
            camera.position.x = newX;
            camera.position.z = newZ;
            camera.rotation.y += rate;
            ani = requestAnimationFrame(cameraRoAni);
        }else{
            cancelAnimationFrame(ani);
        }
    //当物体的旋转角度小于0
    }else{
        ... //代码和大于0时相似
        }else{
            cancelAnimationFrame(ani);
        }
    }
    if (rate>0.01) {
        rate = rate - 0.0001;
    }
}

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

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

相关文章

基于B/S架构springboot框架开发的中小学智慧校园平台源码

一、智慧校园技术框架&#xff1a; 1、使用springboot框架Javavue2 B/S架构 2、JAVA语言数据库MySQL5.7 3、移动端小程序使用小程序原生语言开发 4、电子班牌固件安卓7.1&#xff1b;使用Java Android原生 5、elmentui &#xff0c;Quartz&#xff0c;jpa&#xff0c;jwt …

实现 Linux 视频会议(源码,支持信创环境,银河麒麟,统信UOS)

信创是现阶段国家发展的重要战略之一&#xff0c;面对这一趋势&#xff0c;所有的软件应用只有支持信创国产化的基础软硬件设施&#xff0c;在未来才不会被淘汰。那么&#xff0c;可以使用C#来实现支持信创环境的视频会议系统吗&#xff1f;答案是肯定的。 本文讲述如何使用C#来…

django 快速入门

快速开始 安装Django 首先安装Django包&#xff0c;现在Django已经到了2.0版本&#xff0c;如果还在使用1.11请尽快升级。旧版本以后只修复bug&#xff0c;不会添加新功能。 pip install django 复制 创建项目 Django安装好之后&#xff0c;会附带一个命令行工具django-a…

uCOSii_任务栈检测和任务栈清除

1、任务栈检测和任务栈清除 在创建任务时&#xff0c;也需要设置OSTaskCreateExt()传入opt参数。 当opt (INT16U)(OS_TASK_OPT_STK_CLR | OS_TASK_OPT_STK_CHK)&#xff0c;可以使用OSTaskStkChk()检查的任务栈的剩余空间&#xff0c;也可以使用OS_TaskStkClr()清除任务栈。 …

使用Graalvm+Swing搓了个原生桌面应用的轮子:文件差异对比工具,附轮子源码

文章目录 1、DFDiff介绍2、软件架构3、安装教程3.1、编译为jar包运行3.2、编译为原生应用运行 4、运行效果图5、项目源码地址 1、DFDiff介绍 当前已实现的功能比较两个文件夹内的文件差异&#xff0c;已支持文件差异对比。 2、软件架构 软件架构说明 开发环境是在OpenJDK17&…

docker 安装gitlab jenkins git maven

jenkins 配置git提示 问题1、Error performing git command: /usr/local/git ls-remote -h 问题2、stdout: stderr: Host key verification failed. fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repositor…

【数据结构】一文带你掌握二叉树的构造与应用

文章目录 1. 构造二叉树2. 前序遍历2.1 前序遍历递归2.2 前序遍历非递归 3. 中序遍历3.1 中序遍历递归3.2 中序遍历非递归 4. 后序遍历4.1 后序遍历递归4.2 后序遍历非递归 5. 层序遍历6. 节点个数6.1 所有节点个数6.2 获得叶子节点个数 7. 检测值为value的元素是否存在8.总结 …

数据库SQL2000最基本的安装和操作教程

Chengg0769 2012年 转载请保留以下版权来源 www.mis2erp.com http://blog.csdn.net/chengg0769 http://www.haojiaocheng.cc 题外话&#xff1a; 之前写了一个项目&#xff0c;因为是国企&#xff0c;各种文档都要给到他们。当时就写了一个简单的维护管理SQL2000的文档。这…

【2352. 相等行列对】

来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 给你一个下标从 0 开始、大小为 n x n 的整数矩阵 grid &#xff0c;返回满足 Ri 行和 Cj 列相等的行列对 (Ri, Cj) 的数目。 如果行和列以相同的顺序包含相同的元素&#xff08;即相等的数组&#…

DMBOK知识梳理for CDGA/CDGP——第四章 数据架构(附常考知识点)

关 注ghz“大数据食铁兽”&#xff0c;回复“知识点”获取《DMBOK知识梳理for CDGA/CDGP》常考知识点&#xff08;第四章 数据架构&#xff09; 第四章 数据架构 第四章是CDGA|CDGP考试的重点考核章节之一&#xff0c;分值占比高&#xff0c;知识点比较密集&#xff0c;重点…

CAN message 属性DLC和DataLength,极易混淆

&#x1f345; 我是蚂蚁小兵&#xff0c;专注于车载诊断领域&#xff0c;尤其擅长于对CANoe工具的使用&#x1f345; 寻找组织 &#xff0c;答疑解惑&#xff0c;摸鱼聊天&#xff0c;博客源码&#xff0c;点击加入&#x1f449;【相亲相爱一家人】&#x1f345; 玩转CANoe&…

STM32开发(CubeMX+HAL)——点灯(轮询、中断)

目录 1.CubeMX生成工程文件 2.点灯1——轮询 3.点灯2——中断 3.1CubeMX配置时钟 3.2中断和事件简介 3.3配置GPIO口 3.4使能中断 3.5配置工程 3.6中断函数编写 1.CubeMX生成工程文件 1.1新建工程 1.2输入STM32C8T6选择芯片 1.3双击芯片 1.4 选择System Core—SYS——…

DAY09_JQueryBootStrap实现省略号效果

目录 1 JQuery简介2 引入JQuery方式3 JS与JQ之间的转换4 选择器4.1 基本选择器4.2 层级选择器4.2.1 层级选择器相关方法 4.3 过滤选择器4.4 内容选择器4.5 可见选择器4.6 隐藏显示的相关方法4.7 属性选择器4.8 子元素选择器4.9 表单选择器 5 JQ中新增的遍历方式6 JQ中相关方法7…

vue解决浏览器中跳转新页面缓存上一页表单等内容方法

在工作中&#xff0c;有可能会遇到需要缓存页面或组件的功能。 情况1&#xff1a;比如在h5中有个一个50个表单&#xff0c;在填到第40个表单时&#xff0c;需要你去另一个新页面去选择列表项&#xff0c;然后把数据带回来。需要我们不仅把数据带回来还要保留前面已经填好的40个…

GIS地图:解读未知的地理空间之谜

在这个信息爆炸的时代&#xff0c;如何有效地理解和利用地理空间数据成为各行各业追求的目标。而GIS地图作为一种强大的工具&#xff0c;能够帮助我们连接世界的空间智慧。 GIS地图的魅力在于它能够将庞大的地理数据转化为直观、可视化的地图表达。通过GIS地图&#xff0c;我们…

管理平台|智慧工地将成为施工界的“扛把子”!

大家都知道&#xff0c;建筑业是一个安全事故频发的高危行业&#xff0c;特别在施工环节&#xff0c;由于施工现场人员复杂、环境混乱、地点分散、多工序交叉等现象&#xff0c;如何进行现场施工管理就显得格外重要。 但是&#xff0c;依赖于现场管理的施工模式总是存在着很多…

数据结构-图结构

图是最为复杂的数据结构。如果数据元素之间存在一对多或者多对多的关系&#xff0c;那么这种数据的组织结构就叫作图结构。 图的基本概念 图的定义 图Graph是由顶点&#xff08;图中的节点被称为图的顶点&#xff09;的非空有限集合V与边的集合E&#xff08;顶点之间的关系&a…

什么AC+AP组网?什么是mesh组网?

一、什么是ACAP组网&#xff1f; ACAP组网是一种基于集中式管理的无线局域网&#xff08;WLAN&#xff09;组网架构&#xff0c;主要由AC&#xff08;Access Controller&#xff09;和多个AP&#xff08;Access Point&#xff09;组成。AC作为网络管理中心&#xff0c;负责控制…

别乱分层,PO、VO、DAO、BO、DTO、POJO 到底应该用在哪里,你知道吗

一、PO :&#xff08;persistant object&#xff09;&#xff0c;持久对象 二、VO :&#xff08;value object&#xff09;&#xff0c;值对象 三、DAO :&#xff08;Data Access Objects&#xff09;&#xff0c;数据访问对象接口 四、BO :&#xff08;Business Object&…

30天从入门到精通TensorFlow1.x 第六天,可视化工具 TensorBoard

文章目录 一、接前一天二、TensorBoard&#xff08;1&#xff09;. 什么是TensorBoard&#xff08;2&#xff09;. TensorBoard有什么用&#xff08;3&#xff09;. TensorBoard怎么安装 三、tf.summary模块&#xff08;1&#xff09;.如何使用tensorboard&#xff08;2&#x…