基于HTML5的WebGL经典3D虚拟机房漫游动画


Posted in HTML / CSS onNovember 15, 2017

第一人称在 3D 中的用法要参考第一人称在射击游戏中的使用,第一人称射击游戏(FPS)是以第一人称视角为中心围绕枪和其他武器为基础的视频游戏类型;也就是说,玩家通过主角的眼睛来体验动作。自从流派开始以来,先进的3D和伪 3D图形已经对硬件发展提出了挑战,而多人游戏已经不可或缺。

基于HTML5的WebGL经典3D虚拟机房漫游动画

Doom的截图,这个流派的突破游戏之一,展示了第一人称射击游戏的典型视角

现在博物馆或者公司也经常使用到 3D 动画做宣传片等等,3D动画演绎最大的优势,便是在于内容与形式上给人的真实感受。它比平面作品更直观,比 2D 动画更真实,所以更能给观赏者以置身于广告环境当中的感受,大大增强广告的说服力。3D 技术的发展甚至挑战受众的分辨能力,使受众的判断游离于与虚拟和现实之间。
而且 3D特效的应用为创意提供了更加广阔的思维空间,并成为创意执行的可靠保证,并丰富了创意的形式和风格手段。根据广告主题的表现诉求,可以营造出梦幻般的神奇氛围来刺激打动受众,从而起到与受众沟通的目的。
3D动画宣传片将 3D动画、特效镜头、企业视频、照片、未来前景等内容通过后期合成、配音、解说形成一部直观、生动、喜闻乐见的高品位的企业广告宣传片,让社会不同层面的人士对企业产生正面的、积极的、良好的印象,从而建立对企业的好感与信任,并信赖该企业的产品或服务。

现在 3D 发展地如此迅速也要感谢人类对于“现实”的追求,所以学好用好 3D 是未来成功必不可少的一部分。

本文例子的思路是进入一个机房参观,打开门的动作是再生动不过了, 再加上适当地转弯,基本上完全模拟了人在机房中参观的效果。还有一个好处就是,如果要演示给领导看而又不用操作,这种炫酷的效果领导一定会很满意!

http://www.hightopo.com/demo/room-walkthrough/index.html

基于HTML5的WebGL经典3D虚拟机房漫游动画

界面上的“reset”和“start”两个按钮是直接加在 body 体中的 button,并在这两个按钮上添加点击事件:

<div></div><div></div>

整个场景由 HT 封装的 3D 组件搭建形成的,构造这么大的场景是需要一定量的代码的,为了简化,我把场景单独拿出来,并用 HT 封装的 ht.JSONSerializer 类将场景序列化为 json,代码中只引入了生成后的 json 文件,为了让大家更明确,我这边做个示例,假设已经搭建好 3D 场景了:

dm = new ht.DataModel();g3d = new ht.graph3d.Graph3dView(dm);//.......构建好场景dm.serialize();//可以填入number参数,作为空格缩进值

既然我们已经搭建好环境,转成了 json 文件,代码中不好控制,这种情况下我们会将 DataModel 数据模型再反序列化,这个函数的功能就是将 json 格式转成对象,并将反序列化的对象传入到 DataModel 数据模型中,详情请参考HT for Web 序列化手册:

var g3d = window.g3d = new ht.graph3d.Graph3dView(),    
dataModel = g3d.dm(),    
view = g3d.getView(),    
path = null;g3d.setMovableFunc(function(data) {    return false;});
g3d.setVisibleFunc(function(data) {    
if (data.getName() === "path") {       
 return false;    
}    
return true;});
g3d.setEye([523, 5600, 8165]);g3d.setFar(60000);dataModel.deserialize(json);

我们目前需要操作场景中的“门”、以及我们将要走的路线“path”,遍历 DataModel 数据模型,获取这两个数据:

for (var i = 0; i < dataModel.size(); i++) {    
var data = dataModel.getDatas().get(i);   
 if (data.getName() === "门") 
{//json中设置的名称       
window.door = data;    
}    
if (data.getName() === "path") 
{        
path = data;    
}    
if (window.door && path) 
{//获取到door 和 path 的data之后就跳出循环        
break;   
 }}

这个例子中简单来说就只有四个动作,“重置”回到原点、“开始动作”、“向前移动”,“停止”。点击“开始”按钮,在“开始动作”中我们只做了一个动作,“开门”动作,动作结束之后调用“forward”函数向前移动:

function startAnim() {
   
if (window.isAnimationRunning) 
{        
return;   
 }    
reset();    
window.isAnimationRunning = true;//动画是否正在进行    ht.Default.startAnim({       
 frames: 30, // 动画帧数,默认采用`ht.Default.animFrames`。        
interval: 20, // 动画帧间隔,默认采用`ht.Default.animInterval`。           
finishFunc: function() {// 动画结束后调用的函数。            
forward();        
},         
action: function(t){ // action函数必须提供,实现动画过程中的属性变化。            
door.setRotationY(-120 * Math.PI / 180 * t);        
}    
});
}

这边的“reset”函数就是“重置”回到原点的功能,我们通过这个函数将所有变化过的都恢复初始的位置,包括“门”的位置:

function reset() 
{    
if (window.isAnimationRunning) 
{        
return;    
}    
g3d.setCenter([0,0,0]);    
g3d.setEye([523, 5600, 8165]);    window.forwardIndex = 0;   
 door.setRotationY(0);}

要“移动”,肯定需要走路的“路径”,也就是我们刚刚获取到的“path”,通过window.points = path.getPoints()._as; 获取“path”中的所有元素,初始化window.forwardIndex = 0; 通过控制“path”中前后两点来设置 3D 场景中的 Eye 和 Center,这样就能营造一个我们是第一人的效果:

var point1 = points[forwardIndex],    
 point2 = points[forwardIndex + 1];var distanceX = (point2.x - point1.x),     
distanceY = (point2.y - point1.y),     
distance = Math.sqrt(distanceX * distanceX + distanceY * distanceY)-200;//两点之间的距离通过三角形勾股定理计算 怕碰墙所以-200g3d.setEye([point1.x, 1600, point1.y]);//眼睛g3d.setCenter([point2.x, 1600, point2.y]);//我

HT 中 3D 组件有一个 walk(step, anim, firstPersonMode)方法,该函数同时改变eye和center的位置,也就是eye和center在两点建立的矢量方向上同时移动相同的偏移量。step为偏移的矢量长度值。firstPersonMode参数为空时则默认采用Graph3dView#isFirstPersonMode()当前值, 如果为第一人称模式调用walk操作,该函数会考虑Graph3dView#getBoundaries()边界限制。

g3d.walk(distance, {    
frames: 50,    
interval: 30,    
easing: function(t) {return t; },    
finishFunc: function() {        
forwardIndex += 1;        
if (points.length - 2 > forwardIndex) {//points.length = 5            g3d.setCenter([point2.x, 1600, point2.y]);//把结束点变成起始点            
g3d.rotate(Math.PI / 2, 0, {               
 frames: 30,              
  interval: 30,               
 easing: function(t) {return t;},                finishFunc:function() { forward();}           
 });      
  } 
else 
{            
var lastPoint = points[points.length  - 1];//json 中path的points 的最后一个点           
 g3d.setCenter([lastPoint.x, 1400, lastPoint.y]);            
g3d.rotate(-Math.PI / 2, 0, 
{               
 frames: 30,               
 interval: 30,               
 finishFunc: function() 
{                    
window.isAnimationRunning = false;               
 }           
 });       
 }    
}});

不管“path”的点有多少个,这个判断语句还是能运作,只在最后一个点是跳出 finishFunc 动画结束后调用的函数,并将 window.isAnimationRunning 值设为 false 停止 startAnim 函数。如果不是最后一个点,用户“旋转”之后,回调 forward 函数。至此,全部代码解释完毕,很短的代码量,却做出了这么大的工程!

总结

以上所述是小编给大家介绍的基于HTML5的WebGL经典3D虚拟机房漫游动画,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

HTML / CSS 相关文章推荐
让IE6、IE7、IE8支持CSS3的脚本
Jul 20 HTML / CSS
非常震撼的纯CSS3人物行走动画
Feb 24 HTML / CSS
html5视频播放_动力节点Java学院整理
Jul 13 HTML / CSS
HTML5中新标签和常用标签详解
Mar 07 HTML / CSS
为你的html5网页添加音效示例
Apr 03 HTML / CSS
html5使用canvas绘制文字特效
Dec 15 HTML / CSS
HTML5中Localstorage的使用教程
Jul 09 HTML / CSS
html5组织内容_动力节点Java学院整理
Jul 10 HTML / CSS
基于MUI框架使用HTML5实现的二维码扫描功能
Mar 01 HTML / CSS
前端实现打印图像功能
Aug 27 HTML / CSS
canvas实现手机的手势解锁的步骤详细
Mar 16 HTML / CSS
Html5饼图绘制实现统计图的方法
Aug 05 HTML / CSS
Adobe Html5 Extension开发初体验图文教程
Nov 14 #HTML / CSS
html5中canvas图表实现柱状图的示例
Nov 13 #HTML / CSS
有关HTML5页面在iPhoneX适配问题
Nov 13 #HTML / CSS
浅谈HTML5 FileReader分布读取文件以及其方法简介
Nov 09 #HTML / CSS
如何避免常见的6种HTML5错误用法
Nov 06 #HTML / CSS
HTML5添加禁止缩放功能
Nov 03 #HTML / CSS
基于HTML5 Canvas的3D动态Chart图表的示例
Nov 02 #HTML / CSS
You might like
php 无法加载mysql的module的时候的配置的解决方案引发的思考
2012/01/27 PHP
php实现阿拉伯数字和罗马数字相互转换的方法
2015/04/17 PHP
PHP实现git部署的方法教程
2017/12/19 PHP
javascript json 新手入门文档
2009/12/03 Javascript
解决ExtJS在chrome或火狐中正常显示在ie中不显示的浏览器兼容问题
2013/01/11 Javascript
JavaScript-RegExp对象只能使用一次问题解决方法
2014/06/23 Javascript
Javascript核心读书有感之语言核心
2015/02/01 Javascript
使用AngularJS对路由进行安全性处理的方法
2015/06/18 Javascript
JavaScript运动减速效果实例分析
2015/08/04 Javascript
iScroll.js 使用方法参考
2016/05/16 Javascript
使用jquery获取url以及jquery获取url参数的实现方法
2016/05/25 Javascript
AngularJS 表达式详解及实例代码
2016/09/14 Javascript
jQuery验证表单格式的使用方法
2017/01/10 Javascript
Angular5中提取公共组件之radio list的实例代码
2018/07/10 Javascript
python的迭代器与生成器实例详解
2014/07/16 Python
利用Hyperic调用Python实现进程守护
2018/01/02 Python
分数霸榜! python助你微信跳一跳拿高分
2018/01/08 Python
flask中的wtforms使用方法
2018/07/21 Python
Python 中 function(#) (X)格式 和 (#)在Python3.*中的注意事项
2018/11/30 Python
pytorch获取模型某一层参数名及参数值方式
2019/12/30 Python
python求解汉诺塔游戏
2020/07/09 Python
浅析python 通⽤爬⾍和聚焦爬⾍
2020/09/28 Python
用Python自动清理系统垃圾的实现
2021/01/18 Python
CSS3 flex布局之快速实现BorderLayout布局
2015/12/03 HTML / CSS
德国机车企业:FC-Moto
2017/10/27 全球购物
Vertbaudet西班牙网上商店:婴儿服装、童装、母婴用品和儿童家具
2019/10/16 全球购物
德国家具、照明、家居用品网上商店:Wayfair.de
2020/02/13 全球购物
MyBag中文网:英国著名的时尚包袋电商零售网站
2020/07/31 全球购物
控制工程专业个人求职信
2013/09/25 职场文书
2014年五四青年节活动方案
2014/03/29 职场文书
公司员工活动策划方案
2014/08/20 职场文书
党员检讨书范文
2014/12/27 职场文书
银行客户经理培训心得体会
2016/01/09 职场文书
2016年“12.3”国际残疾人日活动总结
2016/04/01 职场文书
python如何利用cv2模块读取显示保存图片
2021/06/04 Python
15个值得收藏的JavaScript函数
2021/09/15 Javascript