电脑游戏如何呈现其阵地?我将使用几何高度图(尽管我稍后会对其进行优化),但我想知道最好的技术是什么,例如,“绘制”我的地面;到处都是草,到处都是土路,城镇里有砾石,每种材料之间的过渡也很平滑。

我只使用巨大的预烘焙纹理吗?当我可以平铺现有纹理时,这似乎非常低效。那么我是否要为每个现有纹理使用巨大的 alpha 贴图?从理论上讲,这对我来说听起来不错,但我实际上该如何去做以及后果是什么?我真的不知道从哪里开始,而且我的谷歌搜索也不是很有效。

我不想将纹理“捕捉”到网格(即空间(0,0)是草,空间(0,2)是泥土,空间(0,1)是草-泥土过渡);我宁愿能够随意画画,这样看起来更有说服力。当然,这是一种简单的方法,但在图形质量和“真实感”方面牺牲太多。

我主要只是在这里寻找理论和选择。我正在使用 OpenGL,因此如果您能提供有关 OpenGL 的工作方式以及我可能从未听说过的功能的提示,那就太好了。

只是为了澄清一下,《Oblivion》是我正在寻找的内容的一个很好的参考。我不知道地面的几何形状(高度图、静态 3D 模型等),但它们的地形具有不同的地面类型以及它们之间的平滑过渡,就像我所说的那样。这是一个示例图像,请注意鹅卵石如何融入草地,不切实际但平滑: http://www.elitistsnob.com/images/Oblivion%202006-05-21%2008-38-25-15.jpg

另外,我想我在一本《游戏编程宝石》书中读到过这一点,但当时我并没有太注意它,而且现在是夏天,我无法访问我大学的图书馆来查看!我现在正在寻找目录,如果找到就会进行编辑,但直到八月中旬我仍然无法阅读它。

编辑:啊,游戏编程宝石 7 有一个章节 5.8,标题为“室外地形渲染的大型纹理映射”,听起来正是我需要的,但我的图书馆甚至没有那本书!我在其他游戏编程宝石书籍中找不到与此完全相同的内容,尽管有一些关于地形几何的文章。

有帮助吗?

解决方案

我最近写在OpenGL小地形渲染引擎,做类似你说的是什么东西。我用的技术被最好地描述为纹理泼洒

我用5个纹理做到这一点。这些纹理四是细节纹理:草地,岩石,水和沙子。这些纹理是短小的,512×512的纹理,并且它们在地形平铺。第五纹理是mixmap。该mixmap是一个巨大的纹理覆盖整个地形,在我的情况是4096×4096。

MixMap

此mixmap使用所有4个颜色通道(R,G,B,A)来描述如何细节纹理的多在该特定位置处显示。我使用红色通道,以确定如何不透明的沙子,绿色是草,蓝色是水,和α是岩石。这mixmap是基于关闭在初始化时高度图的计算,我用海拔来确定这些值。举例来说,接近海平面,我大多要水,所以我设置在其他渠道的蓝色通道值和最低值的高值。正如我获得更高的进山,我设置alpha色彩通道为一个高值,因为我想了很多岩石结构的,但我设置所有其它颜色通道的较低的值。

片段着色器

此mixmap然后把在片段着色器,其中I取mixmap的这些颜色通道使用和使用它们的细节纹理结合。这里是我使用的片段着色器的GLSL代码:

uniform sampler2D alpha;
uniform sampler2D grass;
uniform sampler2D water;
uniform sampler2D rock;
uniform sampler2D sand;
uniform float texscale;

varying vec3 normal, lightDir ;

void main()
{
   // Get the color information
   vec3 alpha    = texture2D( alpha, gl_TexCoord[0].st ).rgb;
   vec3 texSand  = texture2D( sand, gl_TexCoord[0].st * texscale ).rgb;
   vec3 texGrass = texture2D( grass,  gl_TexCoord[0].st * texscale ).rgb;
   vec3 texWater = texture2D( water, gl_TexCoord[0].st * texscale ).rgb;
   vec3 texRock  = texture2D( rock,  gl_TexCoord[0].st * texscale ).rgb;

   // Mix the colors together
   texSand *= mixmap.r;
   texGrass = mix(texSand,  texGrass, mixmap.g);
   texWater = mix(texGrass, texWater, mixmap.b);
   vec3 tx  = mix(texWater, texRock,  mixmap.a);

   // Lighting calculations
   vec3 dl = gl_LightSource[0].diffuse.rgb;   
   vec3 al = gl_LightSource[0].ambient.rgb;
   vec3 n = normalize(normal);
   vec3 d = tx * (dl * max( dot ( n, lightDir), 0.0 ) + al );   

   // Apply the lighting to the final color   
   vec4 finalColor = vec4( min(d, 1.0), 1.0);
   gl_FragColor = mix(gl_Fog.color, finalColor, fogFactor);
}

均匀texscale是确定细节纹理多少次在地形平铺的值。较高的值将使细节纹理以使它们看起来更重复的风险看起来更加明快。

其他提示

预烘烤是最肯定不是低效率的。这是最有效的,其实是因为你运行的代码没有做任何混合或其他计算。它只是呈现的质感。当然,动态技术提供的工具链和多个选项的简化。

ID似乎已作出了单一的大 “megatexture” (我们谈论32K ^ 2-128K ^ 2)在QuakeWars工作。

有一个有趣的Q&A与卡马克关于它在

http://web.archive.org/web/20080121072936/http://www.gamerwithin.com/?view=article&article=1319&cat=2

(原链接似乎目前死了,但不是不能做一个链接上方,因为SO似乎与互联网档案馆联系的问题,他们看在编辑预览好,然后在主网页上的突破)。

一的标准方法,用于例如在源(HL2)发动机,是有一个每顶点alpha两种材料之间进行混合。这些材料通常包括至少一个反照率和正常映射的。在源发动机每“混合纹理”材料只有2材料是被允许时,这是一种糟糕。

如果你想超过2层的材料必须通过纹理不同质地不同的位移,确保任何单个瓷砖只包含了两个材料最多模仿它。

具有每顶点而不是每个像素的阿尔法给出了一个非常糟糕的外观。正如你在遗忘注意到你鹅卵石顺利融入砂实例。有此缺陷的修复;您使用其他纹理,其调制在每像素基础上的α,使得鹅卵石之间的缝隙用砂填充容易,但鹅卵石的顶部保持在几乎1.0阿尔法直到插值顶点alpha几乎为0的卵石材料。这可以使过渡看起来很不错,而不仅仅是一个丑陋的涂抹。

您也可以使用低分辨率纹理包含阿尔法(但每个顶点仍远高于1的α)。平铺的terain纹理可能是2048×2048,但所用的纹理toghether混合起来并不需要每个纹理像素的分辨率。每纹素纹理256x256的8位是只有96 KB与纹理贴图。

通常,过渡区域被预先创建的,尽管它可能做一些事情alpha通道和纹理的混合。

你不能从平铺逃跑,但也许如果你使用一个基础纹理,这使得在地面噪音小,它看起来像没有贴瓷砖......

使用基本纹理带alpha纹理的相同纹理坐标。基础纹理可以是任何东西..一个sattelite图片,或草质地.. 如果它关系到你的地面形状它将匹配完美..

和尝试使用无缝的纹理,为您的草,石头纹理... 它并没有解决,但使得它看起来没有问题

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top