1

I have a quad, composed by two triangles, defined like so:

glm::vec3 coords[] = {
        glm::vec3(-1.0f, -1.0f, -0.1f),
        glm::vec3( 1.0f, -1.0f, -0.1f),
        glm::vec3( 1.0f,  1.0f, -0.1f),
        glm::vec3(-1.0f,  1.0f, -0.1f)
    };

    glm::vec3 normals[] = {
        glm::vec3(0.0f, 0.0f, 1.0f),
        glm::vec3(0.0f, 0.0f, 1.0f),
        glm::vec3(0.0f, 0.0f, 1.0f),
        glm::vec3(0.0f, 0.0f, 1.0f)
    };

    glm::vec2 texCoords[] = {
        glm::vec2(0.0f, 0.0f),
        glm::vec2(1.0f, 0.0f),
        glm::vec2(1.0f, 1.0f),
        glm::vec2(0.0f, 1.0f)
    };

    unsigned int indices[] = {
        0, 1, 2,
        2, 3, 0
    };

I'm trying to change the quad's 'height' via a black and white jpg so I wrote a vertex shader to do this, however the transformation is not being applied directly to all the points of the quad. Here's the jpg I'm using: heightmap I expect a sudden constant bump where the image turns white, but this is what I'm getting: https://i.gyazo.com/639a699e7aa12cda2f644201d787c507.gif. It appears that only the top left corner is reaching the maximum height, and that somehow the whole entire left triangle is being distorted.

My vertex shader:

layout(location = 0) in vec3 vertex_position;
layout(location = 1) in vec3 vertex_normal;
layout(location = 2) in vec2 vertex_texCoord;
layout(location = 3) in vec4 vertex_color;

out vec2 v_TexCoord;
out vec4 v_Color;
out vec3 v_Position;
out vec3 v_Normal;

//model view projection matrix
uniform mat4 u_MVP;
uniform mat4 u_ModelMatrix;
uniform sampler2D u_Texture1_Height;

void main()
{
    v_TexCoord = vertex_texCoord;
    v_Color = vertex_color;
    v_Normal = mat3(u_ModelMatrix) * vertex_normal;

    vec4 texHeight = texture(u_Texture1_Height, v_TexCoord);
    vec3 offset = vertex_normal * (texHeight.r + texHeight.g + texHeight.b) * 0.33;
    
    v_Position = vec3(u_ModelMatrix * vec4(vertex_position + offset, 1.0f));

    gl_Position = u_MVP * vec4(vertex_position + offset, 1.0f);
}
136
  • 1,083
  • 1
  • 7
  • 14

1 Answers1

1

The bump map is just evaluated per vertex rather than per fragment, because you do the computation in the vertex shader. The vertex shader is just executed for each vertex (for each corner of the quad). Compare Vertex Shader and Fragment Shader.

It is not possible to displace the clip space coordinate for each fragment. You have to tessellate the geometry (the quad) to a lot of small quads. Since the vertex shader is executed for each fragment, the geometry is displaced for each corner point in the mesh. This is the common approach. See this simulation.

Another possibility is to implement parallax mapping, where a depth effect is accomplished by displacing the texture coordinates and distort the normal vectors in the fragment shader. See Normal, Parallax and Relief mapping respectively LearnOpenGL - Parallax Mapping or Bump Mapping with glsl.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • @136 I recommend to tessellate the mesh once on the CPU (or in a post process on the GPU [Transform Feedback](https://www.khronos.org/opengl/wiki/Transform_Feedback)), because tessellation shaders are slow in compare to a simple VS/FS setup. The tessellation shader is performed after the vertex shader, so you have to compute the offset in the tessellation evaluation shader. – Rabbid76 Jul 26 '20 at 06:01