I'm currently using a vertex shader and a fragment shader for loading my texture onto the terrain I made.

Here is my vertex shader

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

float scale = 0.5;

out vec2 TexX;
out vec2 TexY;
out vec2 TexZ;
out vec3 blend_weights;

void main()
    vec3 blend_weights = abs(aNormal.xyz);
    blend_weights = (blend_weights - 0.2) * 0.7;
    blend_weights = max(blend_weights, 0);
    blend_weights /= (blend_weights.x + blend_weights.y + blend_weights.z);

    TexX = aPos.yz * scale;
    TexY = aPos.zx * scale; 
    TexZ = aPos.xy * scale;

    gl_Position = projection * view * model * vec4(aPos, 1.0);

And here is my fragment shader.

#version 330 core
out vec4 FragColor;

uniform sampler2D terrainTexture;

in vec2 TexX;
in vec2 TexY;
in vec2 TexZ;

in vec3 blend_weights;

void main()
    FragColor = texture(terrainTexture, TexX)*blend_weights.x + texture(terrainTexture, TexY)*blend_weights.y + texture(terrainTexture, TexZ)*blend_weights.z;

I was trying to implement 3D texture planar projections, based on section 1.5 of this link https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch01.html

If I just try to implement the texture in a very simple way, it works (which looks terribly stretched on the mountanous terrains, of course). But if I implement it this way, the texture does not load. What could be the possible reason?

Just in case anyone is wondering, the following is my VAO, VBO, EBO configuration

// VAO, VBO configuration
    unsigned int VAO, VBO, EBO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, positions.size()*sizeof(glm::vec3) + normals.size() * sizeof(glm::vec3) , NULL, GL_STATIC_DRAW);
    glBufferSubData(GL_ARRAY_BUFFER, 0, positions.size() * sizeof(glm::vec3), &positions[0]);
    glBufferSubData(GL_ARRAY_BUFFER, positions.size() * sizeof(glm::vec3), normals.size() * sizeof(glm::vec3), &normals[0]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(int), &indices[0], GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)(positions.size() * sizeof(glm::vec3)));

This is my draw function

// Inside the render loop
void drawScene(Shader &shader, unsigned int VAO, unsigned int numIndices, unsigned int texture1)    //draw the scene with the parameter data.
    glm::mat4 model;
    model = glm::translate(model, glm::vec3(-(int)(gridXNum)/2, 0.0f, -(int)(gridZNum)/2));
    glm::mat4 view = camera.GetViewMatrix();
    glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);

    shader.setMat4("model", model);
    shader.setMat4("view", view);
    shader.setMat4("projection", projection);

    glBindTexture(GL_TEXTURE_2D, texture1);

    glDrawElements(GL_TRIANGLE_STRIP, numIndices, GL_UNSIGNED_INT, 0);

However, I really don't think this is the problem because as I said, if I change the shader codes into a really basic one, the texture successfully loads. There is definitely something wrong with my shader program. Any help would be appreciated. Thanks in advance!


1 Answer 1


I found the answer. It was just a stupid mistake.

out vec3 blend_weights;

void main()
    vec3 blend_weights = abs(aNormal.xyz); ...

After I declared an output vec3, I declared another vec3 inside the main() with the same name. That's why the information disappeared as soon as the program exited the main() function. Sorry for the trouble!

  • \$\begingroup\$ Be sure to accept your answer as correct. \$\endgroup\$ Sep 6, 2018 at 8:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .