Opengl Shader: интерполяция между двумя текстурами - PullRequest
0 голосов
/ 01 ноября 2019

Я пытаюсь построить случайный генератор ландшафта в c ++ и opengl, но у меня есть некоторые проблемы с текстурированием. У меня есть два типа текстуры: трава и камень: enter image description here

Как вы можете видеть, на вершине холма есть камень и трава внизу. Я интерполирую эти две текстуры по высоте вершины. Мое значение высоты находится в диапазоне от -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, чтобы получитьболее выраженные холмы.

Жажда: я смешиваю две текстуры по высоте.

Вторая строка: чтобы получить «более сильную» интерполяцию, я использую функцию softmax, чтобы значение высоты было ближе к 0или 1. Честно говоря, это не слишком много, может быть, я не использую эту функцию должным образом.

Я хочу сделать более сильный softmax и иметь возможность контролировать уровень интерполяции. Таким образом, мои значения высоты должны быть ближе к 0 или 1. Потому что то, что я получаю с моей интерполяцией, сейчас выглядит не очень хорошо. Так, например, если мой рост равен 0,7, он должен быть преобразован в 0,95. И f (0,3) = 0,05, f (0,5) = 0,5. Что-то вроде того. Вы знаете советы для этого?

РЕДАКТИРОВАТЬ: Я сделал это!

enter image description here

Это довольно просто, я просто повторяю функцию 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;
}

И я использую смещение длявыбрать на какой высоте начало интерполяции

1 Ответ

3 голосов
/ 01 ноября 2019

Я рекомендую использовать smoothstep, чтобы "плавно" отобразить высоту от ее диапазона (например, [-20,0, 20,0]) до диапазона [0,0, 1,0] для интерполяции с помощью mix. Например:
(smoothstep выполняет интерполяцию Эрмита )

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);

Обратите внимание, что даже можно ограничить интерполяцию определенным диапазоном. Далее используется цвет от texture0, если height < -1.0, и от texture1, если height > -1.0. Между ними оно плавно интерполируется между текстурами:

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