Opengl 将多个纹理图像混合到3D地面上

Opengl 将多个纹理图像混合到3D地面上,opengl,terrain,Opengl,Terrain,电脑游戏是如何发挥作用的?我将使用几何体的高度贴图(尽管我稍后会对其进行优化),但我想知道最好的技术是什么,例如,“绘制”我的地面;到处都是草,到处都是土路,城镇里有砾石,每种材料之间都有平滑的过渡 我只是使用一个巨大的预烘焙纹理吗?当我可以平铺现有纹理时,这似乎效率很低。那么,我要为每个现有纹理使用一个巨大的alpha贴图吗?从理论上讲,这对我来说没什么问题,但实际上我该怎么做呢?后果如何?我真的不知道从哪里开始,我的谷歌搜索也不是很有效 我不希望将纹理“捕捉”到栅格(即空间(0,0)是草,空

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

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

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

我在这里主要是寻找理论和选择。我使用的是OpenGL,所以如果你能提供OpenGL的操作方法,以及我可能从未听说过的功能,那就太好了

只是为了澄清,遗忘是一个很好的参考,我在寻找什么。我不知道地面的几何结构如何(高度贴图、静态3D模型等),但它们的地形有不同的地面类型,它们之间有平滑的过渡,就像我所说的那样。这是一幅示例图像,请注意鹅卵石是如何融入草地的,既不现实又平滑:

另外,我想我在一本游戏编程珍宝书中读到过这方面的内容,但当时我没有太多的注意,现在是夏天,我没有机会去我大学的图书馆查看!我现在正在寻找目录,如果我找到它,我会进行编辑,但直到8月中旬我仍然无法阅读它


编辑:啊,老兄,游戏编程Gems 7有一个5.8章,标题是“为户外地形渲染绘制大纹理”,这听起来正是我需要的,但我的U's library甚至没有这本书!我在其他游戏编程珍宝书中找不到与此完全相同的东西,尽管有几本关于地形几何的文章。

预烘焙肯定不是低效的。事实上,它是最有效的,因为运行时代码不必进行任何混合或其他计算。它只是渲染纹理。当然,动态技术提供了工具链的简化和更多选项。

通常,过渡区域是预先创建的,尽管可以使用alpha通道和纹理混合来完成一些事情。

我最近在OpenGL中编写了一个小型地形渲染引擎,它的功能与您所说的类似。我使用的技术最好描述为

我使用五种纹理来实现这一点。其中四种纹理是细节纹理:草、岩石、水和沙子。这些纹理很小,为512x512纹理,在整个地形上平铺。第五个纹理是混合贴图。混合贴图是一个覆盖整个地形的巨大纹理,在我的例子中是4096x4096

混合图 此混合贴图使用所有4个颜色通道(r、g、b、a)来描述在该特定位置显示的细节纹理的多少。我使用红色通道来确定沙子的不透明程度,绿色代表草,蓝色代表水,阿尔法代表岩石。这个mixmap是根据初始化时的heightmap计算的,我使用高度来确定这些值。例如,接近海平面时,我主要需要水,因此我在蓝色通道中设置高值,在其他通道中设置低值。当我进入更高的山脉时,我将alpha颜色通道设置为一个较高的值,因为我需要大量的岩石纹理,但我将所有其他颜色通道设置为较低的值

片段着色器 然后在片段着色器中使用该混合贴图,在这里我获取混合贴图的这些颜色通道,并使用它们组合细节纹理。以下是我用于片段着色器的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);
}

“均匀纹理比例”(uniform texscale)是一个值,用于确定细节纹理在整个地形上平铺的次数。较高的值将使细节纹理看起来更清晰,但有可能使它们看起来更重复。

ID似乎使单个大纹理(我们说的是32K^2-128K^2)在地震中起作用

关于这一点,卡马克在

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

(原始链接目前似乎已失效,但没有将上面的链接作为链接,因为SO似乎在Internet存档链接方面存在问题;它们在编辑预览中看起来不错,然后在主页上断开)。

您无法摆脱平铺,但如果您使用的基础纹理在地面上产生一些噪音,看起来好像没有瓷砖

使用与alpha纹理具有相同纹理坐标的基础纹理。基本纹理可以是任何东西。。卫星图像或草纹理。。 如果它与你的地面形状相关,那么它会非常完美

并尝试使用无缝纹理为您的草地,岩石纹理。。。
它没有解决问题,但看起来没有问题。例如,在源(hl2)引擎中使用的标准方法之一是使用逐顶点alpha在两种材质之间混合。这些物质通常至少由反照率和法线贴图组成。在源引擎中,每个“混合纹理”材质只允许使用2种材质,这有点糟糕

如果需要2种以上的材质,则必须通过使用不同纹理对不同置换进行纹理处理来模拟,确保任何单个瓷砖最多只包含2种材质

使用每个顶点的alpha而不是每个像素会产生非常糟糕的外观。例如,正如你在《遗忘》中所提到的,你可以将鹅卵石平滑地混合到沙子中。那里