【问题标题】:How can a 3D game render an object without having a sprite for every single angle?3D 游戏如何在没有每个角度的精灵的情况下渲染对象?
【发布时间】:2015-11-23 20:47:29
【问题描述】:

在学习编写简单的 2D 游戏时,每个对象都会有一个 sprite 表,其中包含玩家在每一帧/动画中的样子的小图片。 3D 模型似乎不能以这种方式工作,否则我们需要一个图像来处理对象的每个可能视图!

例如,一个旋转的立方体需要很多图像来描述它在每一面的外观。所以我的问题是,从任意角度查看时,引擎如何表示和渲染 3D 模型“图像”?

【问题讨论】:

标签: game-engine 3d-modelling


【解决方案1】:

多种方法

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

投影

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

从那里,您基本上可以“为”三角形“着色”,以使所有内容看起来都是实心的。虽然这相当快,但另一个缺点是你不能真正拥有反射和折射之类的东西。每当您在游戏中看到折射或反射表面时,他们只是在使用诡计使其看起来像反射或折射材料。照明和阴影也是如此。

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

光线追踪

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

光线投射

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


使用 JavaScript 和 HTML5 画布的德军总部:Martin Kliehm 提供的图片

存储数据

可以使用多种方法存储 3D 数据。它不一定依赖于使用的渲染方法。存储的数据本身没有任何意义,因此您必须使用已经提到的方法之一来呈现它。

多边形

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

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

这是一个多边形模型的例子:

体素

这个方法很简单。你可以把voxel models 想象成位图,只不过它们是一堆位图,它们层叠在一起构成 3D 位图。所以你有一个 3D 像素网格。渲染体素的一种方法是将体素点转换为 3D 立方体。但是请注意,体素不必渲染为立方体。像像素一样,它们只是可能具有可以以不同方式解释的颜色数据的点。我不会详细介绍,因为这不是常见的,并且您通常使用多边形方法渲染体素(例如将它们渲染为立方体时。这是体素模型的示例:


图片来自维基百科用户 Vossman

【讨论】:

  • @Ike 非常感谢!现在我会说实话。我不完全确定你在说什么。您是在谈论片段着色过程(有点 OpenGL 特有,但您知道我的意思)吗?
  • @AidanMueller 很好的答案。主要是我在查看用于保存每个对象的模型的“文件”类型(我假设它是某种 XML 坐标系统,正如你所指出的),它类似于 SVG,非常类比。
  • @reddead 赎回...(见what I did there :P)。无论如何,有大量的格式被使用,并且有不同的技术(如体素数据)。但总的来说,网格是最常见的。虽然没有真正的通用文件格式,因为许多游戏甚至会使用自定义格式。但总的来说,它们基本上只是存储顶点。
  • @AidanMueller 要完成你的答案是缺少分析表示(模型是一组方程而不是多边形),这有时用于光线跟踪和/或物理模拟......
【解决方案2】:

在带有精灵表的 2D 世界中,您正在根据角色的状态(对象的视觉表示)绘制其中一个精灵。在 3D 世界中,您正在为您的演员渲染一个模型,该模型是一系列带有纹理的多边形。有标准化的模型文件(我最熟悉 Autodesk 3DS Max),其中模型和指定的纹理可以打包在一起(.3DS 或 .MAX 文件),提供您的图形库渲染对象及其所需的一切纹理。

简而言之,您不会为 3D 对象的每个视图都使用图像,而是在模型上渲染了纹理,从而在图形库渲染时创建动态视图。

【讨论】:

  • .obj 也支持
  • @thegrandpackard 知道这些文件是由什么组成的吗?坐标,二进制数据?引擎如何使用这样的文件?
  • .3DS 格式是一种二进制格式,需要您将其解析为数据块。非常复杂且根本不可读,这里有一个解析器示例(不确定它是否有效):gamedev.net/topic/313126-3ds-parsing-tutorial .obj 格式更易于人类阅读,但不是二进制的。这是一个带有一些示例代码的教程(不确定它是否有效):rodrigo-silveira.com/opengl-tutorial-parsing-obj-file-blender
猜你喜欢
  • 1970-01-01
  • 2016-11-29
  • 2010-11-04
  • 2014-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多