4
votes

I'm working on a vertex skinning shader, and for some reason my program can't find the uniform locations.

Vertex shader code:

#version 330

const int MAX_JOINTS = 30;
const int MAX_WEIGHTS = 3;

in vec3 position;
in vec2 textureCoords;
in vec3 normal;
in ivec3 boneIndices;
in vec3 weights;

out vec4 fragPos;
out vec3 n;
out vec2 texCoords;
out vec4 mcolor;


uniform mat4 modelMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 normalMatrix;

uniform mat4[MAX_JOINTS] boneTransforms;


void main() {



vec4 totalLocalPos = vec4(0.0);
vec4 totalNormal = vec4(0.0);

for(int i = 0; i < 3; i++){
    mat4 boneTransform = boneTransforms[boneIndices[i]];
    vec4 posePosition = boneTransform * vec4(position, 1);
    totalLocalPos += posePosition * weights[i];

    vec4 worldNormal = boneTransform * vec4(normal, 1);
    totalNormal += worldNormal * weights[i];
}
texCoords = textureCoords;

fragPos = modelMatrix * vec4(position,1);

n = totalNormal.xyz;


gl_Position = projectionMatrix * viewMatrix * modelMatrix * totalLocalPos;
}

The boneTransforms uniform doesn't seem to be set correctly; if I query the active uniforms with

GLint uniforms;
    glGetProgramiv(shaderProgramID, GL_ACTIVE_UNIFORMS, &uniforms);
    for (int i = 0; i < uniforms; i++){
        int name_len = -1, num = -1;
        GLenum type = GL_ZERO;
        char name[100];
        glGetActiveUniform(shaderProgramID, GLuint(i), sizeof(name) - 1,
            &name_len, &num, &type, name);
        name[name_len] = 0;

    }

i always get zero; However, if I just put gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position,1) I get the expected result (correct rendering without any vertex skinning), so the other transforms appear to be working despite it telling me they don't exist? EDIT: this is sometimes the case, other times I get the model at position (0,0,0) but otherwise rendered correctly with this.

I have read about the compiler stripping unused/inactive uniforms, but if I use boneTransforms to calculate totalLocalPos and use that for gl_Positions the uniform should be active.

I try to set the uniform with

vector<glm::mat4> boneTransforms = model.getBoneTransforms();
int location = glGetUniformLocation(shaderProgramID, "boneTransforms");
glUniformMatrix4fv(location, boneTransforms.size(), false, (GLfloat*)&boneTransforms);

location is always -1. Is there something wrong with how I try to set this particular uniform, or is the mistake in the shader code?

EDIT2: I just noticed that the behaviour of my shader changes when I add or remove objects (which use a different shader) from the scene. I don't know what to make of that.
EDIT3: If I remove all other meshes from my scene the shader crashes with an access violation. As long as one other object is being rendered there are currently no crashes.
another EDIT: Apparently accessing the weights variable crashes my shader.

1
You should check that glGetProgramiv and glGetActiveUniform don't raise any errors.G.M.
I suspect as the above poster has stated that your program failed to compile, which is why you get 0 found uniforms.PaulHK
I checked with glGetError() and didn't get any error codes. If the program failed to compile wouldn't that meant that i'd get not output at all?dragon
glGetError won't report shader compilation failureBartek Banachewicz
Again, if the shader didn't compile it wouldn't render the mesh at all, right? It does get rendered, just not correctly. Edit: apparently I do get shader errors, but why am I seeing anything at all in this case?dragon

1 Answers

0
votes

I was reading this quick tutorial about vertex skinning shader found here: khronos and it seems to be using a slightly older version of GLSL how ever they do make a mention about the multiplication of the MVP matrix(model view proj matrix) or in your case the PVM matrix( proj view model matrix) with the vec4 for total position in you case and storing it back into gl_Position and they claim that the w may not always have a value of 1 so to be safe they recommend doing this instead and I'll use your code as their example to fix this possible problem.

Change this:

gl_Position = projectionMatrix * viewMatrix * modelMatrix * totalLocalPos;

To this:

gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(totalLocalPos.xyz, 1.0);

To see if this helps you out. I don't know if this is the cause of your problem or not but from what you have shown your shader appears to be okay other than that.