3D游戏如何在没有每个角度的精灵的情况下渲染物体?

red*_*ead 26 game-engine 3d-modelling

当学习编写简单的2D游戏时,每个对象都会有一张精灵表,其中包含玩家在每个帧/动画中的外观.3D模型似乎没有这种方式工作,或者我们需要一个图像用于对象的每个可能的视图!

例如,旋转立方体需要很多图像来描绘它在每一面上的外观.所以我的问题是,从任意角度看,3D模型"图像"如何由引擎表示和呈现?

Lys*_*sol 87

多种方法

有许多方法可以渲染和存储3D图形和模型.甚至有不同的渲染2D图形的方法!除2D位图外,您还有SVG.SVG使用数字来定义图像中的点.这些点形成了形状.这些点也可以定义曲线.这使您可以在不需要像素的情况下制作图像.除了能够转换图像(缩放和旋转)而不会导致失真之外,结果可以是较小的文件大小.除3D外,大多数3D图形使用类似的技术.然而,这些方法的共同之处在于它们最终都将数据呈现为2D像素网格.

投影

渲染3D模型的最常用方法是投影.在渲染之前,所有要渲染的形状都被分解为三角形.为什么三角?因为三角形保证是共面的.这为渲染器节省了大量工作,因为它不必担心"在线外着色".这样做的一个缺点是大多数3D图形投影技术不支持完美的球体或其他圆形表面.您必须使用近似和其他技巧来制作圆形曲面(尽管有一些渲染器支持圆形曲面).下一步是将所有3D点转换或投影到屏幕上的2D点(如下所示).

图片展示投影

从那里,你基本上"着色"三角形,使一切看起来坚实.虽然这很快,但另一个缺点是你不能真正拥有反射和折射之类的东西.每当你在游戏中看到折射或反射表面时,他们只会使用诡计使其看起来像反射或折射材料.照明和阴影也是如此.

以下是用于使球体近似看起来平滑的特殊着色的示例.请注意,您仍然可以看到平滑版本周围的直线:

光滑着色的图片

光线追踪

您还可以使用光线跟踪渲染多边形.使用此方法,您基本上可以跟踪光线到达摄像机所需的路径.这使您可以进行逼真的反射和折射.但是,我不会详细说明,因为它目前在游戏中实际使用太慢.它主要用于3D动画(就像皮克斯制作的那样).具有低质量设置的简单场景可以很快地进行光线跟踪.但是对于复杂,逼真的场景,单帧渲染可能需要几个小时(就像皮克斯电影的情况一样).但是,它确实产生了超逼真的图像:

光线追踪的场景的图片

射线铸造

不要将射线投射与上述射线追踪相混淆.光线投射不会追踪光路.这意味着你只有平坦的表面; 没有反思.它也不会产生逼真的光线.但是,这可以相对较快地完成,因为在大多数情况下,您甚至不需要为每个像素投射光线.这是用于早期游戏的方法,例如Doom和Wolfenstein 3D.在早期游戏中,光线投射用于地图,角色和其他项目使用始终面向相机的2D精灵渲染.从几个不同的角度绘制精灵,使它们看起来像3D.这是Wolfenstein 3D的图像:

Wolfenstein3D的图片(Javascript克隆)
使用JavaScript和HTML5 Canvas的Castle Wolfenstein:图片来自Martin Kliehm

存储数据

可以使用多种方法存储3D数据.它不一定依赖于使用的渲染方法.存储的数据本身并不意味着任何东西,因此您必须使用已经提到的方法之一来渲染它.

多边形

这与SVG类似.它也是存储模型数据的最常用方法.您可以使用3D点定义几何体.这些点可以具有其他属性,例如纹理数据(以UV映射的形式),颜色数据以及您可能想要的任何其他属性.

可以使用多种文件格式存储数据.使用的常见文件格式是COLLADA,它是存储3D数据的XML文件.但是还有很多其他格式.然而,从根本上说,所有文件格式仍然存储3D数据.

以下是多边形模型的示例:

多边形模型的图片

这种方法非常简单.您可以将体素模型视为位图,除非它们是一堆位图组合在一起制作3D位图.所以你有一个像素的3D网格.渲染体素的一种方法是将体素点转换为3D立方体.但请注意,体素不必呈现为立方体.与像素一样,它们只是可能具有可以以不同方式解释的颜色数据的点.我不会详细介绍,因为这不太常见,你通常使用多边形方法渲染体素(比如当你将它们渲染为立方体时.这是一个体素模型的例子:

体素数据
图片由维基百科用户Vossman提供