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);
glBindVertexArray(VAO);
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]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(int), &indices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
glEnableVertexAttribArray(1);
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.use();
shader.setMat4("model", model);
shader.setMat4("view", view);
shader.setMat4("projection", projection);
shader.setFloat("TERRAIN_WIDTH",gridXNum);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLE_STRIP, numIndices, GL_UNSIGNED_INT, 0);
glBindVertexArray(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!