基于GL Pipeline与光线追踪技术的融合实现的台球模拟器

基于 GL Pipeline 与光线追踪技术的融合实现的台球模拟器

一、Project Title

基于 GL Pipeline 与光线追踪技术的融合实现的台球模拟

二、Abstract

本项目实现了一个台球模拟器。首先我们使用 Box2D 建立了 2 维的物理引擎,算 出了当前所有球体的位置,角度,并通过全局变量与其他模块通讯。之后基于这些 角度和位置,我们首先用光线追踪的方法还原了场景,又用图形流水线的方法还原 了场景。最后,我们将光线追踪计算出的阴影像素值和色彩像素值,作为纹理输 入,通过 fragment shader,与原来仅仅只通过了 Phong Shading 和纹理贴图的 fragment 进行像素融合,得到融合后的图片。本项目充分利用到了本学期所学的 所有知识:三维运动、光照渲染、光线追踪等技术,同时也尝试对不同图形学模拟 方式进行了实现与融合。

三、Motivation

台球运动十分受欢迎,台球类的模拟器并不不常见,但基本都是基于二维平面 贴图的游戏或者模拟器,本组希望实现对台球系统在特定场景下的光线追踪,并使 用 shader 实现一系列特效且与光线追踪的结果相结合,同时编写对应的物理引擎 和框架,实现对台球运动的高还原度的实现。这意味着什么呢,这意味着我们不 仅要从光追的角度去实现这个模拟器,还要从传统流水线的方式进行实现,最后 还需要用到融合算法进行融合。这样做的好处就是能够使用到两者的优点,光线 追踪效果惊艳、真实,而传统图形学流水线已有功能丰富,可以利用 shader 完成 贴图、几何变换、各种特效等功能。此外,我们搭建的是一个完整的模拟系统,这 意味着我们需要完成一个物理引擎和人机交互的部分。

总的来说,本项目难度较大,但也乐趣无穷。但我们分工明确,互相监督,希 望借助图形学课程的锻炼,完成这次 hard core 的项目。

四、The Goal of the project

  • 实现台球系统的物理引擎;
  • 实现人机交互的规则;
  • 实现友好的人机交互界面;
  • 实现球类,吊灯,台球桌和场景的建模;
  • 从 Ray Tracer 的角度实现模拟器渲染,并研究实时算法与代码优化实现;
  • 从传统 GL 流水线的角度实现模拟器渲染,并通过 shader,实现贴图,天空 盒,光晕、景深特效等特效;
  • 将 Ray Tracer 与传统 GL 流水线的结果通过融合,打造更加完美的视觉效果, 同时也是一次两种技术融合的伟大尝试。
    在这里插入图片描述

五、The Scope of the project

我们的光线追踪和特效仅针对台球,吊灯和台球桌面;

我们的台球物理运动场景是 2D 的,但渲染效果是 3D 的;

六、Involved CG techniques

1.光线追踪

  • 渲染方程
  • Monte Carlo 积分与重要性采样
  • 光线求交
  • 基于 Microfacet 理论的 BRDF 模型

2.流水线渲染

  • 纹理贴图
  • 填空盒
  • 纹理混合
  • 景深特效 n 小孔成像 n Accumulation Buffer

3.物理引擎(box2D 实现)

  • 动量定理
  • 能量定理
  • 正碰策略
  • 斜碰策略
  • 摩擦力策略

七、Project contents

项目是一个台球的模拟器,将实现以下功能:

实现台球模拟器的可操作性

对台球实现光追特效

对台球的运动实现实时渲染

八、Implementation

在这里插入图片描述

我们在 BillbardScene 供了游戏场景,声明了 10 个带有物理碰撞检测的 BillbardBall,实时模拟了台球的位置。

游戏采用第一人称实现,并且监听鼠标和键盘来控制了视点和视角,通过判断 视线和台球是否相交来选中台球。关闭了游戏引擎自带的 2D 画面,重载了 BillbardScene 的画面绘制函数 Draw(), 采用 OpenGL 和 ray tracing 结合的方 法,绘制了 3D 画面。

物理引擎

我们使用 cocos2dx-3.17 内置的 Box2D 引擎作为我们的物理引擎。下面将述 我们对物理引擎的使用。

(1)在初始化时,创建 ContactListener,之后每一帧,此容器内将保存着正在 碰撞的对象;

(2)首先使用_world->CreateBody(&bodyDef) 创建了 Box2D(物理引擎)的 场景,然后采用 b2FixtureDef 定义了具有物理特性的 fixtureDef(台球对 象),其中 fixtureDef(台球对象)的形状由 b2CircleShape(台球的初始位 置,台球的初始半径)所述; _

_(3)每一帧,遍历碰撞容器_contactListener,得到所有的碰撞对象 SpriteA 和 SpriteB,分别判断 A 和 B 都是球,A 和 B 一桌一球的情况,然后用 ChangeVehicle 函数,利用动量守恒和能量守恒改写 SpriteA 和 SpriteB 的速度 以及下一帧两者的位置;

(4)每一帧更新台球的位置数据后,将所有台球的位置数据传送给 GPU,这样 GPU 可以根据更新后台球的位置重新绘制台球,这样就实现了台球的移动;台球的旋转 是用一定的“技巧”实现的,GPU 会记录上一帧和此帧台球的位置,并根据这两个 位置信息决定旋转的角度,进行旋转。

光线追踪

这里,我们不会对光线追踪理论的技术细节做过多展开,也不会再对光线追踪理论 的流程及方法做过于宏观的介绍,而是针对于我们实时光线追踪场景的技术难点, 结合实际情景与软硬件条件,对设计的关键技术与概念加以介绍。

渲染方程

对于模型表面上的每个点,我们必须在垂直于该点法线方向的半空间上做积分运算 以便求出该点的颜色值:

在这里插入图片描述

一个表面的亮度是由两个部分组成的,一部分是表面的自发光 ,另一部分是其 他表面的射向该表面的光线经过 BRDF 作用后的结果。

BRDF(Bidirectional Reflectance Distribution Function)即双向反射分布函数。它 的作用是对于我们给定传入方向 ,计算有多少光在任意给定的方向(观察方向) 上散射。 在这一方程的基础上,辐射度方法和蒙特卡罗光线跟踪的方法就可以看成是对方程 中积分的不同的数值求解方法。

注:真正的渲染方程实际上应该包含折射部分的计算(BRDF + BTDF),而我们这 里只考虑反射部分。为了简便计算,我们在实际编程中使用的均为 Blinn-Phong 光 照模型。

Monte Carlo 积分与重要性采样

为了估计某个函数在一个定义域内的积分而在这个定义域内随机地找一些采样点, 计算采样点所在位置的函数值,把所有采样点的函数值平均即可得到该积分的估计 值,这样的方法叫做蒙特卡洛(Monte Carlo)积分。

在这里插入图片描述

对于样本的生成最简单的方法就是直接在积分的定义域内生成均匀分布的随机样 本,但是对于函数值变化平缓的位置这样生成的样本就会过密,而对于函数值变化 剧烈的位置样本数又不足以显示其真实情况。

如果我们先验地知道函数的大致形状,那我们就可以针对性地生成非均匀分布的随 机样本,这样能够在相同样本数量的情况下对目标积分得到一个更准确的估计,这 就是我们常说的重要性采样。

让我们再次观察渲染方程的结构:
在这里插入图片描述

由于对于渲染方程的计算是个递归过程,右侧积分收敛很慢。一个有效的方案就是 使用重要性采样,高采样效率。 注意到右边的积分中有一个因子 ,这意味着可以在半球上进行带有弦函数权 重的概率 来采样。另外还可以对双向反射分布函数 BRDF 进行重 要性采样,或在跟踪足够长的路径后,基于光源位置和 BRDF 同时进行采样,使用 多重重要性采样(MIS)进行混合。

减少采样深度

光线追踪的经典应用场景之一便是多个镜面小球之间的多重镜面反射效果,然而为 实现该效果所付出的代价是巨大的,多重的迭代将迅速升算法复杂度。在我们的 场景中,由于是台球游戏,大多数时候球之间都距离较远,因此不需要过多次迭 代,或过深的采样便可以得到理想的反射效果。基于第三层采样的贡献值很小的假 设,我们将采样深度简化为两层,以高渲染速度。具体而言:

  1. 从视点出发向物体求交
  2. 从交点出发采样其他物体的光线
  3. 与其他物体相交之后直接对光源采样

从而,我们的渲染效果可以表示为:
在这里插入图片描述

减少采样数

采用重要性采样加快收敛。这里,我们使用余弦函数进行重要性采样。 具体而言,对函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

光线求交

在光线追踪过程中,从眼睛发出的光线与 3D 模型的三角面求交是一个复杂问题。 通常精致的 3D 模型可能由几十万至上百万三角面构成,如果采用穷举法求交点, 其时间复杂度将是 O(n), 过于复杂。为了减少不必要的求交检测,应采用空间划分 技术,最常用的是平衡 k-d 树算法,高求交检测的效率。

在这里插入图片描述

在计算机科学里,k-d 树( k-维树的缩写)是在 k 维欧几里德空间组织点的数据结 构。

k-d 树是每个节点都为 k 维点的二叉树。所有非叶子节点可以视作用一个超平面把 空间分割成两个半空间。节点左边的子树代表在超平面左边的点,节点右边的子树 代表在超平面右边的点。

我们尝试了很多用于排除模型的数据结构(如 k-d 树、AABB 包围盒法等),当模 型很少时(例如只有少数台球物体及单点光源的场景),使用多余的数据结构会带 来很大的常数级复杂度,因此我们必须采用常数很小的优化方法,针对具体场景采 取相应的优化方法:
在这里插入图片描述

此时,若 r 大于目前已经求得交点的距离,则即便相交也不会得到更近的交 点。这个优化可以有效减少大部分距离较远的球体求交中的根号运算和除法运算。

软阴影

理想点光源产生的阴影会有锐利而对比分明的阴影,这与实际场景中柔和的阴影效 果相违背。这是由于现实中的光源作为物理实体都具有一定的体积,因此不存在完 美的点光源。 为了模拟软阴影的效果,我们使用 PCS 方法对理想点光源加以随即抖动。具体而 言,我们首先向光源发出射线,与其他物体求交。

在这里插入图片描述

首先,我们在 geometry 这一块的建模,被建模的物体有:

1 球体;

2 围栏;

3 桌面;

其中对于球体的建模,我们将其分割成矩形,然后矩形内部又可以将其划分为 三角形。沿着纬度我们分多个 stacks,沿着经度我们划分了多个 sectors。如下图 (图源为 http://www.songho.ca/opengl/gl_sphere.html)所示:
在这里插入图片描述
在这里插入图片描述

其中对于球类建模的一个小优化就是将顶部和底部的矩形,只画一个三角形。 因为顶部和底部的矩形都有 2 个重合点,故实际上就只需画一个三角形就好。
在这里插入图片描述

具体的话我们建模了 10 个球。

关于球类的运动,直接通过物理引擎计算出当时的旋转矩阵、位移矩阵、投 影矩阵等等,计算得到旋转后球体群。其中瞄准之后球会变纹理,变成显示一个 「AIM」的纹理。

纹理贴图,参数如下:
在这里插入图片描述

景深效应(implemented but not used for performance issue):
在这里插入图片描述

使用 accumulate buffer 可实现这个效果:

原始的 LookAt:glm::LookAt(eye, target, up)

做圆周运动的 LookAt:glm::LookAt(eye + shuffle, target, up)

shuffle = aperture * bokeh glAccum({LOAD/ACCUM}, fraction)

在这里插入图片描述

л

在这里插入图片描述

天空盒(SkyBox)

为了在场景中呈现更好的气氛,加入了一个天空盒特效。在 OpenGL 里有现成的 CubeMap texture 用于实现天空盒。然而悲剧的是,这里用的 cocos2dx 引擎所使 用的 GLSL 版本过于老旧,不支持 CubeMap texture,仅支持 2D texture,所以我 们只能通过手动贴 6 张图的方式实现天空盒了。

实现效果:

在这里插入图片描述

.流水线与光线追踪的融合

目前来说,我们用流水线做出来的图是在 OpenGL 的框架里,而用光线追踪做出来 的图是在 OpenCV 里。融合的话有 2 种思路:

  1. 将 OpenGL 的渲染结果导出成 bitmap,然后在 OpenCV 中与之融合产 生融合后的 cv::Mat,然后通过 cv::imshow 来显示。
  2. 通过 pixel shader 将光追结果 cv::Mat 融合。OpenGL 里不能直接的使用 pixel shader,我们只能将 cv::Mat 当做纹理(Sample2D)导入后,将 其采样到 gl_FragCoord.xy 上(当然,要 x 和 y 要除以窗户大小)。

我们最终选择了第二种方案,融合的算法也比较简单,但效果我觉得还行,如下 图。对于光线追踪部分需要传给流水线的参数:

阴影系数矩阵;

反光矩阵;

在这里插入图片描述

Cg = α Ci + Cr

即阴影系数 * phong 得到的光照 + 反光。在 shader 中我们是这么写的:

在这里插入图片描述

九、Results

在这里插入图片描述
在这里插入图片描述

十、References

https://zhuanlan.zhihu.com/p/30944509
Learn	OpenGL-CN
http://www.songho.ca/opengl/gl_sphere.html
https://raw.githubusercontent.com/quietshu/-paper-cgRayTracing/master/RayTracing.pdf
https://zhuanlan.zhihu.com/p/51387524
https://zhuanlan.zhihu.com/p/41269520
https://zhuanlan.zhihu.com/p/21376124
https://www.cnblogs.com/graphics/archive/2010/08/09/1795348.html

raw.githubusercontent.com/quietshu/-paper-cgRayTracing/master/RayTracing.pdf
https://zhuanlan.zhihu.com/p/51387524
https://zhuanlan.zhihu.com/p/41269520
https://zhuanlan.zhihu.com/p/21376124
https://www.cnblogs.com/graphics/archive/2010/08/09/1795348.html

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shejizuopin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值