GLSL着色器:在两个以上纹理之间插值

T_0*_*_01 4 java opengl interpolation lwjgl heightmap

我在OpenGL中实现了一个高度图.现在它只是一个正弦/余弦弯曲的地形.此刻,我在白色"冰"和深色"石头"纹理之间进行插值.这样做是这样的:

color = mix(texture2D(ice_layer_tex, texcoord), texture2D(stone_layer_tex, texcoord), (vertex.y + amplitude) / (amplitude * 2))
Run Code Online (Sandbox Code Playgroud)

结果:

从顶部

从底部

它工作正常,但如果我想添加更多纹理(例如草纹理),插值顺序为"冰,石头,草",我该怎么办?我想,有没有这样的功能mix(sampler2D[], percentages[])?我怎么能按照这个逻辑写一个GLSL方法?

Ret*_*adi 21

mix()对于你自己可以轻松编写的东西来说,它真的只是一个便利功能 定义是:

mix(v1, v2, a) = v1 * (1 - a) + v2 * a
Run Code Online (Sandbox Code Playgroud)

或者换句话说,它计算加权平均值,v1并且v2使用两个权重w1,w2并且满足约束条件的浮点值介于0.0和1.0之间w1 + w2 = 1.0:

v1 * w1 + v2 * w2
Run Code Online (Sandbox Code Playgroud)

您可以直接对此进行概括,以计算超过2个输入的加权平均值.例如,对于3个输入v1,v2并且v3,你会使用3点的权重w1,w2v3满足约束条件w1 + w2 + w3 = 1.0,并计算加权平均值为:

v1 * w1 + v2 * w2 + v3 * w3
Run Code Online (Sandbox Code Playgroud)

对于您的示例,确定要用于3个纹理中每个纹理的权重,然后使用以下内容:

weightIce = ...;
weightStone = ...;
weightGrass = 1.0 - weightIce - weightStone;
color = texture2D(ice_layer_tex, texcoord) * weightIce +
        texture2D(stone_layer_tex, texcoord) * weightStone +
        texture2D(grass_layer_tex, texcoord) * weightGrass;
Run Code Online (Sandbox Code Playgroud)