I've implemented a heightmap in OpenGL. For now it is just a sine/cosine curved terrain. At the moment I am interpolating between the white "ice" and the darker "stone" texture. This is done like this:
color = mix(texture2D(ice_layer_tex, texcoord), texture2D(stone_layer_tex, texcoord), (vertex.y + amplitude) / (amplitude * 2))
The result:
It works fine, but what could I do if I want to add more textures, for example a grass texture, so that the interpolation order is "ice, stone, grass"? I think, there isn't a function like mix(sampler2D[], percentages[])
? How could I write a GLSL method following this logic?
mix()
is really just a convenience function for something you can easily write yourself. The definition is:
mix(v1, v2, a) = v1 * (1 - a) + v2 * a
Or putting it differently, it calculates a weighted average of v1
and v2
, with two weights w1
and w2
that are float values between 0.0 and 1.0 meeting the constraint w1 + w2 = 1.0
:
v1 * w1 + v2 * w2
You can directly generalize this to calculate a weighted average of more than 2 inputs. For example, for 3 inputs v1
, v2
and v3
, you would use 3 weights w1
, w2
and v3
meeting the constraint w1 + w2 + w3 = 1.0
, and calculate the weighted average as:
v1 * w1 + v2 * w2 + v3 * w3
For your example, determine the weights you want to use for each of the 3 textures, and then use something like:
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;
No, according to the GLSL documentation for mix() there are only overloads for interpolation between two parameters.
Would it be acceptable to you to just interpolate "ice" and "stone" then mix the result with the "grass" texture?
vec4 ice_color = texture2D(ice_layer_tex, texcoord);
vec4 stone_color = texture2D(stone_layer_tex, texcoord);
vec4 grass_color = texture2D(grass_layer_tex, texcoord);
vec4 tmp = mix(ice_color, stone_color, pct);
vec4 final_color = mix(tmp, grass_color, pct);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With