Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL returns -1 for an uniform that does exist and is used

Tags:

c++

opengl

I have this vertex shader:

#version 430 core

layout (location = 0) in vec3 position;
layout (location = 1) in vec2 textureCoordinate;
layout (location = 2) in vec3 normal;
layout (location = 4) in vec3 tangent;

uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
uniform vec3 lightPosition = vec3(0.0, 1.0, 0.0);

out vec2 texCoord;
out vec3 lightDirection;
out vec3 eyeDirection;

void main() {
    vec4 P = modelViewMatrix * vec4(position, 1.0);
    vec3 N = normalize(mat3(modelViewMatrix) * normal);
    vec3 T = normalize(mat3(modelViewMatrix) * tangent);
    vec3 B = cross(N, T);
    vec3 L = lightPosition - P.xyz;
    vec3 V = -P.xyz;

    lightDirection = normalize(vec3(dot(V, T), dot(V, B), dot(V, N)));
    eyeDirection = normalize(vec3(dot(V, T), dot(V, B), dot(V, N)));
    texCoord = textureCoordinate;

    gl_Position = projectionMatrix * P;
}

And this fragment shader:

#version 430 core

in vec2 texCoord;
in vec3 lightDirection;
in vec3 eyeDirection;

layout (binding = 0) uniform sampler2D tex;
layout (binding = 1) uniform sampler2D normalMap;

out vec4 color;

void main() {
    vec3 ambient = vec3(0.1);

    vec3 V = normalize(eyeDirection);
    vec3 L = normalize(lightDirection);
    vec3 N = normalize(texture(normalMap, texCoord)).rgb * 2.0 - vec3(1.0);
    vec3 R = reflect(-L, N);

    vec3 diffuseAlbedo = texture(tex, texCoord).rgb;
    /*vec3 diffuseAlbedo = vec3(1.0);*/
    vec3 diffuse = max(dot(N, L), 0.0) * diffuseAlbedo;

    vec3 specular = vec3(0.0);

    color = vec4(ambient + diffuse + specular, 1.0);
}

As you can see, the variable lightPosition is actually used in the calculations. But when I want to get the location of it via glGetUniformLocation, I get -1.

I looked through the other questions here on SO, like those ones:

  • glGetActiveUniform reports uniform exists, but glGetUniformLocation returns -1
  • glGetUniformLocation return -1 on nvidia cards
  • glGetUniformLocation() returning -1 even though used in vertex shader

Especially the last one - but in my case, lightPosition is used to calculate lightDirection and this is then used in the fragment shader. So it should not be removed.

Any ideas on what is going on here? Or how to debug this?

Also: I set a default value for the uniform. If I remove the default value, it still gives -1.

I am running Ubuntu 15.10 with Nvidia 340.96 drivers and a GF 710M card. I am running OpenGL 4.4 with core profile.

like image 467
Paweł Pela Avatar asked Oct 14 '25 14:10

Paweł Pela


1 Answers

... As you can see, the variable lightPosition is actually used in the calculations. ...

You would think, right. Actually you're using it once in the Vertex Shader to assign a value to vec3 L, which is not actually used after that.

The compilation process for the shaders is very meticulous. You may have used it in a calculation in the Vertex Shader, but you didn't utilize the result L anywhere and it doesn't make any contribution to the final result calculated in the Fragment Shader, so it was "optimized away".

You must give some use to L.

like image 160
aslg Avatar answered Oct 17 '25 03:10

aslg