跳转到内容

Blender 3D:从新手到专业/景观建模 III:导出为高度图

来自 Wikibooks,开放世界中的开放书籍

在本教程中,我将向您展示如何将您美丽的 terrain 导出为高度图,该高度图可以在大多数 3D 图形引擎中使用。与直接导出网格相比,这样做的好处是,许多引擎都具有处理 terrain 的特殊过程,而不是常规网格,它将 terrain 分成不同的部分,以便它可以更细化地细分更靠近摄像机的区域以获得更多细节,并且还可以剔除(不渲染)不在摄像机视野范围内的区域,从而节省宝贵的处理时间。这种结构称为八叉树,它是渲染大型网格(如 terrain)的一种高度优化的方式。

在我开始之前,我必须感谢 从平面创建高度图 Blender wiki 上的教程。这是我学会使用这个技巧的方法,我将要介绍的大部分内容都来自这个教程。我只是为了方便将其包含在我的其他景观教程中。

关于高度图

[编辑 | 编辑源代码]

我将简要介绍高度图是什么以及它为什么有用,以供那些可能不知道的人。如果您熟悉高度图,您可以跳过下一部分。

An example of a heightmap
高度图的示例

高度图是一个灰度图像,它使用不同的灰色阴影来表示地图上的不同海拔。由于这些图像是 8 位(除了某些 16 位的 RAW 格式),因此您有 256 种不同的灰色阴影,从纯黑色 (0) 到纯白色 (255)。黑色表示地图上的最低海拔,而白色表示最高海拔。许多 3D 图形引擎已经具有读取高度图并从中生成 terrain 的功能。它执行此操作的方式是创建一个顶点网格(就像我们将在 Blender 中马上要做的),并使用高度图来确定网格上每个点的海拔。像素颜色越强烈(越接近白色),该顶点的高度就越高。在大多数情况下,如果高度图的分辨率小于 terrain 的分辨率,引擎将对高度图设置的顶点之间的顶点进行插值。例如,如果您的高度图是 256x256,而您的 terrain 是 1024x1024,则您的高度图将确定每四个顶点的海拔,而中间的三个顶点将被插值。

请注意,这些值不代表任何给定像素的绝对高度,而是代表相对于地图其余部分的高度。也就是说,您的高度图不代表一个海拔范围从 0 到 256 的景观。导入高度图时,您可以指定地图的最小和最大海拔,然后整个地图将被缩放。例如,假设您决定最小值为 1000 英尺,最大值为 5000 英尺。当渲染 terrain 时,黑色像素将表示 1000,白色像素将表示 5000,而正好位于黑色和白色之间的像素 (128) 将表示 3000 英尺(最小值和最大值总和的一半)。这使高度图相对灵活。

不幸的是,您可能已经注意到,使用高度图有一个限制。由于您只有 256 种灰色阴影,因此您只有 256 种可能的海拔。这会造成一个问题。无论您在建模的网格中顶点多么精确,无论您让它看起来多么光滑,每个点都将被舍入为介于 0 和 255 之间的整数值。当用于渲染 terrain 时,这会导致“阶梯效应”,因为 terrain 从一个离散的海拔到下一个离散的海拔,而不是平滑过渡。但是,有一些方法可以避免这种情况,我将在后面介绍。

如果您现在正在挠头说“嗯?”,请查看 高度图 上的维基百科页面,以获取更详细的解释和示例。

创建材质

[编辑 | 编辑源代码]
The terrain that will generate the heightmap
将生成高度图的 terrain

要开始本教程,我将假设您已经拥有一个要创建高度图的景观。如果没有,请阅读我的第一个教程,景观建模 I:基础 Terrain,以快速创建一个。警告!!!如果您已经创建了一个景观,请尽量记住您使用的平面的确切大小。如果您要创建一个,可以使用更大的平面来进行缩放,但要记住您缩放了多少倍。这将在以后使事情变得更容易。我建议您使用默认的 2x2 平面或网格,然后放大它。您可能还需要备份您的场景,因为我们将更改一些内容

要创建所需的材质,请执行以下步骤

  • 删除可能应用于 terrain 的所有现有材质。

注意:要删除材质,我认为您需要转到着色器部分中的链接和管道窗口,然后单击“链接到对象”下方的“X”。

  • 在着色选项卡(F5)中添加一个新材质。
  • 转到纹理选项卡(F6)并添加一个新纹理。这应该是您材质上的唯一纹理。
  • 从纹理类型下拉菜单中,选择“混合”。
  • 在同一个窗口中,找到“颜色”选项卡并选择“颜色带”。这将让我们定义混合模式,默认情况下,它从全透明的黑色渐变到实心青色。为什么是青色?我不知道。这是一个奇怪的默认设置。
  • 通过单击颜色带的左侧选择黑色。您应该看到一个小的黑色和白色条被选中。
  • 通过调整标记为“A”的滑块,将 Alpha 调整到 1。
  • 选择青色并将其更改为纯白色。
  • 您现在应该看到与我下面的颜色带类似。

The blend colorband

  • 返回到材质选项卡(位于奶酪图标旁边的红色球形图标)。
  • 在材质窗格中,选择“无阴影”选项以禁用材质上的光照。
  • 在右侧,找到标记为“映射输入”的窗格。在该窗格的底部是一个网格,默认情况下显示

XYZ
XYZ
XYZ

  • 将所有三行都设置为Z,这样纹理将完全映射到 Z 坐标。
  • 在左侧的预览窗口中,如果您选择球体或立方体,您应该会看到它从底部的黑色变为顶部的白色。这就是我们对 terrain 所需的效果。请记住,在高度图中,黑色表示最低点,白色表示最高点。

Map the input to the z-axis and make the material Shadeless

  • 最后,切换回编辑选项卡(F9)并单击“设置平滑”按钮以启用Gouraud 着色,这样一切都将显得光滑。

设置相机

[编辑 | 编辑源代码]

这就是我们对 terrain 本身需要做的所有事情。现在我们将要做的是设置相机,以便当我们渲染场景时,我们将获得一个正对 terrain 的正交投影,以便我们可以将其保存为高度图。

  • 如果您在场景中还有任何灯光或相机,请将其删除。
  • 切换到顶视图(NUM7)并将 3D 光标放置在原点 (0, 0, 0) 上,方法是在原点附近左键单击,然后按 SHIFT+SKEY 并选择光标到网格。(更简单的方法是:按“SHIFT+SKEY”并选择“光标到中心”)
  • 添加一个新相机,Space->添加->相机。这将添加一个新的相机到场景中,该相机正对下方。
The camera needs to be above the terrain
相机需要位于 terrain 上方
  • 切换到侧视图(NUM1NUM3)并将相机沿 Z 轴向上移动,使其位于 terrain 的最高点上方。即使视图将是正交的,因此距离无关紧要,整个 terrain 仍然需要位于相机前面。
  • 现在,选择相机后,转到编辑选项卡(F9)并选择“正交”按钮。这将更改相机为正交投影,它基本上会忽略所有顶点的 z 坐标(除了确定哪些像素应该在其他像素前面)。
  • 正交按钮上方有一个名为“Scale”的值。还记得我之前让你记住地形的大小吗?这就是原因。
  • 更改镜头比例(默认值:6)以匹配地形的大小。如果你保留了默认大小的飞机,这个值应该为 2。如果你按照“景观建模 I:基本地形”教程的建议将飞机放大 20 倍,这个值应该为 40(飞机最初是 2 个单位的正方形)。
  • 现在转到场景选项卡(F10),在“Format”下,将“SizeX”和“SizeY”更改为所需的高度图大小。对于大多数图形引擎,这需要是 2 的幂(2^n)或 2 的幂加 1(2^n+1)。所以尝试类似 256(或者如果你需要 2^n+1,则尝试 257)。
What the terrain will look like from the camera view
地形在相机视角下的外观
  • 现在,如果你切换到相机视角(NUM0),你应该看到一个“扁平”的正方形,它完全填满了表示相机视野的点线框。
The rendered image will be your heightmap.
渲染的图像将是你的高度图。
  • 渲染场景(F12)。你应该看到你的高度图。按F3保存渲染的图像,你就可以开始使用了!

由于这个图像没有颜色,并且一些引擎要求你的高度图是灰度图像(只有一个颜色通道而不是三个),所以在渲染之前,在“Format”窗格中选择“BW”按钮。这将把它渲染为灰度图像而不是彩色图像。 选择 BW 以保存为灰度图像。

避免阶梯效应

[编辑 | 编辑源代码]

如前所述,将高度图导出为 8 位图像(据我所知,Blender 不支持任何 16 位格式)有一个缺点,即你只有 256 个离散的高度值,当地形细分时会导致阶梯效应。理想情况下,你可以使用一个应用程序,它可以将图像导出为 16 位原始格式,例如 Terragen。但这是一篇 Blender 教程,所以我们不会深入讨论它。=P

降低分辨率

[编辑 | 编辑源代码]

你可以“平滑”渲染的地形的一种方法是实际上降低高度图的分辨率。这可能听起来违反直觉,但请耐心听我解释。假设你有一个高度图,它从左到右从黑色到白色简单地混合。如果你的高度图是 1024x1024,由于你只有 256 个不同的值,你将获得每种高度的 4 列。换句话说,你的灰度图将类似于这样

00001111222233334444...

00001111222233334444...

00001111222233334444...

00001111222233334444...

00001111222233334444...

00001111222233334444...

如果你尝试从这个高度图渲染地形,你将得到 4 个高度为 0 的点,4 个高度为 1 的点,4 个高度为 2 的点,以此类推,从而产生阶梯效应。

现在假设你创建了相同的高度图,但将大小缩减为 256x256。现在你将有 1 列对应于每个高度,你的灰度图将类似于这样

012345678...

012345678...

012345678...

012345678...

你可能在想,“但这会导致我的地形更小,或者更不详细”。但事实恰恰相反。考虑将上述高度图应用于 1024x1024 的地形。来自你的高度图的值将应用于每 4 个顶点,而其间的值将被插值。因此,你将得到类似于这样

0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0 2.0

这与使用 1024x1024 高度图得到的结果一致,你实际上将得到类似于这样

0.0 0.25 0.5 0.75 1.0 1.25 1.5 1.75 2.0

其中整数是来自你的高度图的值,而分数是插值值。这是假设你使用的任何引擎都会对从高度图读取的高度值之间的值进行插值。

目前,这是我验证过的唯一有助于减少阶梯效应的方法。当我尝试不同的技术时,我将在这个页面上更新它们。例如,我知道 Adobe Photoshop 可以将图像导出为 16 位原始格式,但我还没有尝试过,所以我不想把它作为解决方案建议。

华夏公益教科书