这很长但我保证这很有意思。 :)
我正在尝试使用jMonkeyEngine模仿另一个应用程序纹理的外观。我有一个顶点列表和构成“景观网格”的面(三角形),应该用大约7-15种不同的纹理(取决于“景观”的地形)进行纹理化。每个三角形都有一个与之关联的纹理代码,表示特定三角形应该主要由哪个纹理组成。当然,纹理应该在每个面部之间平滑地混合。
所以我正在尝试开发一种允许这种方法的策略(它不使用预先制作的alpha map png文件,纹理alphas需要在运行时完成)。现在我想是否计算每个顶点(在顶点着色器中)每个纹理的“强度” - 通过考虑所有相邻面的地形类型(不确定如何做到这一点) - 我应该能够根据像素距顶点的距离设置alpha值。 frag着色器将使用生成的“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上进行的,我想。欢迎任何建议。
答案 0 :(得分:3)
如果我理解正确的话,这就是我的第一次拍摄:
您的问题或多或少是如何将您的每个面值分配到顶点上。这实际上类似于网格上的正常生成:首先,您将为每个三角形生成法线,然后根据每个顶点计算它们。谷歌“正常一代”,你会到达那里,但这里是要点。对于每个相邻的三角形,找到一个加权系数(通常是使用顶点的角的角度,或三角形的表面区域,或组合),然后总结值(正常或您的“强度”)乘以通过加权因子得到总结果。规范化,你就完成了。
那么你就可以将纹理“强度”发送到顶点着色器。现代的解决方案是使用字符并在像素着色器中对纹理数组进行采样,然后稍微捏合混合值以便为您提供更好的传输。
所以,如果我正确地解决了你的问题:
预处理:
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
渲染时间:
将每个顶点的值传递给fragmenthader,并在片段着色器中执行此操作:
basecolour = 0;
foreach value
basecolour = mix(basecolour, texture2D(textureSamplerForThisValue,uv), value)
//this is simple, but we could do better once we have this working
或者,您也可以好好看看几何体。如果你有大三角形和小三角形的组合,你将有不均匀的数据传播,并且由于你的数据是每个顶点,你将有更多的细节,这是更多几何。在这种情况下,您可能希望做其他人正在做的事情,并使用混合贴图将纹理与几何体分离。这些可能是低分辨率的,不应该增加你的内存消耗或着色器执行时间。