OpenGL: деформация ландшафта с использованием карты высот в вершинном шейдере

Я пытался реализовать карту высот в своем шейдере ландшафта, но ландшафт остается плоским. Текстура правильно загружена в вершинный шейдер, и я пытаюсь использовать значения оттенков серого текстуры на основе uvs сетки для регулировки высоты вершины:

//DIFFUSE VERTEX SHADER
#version 330 

uniform mat4    projectionMatrix;
uniform mat4    viewMatrix;
uniform mat4    modelMatrix;

in vec3 vertex;
in vec3 normal;
in vec2 uv;

uniform sampler2D heightmap;

out vec2 texCoord;

void main( void ){

vec3 _vertex = vertex;
_vertex.y = texture(heightmap, uv).r * 2.f;
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(_vertex, 1.f);
texCoord = uv;

}

Фрагмент: (splatmap работает, не обращайте на это внимания)

uniform sampler2D splatmap;
uniform sampler2D diffuse1;
uniform sampler2D diffuse2;
uniform sampler2D diffuse3;
uniform sampler2D diffuse4;

in vec2 texCoord;
out vec4 fragment_color;

void main( void ) {
///Loading the splatmap and the diffuse textures
vec4 splatTexture = texture2D(splatmap, texCoord);
vec4 diffuseTexture1 = texture2D(diffuse1, texCoord);
vec4 diffuseTexture2 = texture2D(diffuse2, texCoord);
vec4 diffuseTexture3 = texture2D(diffuse3, texCoord);
vec4 diffuseTexture4 = texture2D(diffuse4, texCoord);
//Interpolate between the different textures using the splatmap's rgb values (works)
diffuseTexture1 *= splatTexture.r;
diffuseTexture2 = mix (diffuseTexture1, diffuseTexture2, splatTexture.g);
diffuseTexture3 = mix (diffuseTexture2,diffuseTexture3, splatTexture.b);
vec4 outcolor = mix (diffuseTexture3, diffuseTexture4, splatTexture.a);

fragment_color = outcolor;

}

Дополнительная информация: все текстуры загружаются в мой материал ландшафта и передаются шейдеру (работает правильно):

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, heightMap->getId());
glUniform1i (_shader->getUniformLocation("heightMap"),0);
...

Плоскостная сетка uvs отображается следующим образом:

(0,1) (1,1)

(0,0) (1,0)

Думаю, я делаю что-то ужасно неправильно, но не могу понять, что именно. Любая помощь приветствуется!


person Possimpible    schedule 23.01.2017    source источник
comment
Какова цель _vertex? Вы устанавливаете _vertex.y, но после этого никогда не используете его снова.   -  person Mukesh Ingham    schedule 23.01.2017
comment
Извините, в GL_position должно быть написано _vertex вместо vertex. Я забыл отредактировать   -  person Possimpible    schedule 23.01.2017
comment
Вам следует попробовать найти функцию генерации случайной высоты и попробовать ее вместо карты текстуры. Таким образом, вы сможете увидеть, что является причиной проблемы: карта текстуры или gl_Position.   -  person Mukesh Ingham    schedule 23.01.2017
comment
Почему бы вам не создать сетку карты высот один раз и не передать вершины шейдеру вместо того, чтобы постоянно пересчитывать значение y для каждой вершины?   -  person eldo    schedule 23.01.2017
comment
Это заставило бы меня написать дополнительный загрузчик меша специально для моей карты высот. Текущий способ - это способ, который я нашел в нескольких руководствах, и он должен сработать. Я не говорю, что это самый гибкий способ, но я хочу выяснить, почему он не работает.   -  person Possimpible    schedule 23.01.2017


Ответы (1)


Вы пишете это:

Плоскостная сетка uvs отображается следующим образом:

(0,1) (1,1)

(0,0) (1,0)

… Означает, что ваша сетка состоит всего из 4 вершин? Если так, то в этом и заключается ваша проблема: шейдер вершин не может волшебным образом создавать «новые» вершины, поэтому ваша текстура карты высот выбирается только в 4 точках (и ничего между ними).

И поскольку вы выбираете координаты текстуры с целочисленными значениями и координаты текстуры, которые находятся в 0 и 1, вы фактически выбираете одну и ту же координату текстуры, поэтому вы увидите одинаковое смещение для всех четырех вершин.

Решение: создайте мозаику для вашей базовой сетки, чтобы на самом деле были вершины, доступные для смещения. Для этого отлично подойдет тесселяционный шейдер.

РЕДАКТИРОВАТЬ:

Кстати, вы можете немного настроить вершинный шейдер: для атрибутов сделайте его

in vec2 vertex;

для которого требуется всего 2/3 пространства vec3, поскольку вы все равно не используете компонент z.

float y = texture(heightmap, uv).r * 2.f;
gl_Position =
    projectionMatrix
  * viewMatrix
  * modelMatrix
  * vec4(vertex.x, y, vertex.y, 1.f);
person datenwolf    schedule 23.01.2017
comment
Большое спасибо за подробный ответ! Вы были правы насчет количества вершин меша. Я обновил плоскость, теперь она содержит 8192 вершины, и есть некоторый прогресс. Однако они не интерполируются, поэтому выглядит как прозрачная гора. Здесь на помощь приходит шейдер тесселяции? - person Possimpible; 23.01.2017
comment
@Possimpible: Нет, шейдер тесселяции вам в этом не поможет. Для меня это больше похоже на проблему с координатами текстуры. А именно, что вы используете одну и ту же координату текстуры для выборки смещения всех 4 вершин в четырехугольнике. - person datenwolf; 23.01.2017
comment
Только что вернулся, чтобы сказать, что проблема была вызвана смешиванием внешнего цвета во фрагментном шейдере. Когда я вставляю его в новый vec4 с альфой, равной 1, он работает как шарм. Спасибо за помощь! - person Possimpible; 24.01.2017