Opengl 着色器:在两个纹理之间进行插值

Opengl Shader : Interpolating between two textures

我正在尝试用 c++ 和 opengl 构建一个随机地形生成器,但我在纹理方面遇到了一些问题。 我有两种质地:药草和岩石:

如你所见,山顶上是岩石,下面是草本植物。我通过顶点的高度在这两个纹理之间进行插值。我的高度值在 -1 和 1 之间。所以在我的片段着色器中我这样做:

float height = clamp(vs_position.y/20.f, -1f, 1f );

height = exp(height) / exp(1.f);


vec3 final_texture = mix(
vec3(texture(texture0, vs_texcoord)), 
vec3(texture(texture1, vs_texcoord)), 
vec3(height));

第一行并不重要,在我将顶点数据发送到我的着色器之前,我将高度乘以 20 以获得更明显的山丘。

口渴线:我按高度混合了两种纹理。

第二行:要进行"stronger"插值,我使用softmax函数使高度值接近0或1。老实说它并没有做太多,也许我不使用这个函数正确。

我想要的是做一个更强的softmax,并且能够控制插值的水平。所以我的高度值应该更接近于 0 或 1。因为我通过插值得到的结果现在看起来不太好。 因此,例如,如果我的身高是 0.7,则应将其转换为 0.95。 f(0.3) = 0.05,f(0.5) = 0.5。像那样的东西。 你知道这方面的秘诀吗?

编辑: 我做到了 !

很简单,我只是重复了几次softmax函数:

float softmax(float value, float max , int iteration, float offset)
{
    value += offset;

    for(int i=0; i<iteration; i++)
    {
        value = exp(value);
        max = exp(max);
    }

    value = (value/max);
    value = clamp(value, 0.f, 1.f);

    return value;
}

然后我使用偏移量来选择插值开始的高度

我推荐使用smoothstep to "smoothly" map the height from its range (e.g. [-20.0, 20.0]) to the range [0.0, 1.0] for the interpolation by mix。例如:
(smoothstep 执行 Hermite interpolation)

vec3 color0 = texture(texture0, vs_texcoord).rgb;
vec3 color1 = texture(texture1, vs_texcoord).rgb;

float a = smoothstep(-20.0, 20.0, height);
vec3 final_texture = mix(color0, color1, a);

注意,甚至可以将插值限制在一定范围内。在下文中,如果 height < -1.0,则使用 texture0 的颜色;如果 height > -1.0,则使用 texture1 的颜色。在它之间平滑地插入纹理之间:

float a = smoothstep(-1.0, 1.0, height);
vec3 final_texture = mix(color0, color1, a);