Unity3D实现3D立体游戏原理及过程

183 0 0
    下面的教程是我今天整理的资料,教大家一步步完成自己的3D立体游戏,并向大家介绍一些3D成像的原理。
    理论上,每个普通的非立体3d游戏,都可以改为3D立体游戏,看完这篇帖子,你们都可以把自己之前做过的3D游戏改为立体游戏,那效果。。。
   一直想尝试用unity做3D立体游戏,昨天终于入手了一台3D显示器,并成功模拟出3D信号,出现了3D效果:
    带上眼镜后的观看效果不错,个人感觉比一般的3D电影的立体效果还要强。

    第一步:了解偏振式3D成像原理
    偏振式3D成像是根据人眼成像原理发明的,人眼看到的景象呈现立体感,是由于双眼所观察到的景象有略微的差别,因为瞳距(两眼球之间的距离)导致观察的物体的角度不同。
    所谓偏振成像就是将两幅不同偏振态的图像送到双眼,每只眼睛只允许看到其中一幅,我们用unity制作3D游戏,其实就是制作这两幅图像。或者说模拟3D信号。
 
    第二步:了解现在的硬件技术能帮我们做什么,我们需要做什么
    在3D显示器出现之前,我们要做3D立体游戏,估计只能用两台投影仪来实现3D效果了,不过现在的3D液晶显示器大多都是集成好一键转3D功能,在这里这个转3D功能指的是自动识别左右半宽的信号(上下的就不考虑了,一般都是左右),并将其融合,转换为偏振的3D信号,并通过3D眼镜观看到3D效果。当然现在的3D显示器经常会宣传说一键2D转3D功能,这个功能不是我刚才说的融合,而是显示器根据2D影像自动给加上景深,生成左右两幅图像,其实是伪3D,试了一下,的确略微有些效果,不过效果真的不怎么样。。。我们这里还是做真的3D立体吧。
    知道了显示器能够帮我们自动融合左右图像后,我们就只需要模拟出左右半宽的图像就OK了
 
    第三步:如何用Unity3D模拟出3D信号
    这步才是我们要做的重点。要模拟出真实的3D立体影像,首先要知道人眼成像原理,上面第一步说了,因为我们有两只眼睛,并分开一定距离(大约150px),这样就出现了距离感。我们都知道unity中的摄像机是模拟人的眼睛的,一般我们在unity中观察场景都是创建一个摄像机,当然就没有立体感了,要模拟人的眼睛,就要创建两个摄像机(好吧,废话一大堆,其实我就是想说,请先创建两个摄像机。。。)。
    把场景本来存在的主相机删掉,把创建的两个摄像机放在同一平面,分开很小的距离,角度调成一样,注意不是往中间看,而是平视,人的双眼也都是平视向前的,这个和焦距是两个概念,别弄混了,类似于下面这样:

    至于相距多少,这个视环境而定,两个摄像机之间的距离类似于人眼之间的距离。我们用自带的第一人称控制器来解释这个距离。导入第一人称控制,把这两个摄像机拖到第一人称控制器的摄像机下,作为子物体,把第一人称控制自带的相机关掉(enabled=false),就是把camera组件对号去掉。把左右相机的位置改为这样:
    左相机:

    右相机:

    对于第一人称控制器的大小来说,这个0.06的距离够用了,为什么说是够用了,不是正好,是因为距离大点小点都是可以的,距离越大,景深越大,看起来更清晰,好像是距离拉近了,不过给人观看的感觉更累了,这个很好理解,人的眼睛距离变大,就相当于人变成了巨人,或者眼前的景象拉近,也就是你把手指从远处拉到眼前的感觉,当近到一定程度是,你要看你的手指就会很吃力,要不就重影~~再近,就是斗鸡眼了,斗鸡眼的感觉,你懂的。。。
    如果距离拉近的话,3D感会渐渐变弱,最近就是两个相机重合,重合后就没有立体感了。所以这个距离要根据你看的场景而定,对于自带的第一人称控制器,它的大小作为人的大小的话,它所存在的场景比例就是固定的,此时的瞳距根据你想要的效果而定,具体可以在显示器上测试。
    当两个摄像机的距离固定后,怎么把影像分开呢?因为我们用3d显示器来融合,就不需要考虑unity的融合图像部分,只需要把两个相机的影像分为左右半宽同时输出即可。要达到这样的效果,用RenderTexture是个很好的解决方案,我们新建两个RenderTexture,分别用来显示左右两个相机的视野:

    把新建的两个RenderTexture放到plane上,并排放到一起,并新建一个垂直摄像机来单独显示这两个RenderTexture,这个摄像机也是我们最后看到的画面所使用的相机。所以它的depth要设置的高一点。

    关于RenderTexture,我们需要稍微调整一下,size改为2048*1024,注意不要改为2048*2048,即使这样会更加清晰,但是会出现显示不全的情况。注意,此时这两个plane的scale大小只有设为2:1的比例才不会出现图像变形,也就是说plane的大小要和RenderTexture的比例一样才会显示正常比例内容,但是我们需要的并不是正常比例,只要融合后是正常比例既可,显示器的融合功能是将左右部分先放大到整个屏幕,再进行偏振融合,所以我们要的3d信号是压缩一半之后的两个影像,所以降2:1的比例压缩后就成了1:1.也就是plane的大小还是1:1的方形,这样在融合后才不会出现比例失真的情况。
    大多数的3D显示器的屏幕比例都是1920*1080,也就是16:9,现在的3D视频分辨率大多也是这个比例,这样在全屏的时候就不会变形或者出现黑边,我们玩游戏全屏不失真的话,也要按这个比例(16:9),当然不全屏的话也是看不了3D的,因为左右半宽的窗体无法融合,3D显示器也不认识这样的3D信号。
    再回到上面说的RenderTexture的大小(分辨率)问题上来,假如选择了2048*2048,而game窗口比例又是16:9,unity的RenderTexture为了显示1:1的比例,就把摄像机中间部分显示出来,两侧内容裁减掉了,造成视野缺失,所以要选择size为2048*1024,不过这样又出新的问题,Game窗口是16:9,也就是摄像机视野比例是16:9,比2048*1024,也就是2:1的比例要小,造成RenderTexture两侧多显示了一部分,这部分是左右相机视野中没有的部分,必须要去掉的。去掉的方法其实很简单,通过更改材质的UV值即可,也就是让这两个RenderTexture,显示的影像往中间偏移,偏移的量,通过计算可以算出为0.05555…,我们改变UV偏移:

    由于我们的摄像机视野时16:9,所以附有RenderTexture的plane的两侧内容并不在我们的视野内,这样主相机的显示影像只有左右相机的视野影像,不会有其他的内容.

    到这里,我们在unity中要做的3D方面的操作已经差不多了,剩下的内容就是我们做普通游戏的流程,只要把我们曾经用的相机改为上面做的两个相机即可,我们可以把这两个相机连它们的父物体导出一个预制体,看向RenderTexture主相机和两个附有RenderTexture的plane导出另一个预制体,这两个预制体导出包package,这个package包就是一个转3D立体游戏的插件了,要转化哪个游戏为立体游戏,就把这个包导入,把两个预制体拖进场景,把相机替换为左右两个相机,然后导出游戏就是3d立体游戏了。
    将导出的游戏(exe)打开,电脑要连好3D显示器,这样在选择比例的时候才有1920*1080, Windowed的对号去掉,保证是全屏,导出设置里面也有默认全屏,

    打开后,将显示器改为3D模式,3D显示器一般都有按键在下面或者侧面,有转换3D的功能键,打开后,带上眼镜就可以体验3D立体效果了!

    最终搞出来的效果:

    注:假如感觉立体效果不明显,就把两个相机的距离拉开一点.

Unity3D实现3D立体游戏原理及过程的更多相关文章

  1. Unity3D实现3D立体游戏原理及过程,需偏振眼镜3D显

    http://tieba.baidu.com/p/3038509618?fr=ala0&pstaala=3

  2. 【Unity3d】3d网页游戏场景打包与加载

    http://www.cnblogs.com/dosomething/archive/2012/04/07/2436353.html 3d游戏中  一个场景往往比较大  如果游戏的进行需要下载一个10 ...

  3. 3D立体显示技术原理与游戏应用历程简介 【转】

    本文来自 中关村ZOL 「3D 立体显示」可说是近来娱乐产业相当热门的话题,不但有好莱坞推出<阿凡达>等卖座 3D 立体电影,全球各大家电厂商也积极布局准备推出一系列支持 3D 立体显示的 ...

  4. Unity3D 之3D游戏入门Hello world(一)

    这几天开始玩Unity3D 有关3D的内容了,去年开始玩过一段时间的2D制作,不过因为年初找工作,所以放了一段时间, 现在再捡起来发现忘的已经差不多了,只能再从头开始,所以就从3D开始算了.下面是3D ...

  5. 【Unity3d】3d角色换装实现原理及步骤

    http://www.cnblogs.com/dosomething/archive/2012/04/15/2450526.html 1.角色模型制作 unity3d支持Skin动画  但是不支持Ph ...

  6. 用webgl打造自己的3D迷宫游戏

    用webgl打造自己的3D迷宫游戏 2016/09/19 · JavaScript · WebGL 原文出处: AlloyTeam    背景:前段时间自己居然迷路了,有感而发就想到写一个可以让人迷路 ...

  7. 裸眼3D立体显示技术原理详解

    众所周知,现实世界是一个三维空间,除去时间这一维度,现实世界是由长度.宽度和高度三个维度组成,我们每天就生活在这个三维世界中,而现有的显示设备大多数都只能显示二维信息,并不能带给人真实的三维感觉.为了 ...

  8. 【Unity3D】3D角色换装++ Advance

    http://www.cnblogs.com/dosomething/archive/2012/12/15/2818897.html 本文在之前的文章Unity3D角色换装的原理 基础上做一个补充 给 ...

  9. 3D重建算法原理

    3D重建算法原理 三维重建(3D Reconstruction)技术一直是计算机图形学和计算机视觉领域的一个热点课题.早期的三维重建技术通常以二维图像作为输入,重建出场景中的三维模型.但是,受限于输入 ...

随机推荐

  1. Maven学习(四)-----Maven中央存储库

    Maven中央存储库 当你建立一个 Maven 的项目,Maven 会检查你的 pom.xml 文件,以确定哪些依赖下载.首先,Maven 将从本地资源库获得 Maven 的本地资源库依赖资源,如果没 ...

  2. 集群服务器、负载均衡和session共享,C#的static变量

    集群服务器:是指由两台以上服务器共同组成的服务器,目的是为了提高性能. 负载均衡:是基于集群服务器实现的,作用是当A服务器访问数达到一定上限时,接下来客户端的请求会自动分配给B服务器,目的是减少服务器 ...

  3. NES像素风格的Raspberry

    周末小实践,vue+树莓派+一言API 一直有个想法,让树莓派做后端,实现一个有趣的网络服务.可是,苦于不会前端,迟迟无法动手.最近由于工作任务需要研究了一下前端. 问过前端大佬们,个个都说你得用vu ...

  4. spring-boot 项目整合logback

    使用spring-boot项目中添加日志输出,java的日志输出一共有两个大的方案log4j/log4j2 ,logback.log4j2算是对log4j的一个升级版本. 常规做法是引入slf4j作为 ...

  5. java运行时内存分类

    主要有java栈(虚拟机栈), 堆 ,方法区. 线程私有: 栈: 每个方法执行的时候 都会同时创建一个栈桢 Stack Frame 用于存储  局部变量表, 操作数栈,动态链接, 方法出口等信息 线程 ...

  6. C++ STL 优先队列 priority_queue 详解(转)

    转自https://blog.csdn.net/c20182030/article/details/70757660,感谢大佬. 优先队列 引入 优先队列是一种特殊的队列,在学习堆排序的时候就有所了解 ...

  7. 20181023-10 Alpha阶段第2周/共2周 Scrum立会报告+燃尽图 07

    作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2290 Scrum master:范靖旋 一.小组介绍 组长:王一可 组员: ...

  8. 【Alpha】阶段第二次Scrum Meeting

    [Alpha]阶段第二次Scrum Meeting 工作情况 团队成员 今日已完成任务 明日待完成任务 刘峻辰 发表评论接口 更新评论接口 赵智源 部署实际项目 编写脚本实现持续集成 肖萌威 编写注册 ...

  9. oracle selinux 问题

    Error: cannot restore segment prot after reloc: Permission Denied http://www.oracledistilled.com/ora ...

  10. OpenCV学习笔记——imread、imwrite以及imshow

    1.imread Loads an image from a file. 从文件中读取图像. C++: Mat imread(const string& filename, int flags ...