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

标签 opengl textures shader vertex heightmap

我一直在尝试为我的地形着色器实现高度图,但地形仍然平坦。纹理已正确加载到顶点着色器中,我尝试使用基于网格 uv 的纹理的灰度值来调整顶点高度:

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

}

一些附加信息: 所有纹理都像这样加载到我的地形 Material 中并传递到着色器(工作正常):

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

平面网格 uv 的映射如下:

(0,1) (1,1)

(0,0) (1,0)

我想我做了一些非常错误的事情,但我不知道是什么。如有任何帮助,我们将不胜感激!

最佳答案

你写的是:

The plane mesh uvs are mapped like this:

(0,1) (1,1)

(0,0) (1,0)

...意味着您的网格仅由 4 个顶点组成?如果是这样,那么这就是您的问题:顶点着色器无法神奇地创建"new"顶点,因此您的高度图纹理仅在 4 个点处进行采样(中间没有任何内容)。

因为您以整数值和纹理坐标在 0 和 1 处对纹理坐标进行采样,所以您实际上是在对完全相同的纹理坐标进行采样,因此您将看到所有四个顶点的相同位移。

解决方案:对基础网格进行分割,以便实际上有可用于替换的顶点。曲面分割着色器非常适合这一点。

编辑:

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

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

关于OpenGL:在顶点着色器中使用高度图进行地形变形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41804142/

相关文章:

c++ - 如何检查当前在 OpenGL 中绑定(bind)了哪个帧缓冲区对象?

c++ - 无法向 GL_QUAD 添加纹理

ios - 是否有常见 OpenGL 着色器的常用来源?

javascript - 读取 WebGLTexture 中的像素(将 WebGL 渲染到纹理)

ios - 将纹理设置为彩色 CC3MeshNode

c - OpenGL 着色器编译代码位于何处?

c++ - OpenGL 统一函数 - 为什么这么多?

c - 带时序的流动动画 (OpenGL)

java - OpenGL 着色器不工作?

c++ - glColor 不工作,随机颜色出现