【科普向】裸眼3D商业化在即,楼主带你一文弄懂计算机图形学基础

最近估计科技圈可能有大新闻了:以前一直存在于科幻电影中的裸眼3D技术,即将在未来的2-3年内走入市场。楼主应该是最早得到这个消息的人,因为楼主直接负责适用于裸眼3D屏幕的图像渲染程序的开发。昨天,楼主花一天时间,从一个计算机图形学方面的完全小白到写出了自己的第一个渲染引擎(CPU的,效率极低,目前还只能渲染顶点。原因以后会讲到)自此发现:很多计算机学中的高深概念,不过是纸老虎而已。这里就来现学现卖一下,也是抛砖引玉。如果有什么部分不正确或不严谨的,欢迎大佬批评指正。

自己写的渲染流水线镇楼~

楼主 Andy18650  发布于 2019-08-30 21:03:00 +0800 CST  
首先来讲一下本文的目的:
1.表示一下楼主除了写《黑暗森林》以外还干了其他事,为鸽找借口。。。
2.吸引OpenGL和计算机图形学大佬,帮忙优化算法。
3.给大家科普一下我所知道的计算机图形学知识。
(好像蛮自私的。

楼主 Andy18650  发布于 2019-08-30 21:08:00 +0800 CST  
首先,第一部分,裸眼3D的原理。声明一下,这个裸眼3D和全息投影什么的无关,那个技术虽然已经有上百年历史了,还在前期研究中,设备也很贵,楼主高二狗,玩不起。。。但是,我们完全能用很简单,很粗暴的方法实现裸眼3D,成本也远低于一块高级电竞屏。

楼主 Andy18650  发布于 2019-08-30 21:12:00 +0800 CST  
我们以一个问题开始:什么是3D?俩眼睛看到的东西不一样就是3D。当然,人类还有焦距法(通过调节眼睛焦距,看哪个物体是清晰的反推物体距离,拍过照的人都知道),位移法(在人移动时,近处的东西移动快,远处的物体移动慢),尺寸法(近大远小,通过把实际大小与经验中的大小作比较,完全的基于经验和神经网络的“软件算法”),甚至使用前庭等感官确定自己在空间中的位置,然后整体判断。人类生成3D场景的过程,其实就是在糊弄这几个判断方法。其中任何现代电脑生成的三维场景都可以糊弄位移法和尺寸法,否则产生不了任何真实感。焦距法可以通过与本文及其类似的技术糊弄,但是要求高至少两个数量即的精度。而如果想要糊弄混合感官,那就不仅仅是光学设备的问题了,就接近《刀剑神域》或《黑客帝国》中的神经连接技术了。

楼主 Andy18650  发布于 2019-08-30 21:26:00 +0800 CST  
现在3D技术最主要的,就是糊弄这个双目视觉。就是要让两个眼睛看到的东西不一样。怎么做到?最一般的想法就是:上俩屏幕,一个眼睛一个。可是,大脑是很狡猾的,通过聚焦分析和逻辑判断,很容易知道“这里有个用心不良的人在用两块屏幕糊弄我”。因为眼睛同时看到了两个屏幕嘛!但是这样的尝试不是没有,就是所谓的“斗鸡眼3D”:把屏幕切开,显示两个视角的图像,然后override大脑的判断,强行把眼睛拉开,这样视角中就会出现四个屏幕,然后想办法把中间两个对起来,形成三个屏幕,然后再对焦,就完成了。



楼主 Andy18650  发布于 2019-08-30 21:40:00 +0800 CST  
所以,与其叫它“斗鸡眼3D”,不如叫“发散眼3D”,但是可能大家叫习惯了,就这么着了。
这个过程听上去简单,实际上要很多的训练,稍不留神就会回到四个屏幕的状态,用户体验极差。而且最难的一步在重新对焦的环节,因为大脑会持续认为对焦的距离和“对眼测距”的距离不一样,从而不断地调整。这就是所谓"辐辏冲突”。

楼主 Andy18650  发布于 2019-08-30 21:45:00 +0800 CST  
为了解决这一问题,有人想到了:那把屏幕移到离眼睛非常近的地方,然后中间加一块隔板,眼睛不就不能看到两个屏幕了吗?
其实,这个方法糊弄的实际上是大脑的逻辑判断方面,就是不需要麻烦的对眼了,其他还真没什么改变。辐辏冲突照样来,还有一个新问题:眼睛无法对焦过近的物体。

楼主 Andy18650  发布于 2019-08-30 21:52:00 +0800 CST  
看不清好办,近视眼不就看清了?问题是不能让全世界人民一夜间变成近视眼啊。那。。。怎么办?很简单!把正常人当成老花眼(远视),然后戴上老花眼镜(凸透镜),加个罩子就是现在的VR了,没别的。

楼主 Andy18650  发布于 2019-08-30 21:57:00 +0800 CST  
VR就讲完了(话说这不是重点的部分就讲了这么多),成就达成:自嗨。
现在问题来了,如果不是自嗨,而是几十上百人的大阵仗的话,以上原理就统统行不通了。因为VR要求屏幕与人眼距离很近,总不能每个人发一个VR吧?那和这些人在家自嗨有什么区别?当然,斗鸡眼理论上是可以的,只要你找得到几十个人跟你一起斗上两个小时。

楼主 Andy18650  发布于 2019-08-30 22:02:00 +0800 CST  
有人吗?感觉在用贴吧单机版。。。

楼主 Andy18650  发布于 2019-08-30 22:04:00 +0800 CST  
所以,3D电影上场了,首先是最老的红蓝眼镜,使用的是牛顿老爷爷的理论(色光理论)红色光透不过蓝色镜片,反之亦然,但是要在大脑中把红蓝的场景混合成原来的颜色,简直比斗鸡眼还要难。
于是就有了偏振眼镜。这玩意很神奇,看起来看上去是灰色的,戴上就能3D。关键在于,光线不仅分颜色,亮度,还有一个“方向”。“竖着”的光通不过“横着”的镜片,“横着”的光透不过“竖着”的镜片(倾斜45°的呢?是(cos45°)^2=0.5就是一半亮度,再讲下去就是量子物理了),而人眼对于光线的“方向”没什么概念,都是一样感觉,只区分亮度和光谱。就这样,用两台投影仪,一台用“横光”投左眼,一台用“竖光”投右眼,然后人戴上不同镜片的眼镜就可以了。问题在于,这货的3D效果不强,反正楼主每次去电影院戴这玩意主要是为了消除重影。然而楼主又有近视加散光,两个眼睛同时戴不下,所以经常要在“这种重影”和“那种重影”之间选择。

楼主 Andy18650  发布于 2019-08-30 22:17:00 +0800 CST  
而这次的裸眼3D,要求是“裸眼”,就是不能有VR头显,不能有红蓝或偏振眼镜,不能有两个屏幕。
那么我们来梳理一下,这个技术“要”什么。

楼主 Andy18650  发布于 2019-08-30 22:22:00 +0800 CST  
首先,“要”一个屏幕。如果屏幕多余一个,那么势必涉及到多个屏幕的合成,这只能使用技术(眼镜)或技巧(斗鸡眼)手段来完成。
其次,“要”显示不同视角。假设我们要显示屏幕后面的一个红绿色的盒子,那么点A势必要向两个方向发出颜色不一样的光线。问题就来了,无论是CRT(阴极射线管),TFT(薄膜晶体管),LCD(液晶显示),LED(发光二极管),OLED(有机发光二极管),LTPS(低温多晶硅),QD(量子点),无论名字多么高深莫测,无论缩写多么酷炫狂拽,它们没有一个可以向不同方向发射不同的光线!


楼主 Andy18650  发布于 2019-08-30 22:37:00 +0800 CST  
怎么办?凉拌!这是硬件问题,没办法解决,但是——有办法变通。
大家还记得初中学过的凸透镜成像吗?在物距等于一倍焦距的时候,光线无法汇聚,会形成一条光柱。

(相信中考过的吧友都经历过被这张图支配的恐惧。。。)
剩下的事情就很简单粗暴了,将这张图逆时针旋转90°,然后缩小,再缩小,每一根。。。bi——,就成了18楼的图片了。

楼主 Andy18650  发布于 2019-08-30 22:52:00 +0800 CST  
所以,所谓裸眼3D的原理,就是用很多像素替代一个像素,分管不同的方向。一个显著的问题就是分辨率会减低,有办法解决吗?有!上4K!(对,就是这样)像素多了,自然就可以分多一点。另一个办法就是减少每个“大像素”背后的“小像素”数量,也就是说,减少视角的数量。最后,经测试,分辨率可以接受而又有裸眼3D效果的最小视角数为16个每方向,这样就需要256个“小像素”才能“撑起”一个“大像素”。不过既然人眼是横着看东西的,那么纵向上的视角分布。。。要不就省了吧。最后,第一批商业化准备的裸眼3D采用了横向16视角,不过使用的不是凸透镜,而是稍微“黑科技”一点的纳米光栅。

楼主 Andy18650  发布于 2019-08-30 23:06:00 +0800 CST  
然后,还有一个小问题,即如果使用21楼的光学结构,就需要横向的16个像素合成一个,纵向的不变,那么4K的3840*2160分辨率就会变成240*2160,由16:9变成1:9,图像完全走样。(好像也不是什么小问题。。。)对此,苏大维格拿出了黑科技:把4*4的小像素合成一个大像素,而排列仍然是只有横向。看来这就是纳米光栅的好处:可以任意调戏光线(修改方向)。

楼主 Andy18650  发布于 2019-08-30 23:22:00 +0800 CST  
接下来就是本文的重头戏:如何渲染为纳米光栅结构准备的特殊图像。因为这个过程等价于渲染16张960*540的图像,然后把它们“打散”放在一3840*2160的屏幕上。
原本,OpenGL是有完整的渲染流水线的,我只需要把模型、材质贴图,法线等等数据以VAO(顶点数组对象)和VBO(顶点缓冲对象)的方式一股脑扔给OpenGL,它就会帮我算,我还能告诉它怎么算,用shader(着色器语言)实现光照,纹理甚至简单的反射。所以,我最初的想法是非常美好的:我再我现有的《黑暗森林》的基础上,把shader改掉——由于shader拥有渲染一幅裸眼3D图像所需要的所有信息:模型位置,大小,形状,视角位置,角度(顶多多几个角度)等等——我就可以把最后的图像渲染成符合裸眼3D的。可是,梦想很美满,现实很凄惨:再Fragment shader阶段,其sampler2D不支持根据屏幕像素FragCoods的位置对不同的模型材质进行采样。加上我对GLSL的理解不够充分,一改代码就是无法compile(编译)所以,楼主迫不得已去补课了全套的3D渲染流水线,收获还是颇丰的。

楼主 Andy18650  发布于 2019-08-30 23:40:00 +0800 CST  
顺便求OpenGL方面的大佬帮忙看一下有没有什么办法实现我原来的设想(用shader)因为现在的CPU渲染效率太低了,要是4K分辨率渲染八个顶点(还没贴图)一个视角就把我的9700k单核吃满。原来打算16线程每个渲染一个视角,至少支持100个三角形,现在看来这要求是要把我的9700k废掉而且帧率还低于一帧每秒。。。

楼主 Andy18650  发布于 2019-08-30 23:44:00 +0800 CST  
明天上午,正课开始~

楼主 Andy18650  发布于 2019-08-30 23:45:00 +0800 CST  
首先,渲染流程的开端是模型坐标系,也就是建模时候用的坐标系。这个很好理解,选取一个原点,然后就能用三维坐标表示模型的每一个顶点,再按照一定的顺序连接起来形成边,再围成面,再围成体,一个模型就完成了。

楼主 Andy18650  发布于 2019-08-31 10:56:00 +0800 CST  

楼主:Andy18650

字数:6222

发表时间:2019-08-31 05:03:00 +0800 CST

更新时间:2019-09-11 22:14:27 +0800 CST

评论数:67条评论

帖子来源:百度贴吧  访问原帖

 

热门帖子

随机列表

大家在看