【问题标题】:Blending multiple textures in GLSL在 GLSL 中混合多个纹理
【发布时间】:2011-07-03 18:13:06
【问题描述】:

这很长,但我保证它很有趣。 :)

我正在尝试使用 jMonkeyEngine 来模仿另一个应用程序纹理的外观。我有一个构成“景观网格”的顶点和面(三角形)列表,应该用大约 7-15 种不同的纹理(取决于“景观”的地形)进行纹理化。每个三角形都有一个与之关联的纹理代码,表示该特定三角形应该主要由哪个纹理组成。当然,纹理应该在每个面之间平滑融合。

所以我正在尝试制定一种策略来实现这一点(它不使用预制的 alpha 贴图 png 文件,纹理 alpha 需要在运行时完成)。现在我想如果我计算每个顶点的每个纹理的“强度”(在顶点着色器中) - 通过考虑所有相邻面的地形类型(不确定如何做到这一点) - 我应该能够根据像素与顶点的距离来设置 alpha 值。碎片着色器将使用生成的“阿尔法贴图”来混合每个像素的每个纹理。

这是否可行,还是我应该考虑完全不同的策略?我有我试图模仿的应用程序的着色器代码(但它们是 HLSL,我正在使用 GLSL),但似乎他们正在其他地方执行此混合步骤:

    sampler MeshTextureSampler = sampler_state { Texture = diffuse_texture; AddressU = WRAP; AddressV = WRAP; MinFilter = LINEAR; MagFilter = LINEAR; }; 

我不确定这个 HLSL“MeshTextureSampler”是什么,但看起来这个应用程序可能已经根据需要预先混合了所有纹理,并根据面部/地形代码数据为整个网格创建了一个纹理。在像素/片段着色器中,他们真正做的似乎是:

float4 tex_col = tex2D(MeshTextureSampler, In.Tex0);

在那之后,它只是阴影、照明等——据我所知,根本没有任何纹理混合,这让我相信这种纹理混合工作是事先在 CPU 上完成的,我想。欢迎提出任何建议。

【问题讨论】:

    标签: opengl 3d glsl shader hlsl


    【解决方案1】:

    如果我理解正确的话,这是我的第一枪:

    您的问题或多或少是如何在顶点上分配您的每面值。这实际上类似于网格上的法线生成:首先您将为每个三角形生成法线,然后按顶点计算它们。谷歌“正常一代”,你会到达那里,但这是要点。对于每个相邻的三角形,找到一个加权因子(通常是使用顶点的角的角度,或三角形的表面积,或组合),然后将值相加(无论是正常的还是你的“优势”)相乘通过加权因子得出总结果。规范化,你就完成了。

    那么你就有了可以发送到顶点着色器的纹理“强度”。现代解决方案是使用字符并在像素着色器中对纹理数组进行采样,在您稍微捏造混合值以提供更好的传输之后。

    所以,如果我正确地解决了您的问题:

    预处理:

    forearch vertex in mesh
      vertexvalue = 0
      normalization = 0
      foreach adjacent triangle of vertex
          angle = calculateAngleBetween3Vertices(vertex,triangle.someothervertex,triangle.theotherothervertex)
          vertexvalue += triangle.value * angle
          normalization += angle
      vertexvalue/=normalization
    

    渲染时间:

    将每个顶点的值通过管道传送到片段着色器,并在片段着色器中执行此操作:

    basecolour = 0;
    foreach value    
       basecolour = mix(basecolour, texture2D(textureSamplerForThisValue,uv), value)
       //this is simple, but we could do better once we have this working
    

    或者,您也可以仔细查看您的几何图形。如果您有大三角形和小三角形的组合,您将拥有不均等的数据分布,并且由于您的数据是每个顶点的,您将在更多几何的地方获得更多细节。在这种情况下,您可能想要做其他人正在做的事情,并通过使用混合贴图将纹理与几何体分离。这些可能是低分辨率的,不应该增加内存消耗或着色器执行时间。

    【讨论】:

    • 我被卡住的地方通常是“对于每个相邻的三角形,找到一个权重因子......”——我会在哪里执行此操作,以及如何从着色器中访问它?仍然很难想象这一点。
    • 你没有。这只是预处理阶段(您的值在渲染时是静态的,对吧?)。每个三角形的权重因子为 1 应该可以工作,这是一个质量问题。否则,您可以将其视为接触顶点的三角形角的角度。然后,顶点处的值变为 FOREACHN 值 += angle_of_triangle*value_at_tringe
    • 我只是想到了一个可能的解决方案,但再读一遍我认为这与您建议的基本相同(去图)。我在想我会尝试为每个顶点传递“加权”阿尔法值(每个纹理),并将片段着色器中的那些用作纹理阿尔法。 (这是你在说什么吗?)我很难确定如何使用 jMonkeyEngine 执行此操作,但我希望我可以将这些数据作为顶点属性作为“texCoordX”顶点缓冲区类型传递。 (那里有一些 jME 特定的东西。)如果这可行,那么按照你的建议使用面积/角度来计算权重可能会奏效......
    • 竞争很激烈,但你是赢家,我的朋友......这个策略确实有效,仍然需要看看我是否可以调整它以获得我需要的外观,但这个概念是有效的.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多