用cocos实现的立方体宣传查看页面

news2024/12/24 20:38:57

cocos进入3.x时代,我也努力跟进,实现了一个将页面映射到立方体上进行旋转查看的效果。

效果如下:

要点

为了这个效果,我主要实现了3个要点:

  • 将页面准确映射到立方体上面,适配不同尺寸的手机屏幕。
  • 对页面内容进行正常滑动、点击操作。
  • 不同页面数量能够在立方体上滑动屏幕循环查看。

页面映射到立方体

创建立方体和页面

因为需要在4个面上显示不同的页面内容,引擎自带的立方体并不能简单地满足这个功能。这里我使用了4个quad拼凑成一个四面体,放在一个节点下,方便后面进行整体旋转。

四个quad节点的坐标分别是:前(0,0,0.5),右(0.5,0,0),后(0,0,-0.5),左(-0.5,0,0)

(图一:立方体拼凑示意)

页面就是普通的渲染节点。不用scrollview做页面滚动,之后统一用屏幕操作来处理。

页面没有铺满屏幕,在上方空出了导航栏的空间。

(图二:页面布局示意)

canvas的宽度尺寸是750,写有内容的页面的宽度是600(后面用pageWidth表示),居中。

屏幕宽适配,页面距离canvas顶部始终是250(后面用top表示) ,距离底部始终是60(后面用bottom表示) 。

页面节点加了mask组件所以只显示了一部分内容。

透视摄像机参数调整

做3d项目,首当其冲的是透视摄像机的引入。需要先了解它的各项参数的意思,才好完成一些3d功能。

我想实现的是:调整主摄像机的参数,可以让立方体的前quad模型在页面上呈现和“图二”一样的尺寸效果。

主要是调整主摄像机的位置坐标和fov值。(我想保持立方体不动)

x坐标影响quad左右显示,因为页面左右对称,所以x坐标为0 。

y坐标影响quad上下显示,值越大,页面越靠下。

y的值可以直接由:(top-bottom)/(2*pageWidth)得到。这里是:(250-60)/(2*600)=0.1583333

z坐标影响quad两边的空间,值越大,离quad越远,页面显示越小。

摄像机距离立方体距离和fov的大概关系如下:

(因为用了宽适配,不想fov影响宽度,所以fov axis使用了horizontal)

(图三:透视摄像机距离和fov关系,俯视图)

红色实线代表了前quad模型。宽度是1

绿色实线是近裁剪面。

BC比上AD的大小是:600/750 . 这里用ratio表示

AD尺寸:2*near*tan(fov/2)

可以算出DisZ和Fov的关系是:

DisZ=1/(2*tan(Fov/2)*ratio)

当Fov取60度时,DisZ是:1.0825 。那么主摄像机距离原点就是:1.5825(前quad距离立方体节点0.5)

调整z坐标后的效果如下。

(图四:调整主摄像机z坐标后的效果)

可以看到调整主摄像机的z值后,透视摄像机的前quad模型和正交摄像机的页面宽度保持了一致。

因为设备屏幕宽高比(aspect)不一致,所以quad的高度需要在启动后调节。

适配需求:页面距离canvas顶部始终是250 ,距离底部始终是60 。

quad高度和透视摄像机的关系如下图:

(图五:透视摄像机和立方体前quad的关系,左视图)

其中绿色实线为近裁剪面,红色实线为前quad模型

黄色虚线是xz平面,经过立方体中心。

蓝色虚线是摄像机xz平面,经过近裁剪面中心。

近裁剪面的宽度除以高度等于aspect,这个可以通过屏幕尺寸得到。

在cocos里可以通过camera.aspect得到

通过之前的公式,计算得到红色实线即前quad的高度为:

1/(ratio*aspect)-(top+bottom)/pageWidth

如果基于iphoneSE的屏幕,该值为:1.706666

调整好x,y,z和fov值后的效果:

(图六:调整完摄像机参数后的效果)

可以看到,2d页面和quad已经完全重合了!✌

立方体旋转

我直接监听了input的touchmove事件,然后根据delta来旋转立方体。

旋转的时候,使用到了四元数,四元数又是一个新词,不好理解,

但是cocos做了很好的封装,使用起来很方便。

旋转api用到了Quat.fromAxisAngle函数,代表了基于旋转轴和旋转角度的旋转。

旋转轴很容易确定,因为只是水平方向的旋转,那么就是绕着y轴旋转。即Vec3.UP

旋转角度做了一个限制,就是希望玩家即使从屏幕一侧滑到另一侧,也不会看到背面。

所以,最大旋转角度为90度。每次滑动屏幕距离是deltaX,那么每次的旋转角度是:90*deltaX/屏幕宽度

核心旋转代码是:node.rotate(quat)

设置后效果如下:

(图七:立方体旋转示意)

动图中,文字页面还没有映射到立方体上,所以为各个面加了基础颜色。

图七中的效果,仅是旋转跟随滑动。当松手后,应该需要像pageview那样,根据一个阈值,要么还原,要么旋转到下一个页面。

我使用了tween的方式,在松手后,直接旋转到原角度或者下一个页面的角度。

为了方便,在旋转的时候加了锁,只有tween完成后,才可以进行下一次滑动旋转。

这里还根据需要旋转的角度,算了一下时间,最长0.5秒,最短0.1秒。做一个线性插值。

最后的旋转效果如下:

(图八:立方体旋转示意,带自动旋转)

页面映射

我使用了rendertexture渲染贴图,为立方体的前,右,后,左各面片分别创建了对应的渲染贴图、材质、摄像机。材质绑定对应的渲染贴图。将材质赋值给各quad面片。为每个面设置一个layer。然后让对应的摄像机只拍摄这个layer。将渲染贴图赋值给对应的摄像机。

总之创建了:

4个渲染贴图,4个材质,4个摄像机。

都配置好后的效果如下:

(图九:配置渲染贴图后的效果)

现在会有2个问题:不同屏幕尺寸,内容会变形;内容没有铺满。

只要将各面的摄像机尺寸和主正交摄像机的orthoHeight设置成一样,

将各面的渲染贴图的尺寸设置成(aspect*orthoHeight,orthoHeight)

就能保证屏幕完整映射到立方体各面上。如下:

(图十:页面完整映射到立方体各面)

现在内容还是处于拉伸或者压缩的状态,因为页面的宽高比和屏幕的不一致。

只需要将渲染贴图的材质的tiling offset参数进行调整,

去掉黑色区域就可以还原内容的尺寸比例。

tilingOffset的x,y对应uv的xy缩放,tilingOffset的zw对应uv的xy偏移。

宽度是600/750=0.8;

所以tilingOffset的x设置为0.8 .

x方向应该采样0.1~0.9这个范围。所以将tilingOffset的z设置为0.1。

tilingOffset的y需要用公式:y=(screenHeight-top-bottom)/screenHeight来运算。

w需要用公式:z=top/screenHeight来运算。

最后用

material.setProperty('tilingOffset',new Vec4(0.8,(screenHeight-top-bottom)/screenHeight,0.1,top/screenHeight))  

来设置最终的渲染效果,如下动图所示:

(图十一:对材质进行tilingoffset后的效果)

然后再加上一个背景图

调整一下各个摄像机的参数

主透视摄像机用depth only,priority 设置成最高

页面的正交摄像机用solid color,clear color用半透明白色, priority 设置成中等

主正交摄像机priority设置成最低,用于背景渲染。

将各页面材质的technique设置成1-transparent。

就实现了相对高级一点的效果:

(图十二:添加背景和透明度的效果)

对立方体各面内的页面进行长图滑动和点击

我的做法概要:

在滑动的第一帧,判断是想上下滑,还是想左右滑。

如果判断deltaY大于deltaX,则上下滑动,对当前页面进行content坐标处理。

如果无移动,则对当前页面进行点击处理。

页面点击是利用世界坐标进行的判断。

最后的效果如下:

(图十三:添加滑动和点击的效果)

因为不是3d内容范畴,所以写的比较简单。嘿嘿。

对不同数量的页面进行映射

我用过切换页面的layer,但是这样只能适用至少3个页面的情况。如果只有1、2个就不行了。

所以最后使用了切换摄像机的visibility来实现。

每次旋转结束,判断前,右,后,左四个页面,应该是哪个一。

然后设置摄像机的visibility来对应。

并且因为只有4个面片,所以layer也只需要用到1,2,4,8即可。

去掉一个页面后的效果如下(也是开头的效果)

(图十四:只有3个页面的效果)

END...

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

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

相关文章

C++初阶作业 Vector作业详解

作者:小萌新 专栏:C初阶作业 作者简介:大二学生 希望能和大家一起进步 本篇博客介绍:讲解vecotr学校布置的作业 弥补自己不足的知识点 Vector作业详解Vector的特性及使用题目一 迭代器失效编程一 只出现一次的数字编程二 杨辉三角…

aws eks 部署jupyterhub执行kubectl

资料 https://aws.amazon.com/cn/blogs/china/teach-you-how-to-handle-kubeflow-on-eks-2/https://hub.docker.com/r/jupyterhub/singleuser 在部署kubeflow的过程中意识到在jupyter中能够运行外部指令,如果在其中集成一个kubectl,就可以实现命令的重…

【PowerQuery】Excel 自动刷新PowerQuery连接

Excel集成的PowerQuery提供了数据的手动刷新功能之外,也提供了数据的自动刷新功能。需要注意的是,PowerQuery提供的自动刷新功能是针对连接的,也就是说在PowerQuery自动刷新功能不是全局刷新功能,而是针对连接本身提供。接下来我们来看一下如何实现PowerQuery连接的自动刷新…

封装vue插件并发布到npm详细步骤

前言 平常使用Vue开发时,一个项目中多个地方需要用到的相同组件通常我们会封装为一个公共组件,但是如果项目不同我们也需要这个组件,那就需要复制一份公共组件代码到新项目,一个还好,如果是多个组件,这样就…

Design Compiler工具学习笔记(2)

目录 引言 知识储备 设计 objects 库 objects 命令 对象和属性 实际操作 all_* all_inputs all_outputs all_registers 其他 remove_from_collection list 数组 查看环境变量 设置/取消环境变量 引言 本篇继续学习 DC的基本使用。本篇主要学习 design 和 libr…

spring authorization server 0.3.1 - 默认示例

spring authorization server 0.3.1 - 默认oidc开始1、default-authorizationserver项目1.1、AuthorizationServerConfig.java1.2、DefaultSecurityConfig.java1.3、Jwks.java1.4、KeyGeneratorUtils.java1.5、DefaultAuthorizationServer.java1.6、application.yml2、client项…

使用poi操作excel详解

使用poi操作excel详解1、POI工具介绍2、POI可操作的文件类型3、POI所需依赖4、xls和xlsx的区别5、POI Excel 写 03(xls)和07(xlsx)版本方式6、HSSF和XSSF写大文件的区别6.1、使用HSSF写大文件6.2、使用XSSF写大文件6.3、使用SXSS写大文件1、POI工具介绍 1.1、POI 是用Java编写…

为什么进程切换比线程切换代价大,效率低?【TLB:页表缓存/快表】

参考: 计组复习:cache,虚拟内存,页表与TLB小林coding - 为什么要有虚拟内存? 一、为什么进程切换比线程切换代价大,效率更低? 首先,先给出标题的答案(关键在于进程切换…

CleanMyMac X2023最新版安装图文详解

对于刚刚入手苹果Mac设备的用户来说,什么软件好用、怎样设置能够获得最佳的使用体验等这些问题都需要一步一步摸索,但其实,从懵懂到熟练使用OS X系统的过程是非常有趣的。日前,有网友分享了自己认为在OS X系统下非常好用的软件&am…

免费查题接口系统调用

免费查题接口系统调用 本平台优点: 多题库查题、独立后台、响应速度快、全网平台可查、功能最全! 1.想要给自己的公众号获得查题接口,只需要两步! 2.题库: 查题校园题库:查题校园题库后台(点…

Spring——Bean注入几种方式(放入容器)

Bean注入几种方式1.XML方式注入set方式注入构造方法注入2.注解方式注入ComponentComponentScanConfigurationBeanComponentScanImport3.实现ImportBeanDefinitionRegistrar接口4.实现FactoryBean5.实现BeanDefinitionRegistryPostProcessor1.XML方式注入 在现在这个Springboot…

jsp课程资源网站系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 课程资源网站系统 是一套完善的web设计系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql,使用…

怎么用docker将项目打包成镜像并导出给别人适用 (dockerfile)

前提 你得安装docker,没有安装的可以看看这篇文章 编写dockerfile 这个位置最好和我一样,不然后面打包成镜像可能出问题(找不到jar包) FROM openjdk:8-jdk-slim MAINTAINER JacksonNing COPY /target/iec104-1.0.0-SNAPSHOT.j…

这次把怎么做好一个PPT讲清-演讲篇

《商务演讲与汇报》 一、目标:演讲必须有清晰的目标 演讲:影响他人发生积极的**“改变”** 注意,目标就要设定的影响听众在听完你的演讲后发生积极的改变; 例:5月初向领导做月度工作汇报→→让领导在5月第一周例会…

QGradient(渐变填充)

QGradient(渐变填充) QGradient和QBrush一起使用来指定渐变填充。 Qt支持的填充: 线性渐变(linear gradient),在起点和终点之间插值颜色辐射渐变(radial gradient),在焦点和围绕它的圆的端点之…

2019上半年-2019下半年软件设计师上午题错题总结

2019上半年 30.以下关于极限编程(XP)的最佳实践的叙述中,不正确的是(C )。 A.只处理当前的需求,使设计保持简单 B.编写完程序之后编写测试代码 C.可以按日甚至按小时为客户提供可运行的版本 D.系统最…

【附源码】Python计算机毕业设计水库洪水预报调度系统

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,我…

linux进阶-构建deb软件安装包

Linux软件包的组成:源码包和二进制包。 文件类型保存目录普通程序/usr/binroot权限程序/usr/sbin程序配置文件/etc日志文件/var/log文档文件/usr/share/doc 源码包优点:开源免费、自由裁剪、修改源代码。 源码包缺点:安装步骤繁琐、编译时间…

【信号处理】卡尔曼滤波(Matlab代码实现)

👨‍🎓个人主页:研学社的博客 💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜…

区块链解决方案-最新全套文件

区块链解决方案-最新全套文件一、建设背景区块链的五大场景1、合同存证2、产品防伪溯源3、供应链金融4、住房租赁5、贸易金融业务二、建设架构三、建设方案四、获取 - 区块链全套最新解决方案合集一、建设背景 区块链的五大场景 1、合同存证 传统的合同存证存在着被篡改、删…