Man*_*ius 6 opengl 3d shader glsl hlsl
这很长,但我保证这很有意思.:)
我正在尝试使用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; };
Run Code Online (Sandbox Code Playgroud)
我不知道这是什么HLSL"MeshTextureSampler"是,但它似乎像这样的应用程序可能已经预先混合作为所需的所有纹理,并根据面部/地形数据的代码创建一个单一的质地为整个网格.在像素/片段着色器中,他们真正做的就是:
float4 tex_col = tex2D(MeshTextureSampler, In.Tex0);
Run Code Online (Sandbox Code Playgroud)
在那之后它只是阴影,灯光等 - 据我所知,没有任何纹理混合,这让我相信这种纹理混合工作是事先在CPU上完成的,我想.欢迎任何建议.
如果我理解正确的话,这就是我的第一个镜头:
您的问题或多或少是如何在顶点上分配每个面的值。这实际上类似于网格上的法线生成:首先为每个三角形生成法线,然后按顶点计算它们。谷歌“正常一代”,你就会到达那里,但要点是这样的。对于每个相邻的三角形,找到一个权重因子(通常是使用顶点的角的角度,或三角形的表面积,或组合),然后将乘以的值(无论是正常的还是你的“力量”)相加通过权重因子得出总结果。正常化就完成了。
这样你就有了可以发送到顶点着色器的纹理“强度”。现代的解决方案是在稍微修改混合值以提供更好的传输之后,使用字符并在像素着色器中对纹理数组进行采样。
所以,如果我正确地理解了你的问题:
预处理:
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
Run Code Online (Sandbox Code Playgroud)
渲染时间:
将每个顶点的值通过管道传输到片段着色器,并在片段着色器中执行此操作:
basecolour = 0;
foreach value
basecolour = mix(basecolour, texture2D(textureSamplerForThisValue,uv), value)
//this is simple, but we could do better once we have this working
Run Code Online (Sandbox Code Playgroud)
或者,您也可以仔细看看您的几何形状。如果您有大三角形和小三角形的组合,您将拥有不均匀的数据分布,并且由于您的数据是每个顶点的,因此您将在更多几何图形的地方获得更多细节。在这种情况下,您可能会想做其他人正在做的事情,并通过使用混合贴图将纹理与几何体分离。这些可以是低分辨率的,并且不会增加太多的内存消耗或着色器执行时间。