OpenGL:使用顶点着色器中的高度图进行地形变形

时间:2017-01-23 10:30:35

标签: opengl textures shader vertex heightmap

我一直在尝试将高度图实现到我的地形着色器,但地形保持平坦。纹理在顶点着色器中正确加载,我尝试使用基于网格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)

我想我正在做一些可怕的错误,但我无法弄清楚是什么。任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:3)

你写这个:

  

平面网格uvs映射如下:

     

(0,1)(1,1)

     

(0,0)(1,0)

...意味着你的网格只包含4个顶点?如果是这样,那么那就是你的问题:顶点着色器无法神奇地创建“新”顶点,因此你的高度贴图纹理仅在4个点处被采样(并且两者之间没有任何内容)。

因为您以整数值和纹理坐标对纹理坐标进行采样并且为0和1,所以您可以有效地采样相同的纹理坐标,因此您将看到所有四个顶点的相同位移。

解决方案:对基础网格进行细分,以便实际可以替换顶点。一个tesselation着色器完全没问题。

编辑:

顺便说一句,您可以简单地使用顶点着色器:对于属性,使其成为

in vec2 vertex;

只需要vec3空间的2/3,因为你还没有使用z组件。

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