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!


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\$ – Jack Aidley Sep 6 '18 at 8:42

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.