GLSL 330 Matrix-Computation Error {No compile error} - c++

Edit:
Alright got it now :D
Problem: Completly forgot glm uses colum-major matrices. Just had to change GL_TRUE, to GL_FALSE and everything is alright.
I try to compute my ModelMatrix with my ProjectionMatrix. Like so:
#version 330
layout(location = 0) in vec4 position;
layout(location = 1) in vec4 color;
uniform mat4 projectionMatrix; //This are the Matrixes from my cpp-app
uniform mat4 modelMatrix; //With a debugger that can show all active uniforms i checked their values: They're right!
uniform mat4 testUni; //Here I checked if its working when I precompute the model and perspective matrices in my source: works
mat4 viewMatrix = mat4(1.0f);
noperspective out vec4 vertColor;
mat4 MVP = projectionMatrix * modelMatrix ; //Should actually have the same value like testUni
void main()
{
gl_Position = testUni * position ; //Well... :) Works
gl_Position = MVP * position ; //Well... :) Doesn't work [Just the perspective Transforn]
vertColor = position;
}

Move the statement
mat4 MVP = projectionMatrix * modelMatrix ; //Should actually have the same value like testUni
into main(). Shader execution starts at main. If you want to avoid per-vertex computations, precompute the matrix outside and supply it as a uniform.

Related

GLSL shader uniform locations can't be found

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.
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.
I saw that the way you push the mat4 into the shader is a bit off. When I do "glUniformMatrix4fv" I say the first parameter is the ID of your shader, the one you get from "glCreateProgram()". The second is the name of the variable in the shader, so in your case "boneTransforms". The third is a "1". The fourth I put "GL_FALSE" not "false" but I don't think that should make a difference. The next is your first float of the mat4 which would look more like this :
&boneTransforms[0][0]

uniform sampler2D in Vertex Shader

I tried to realize height map with GLSL.
For it, i need to sent my picture to VertexShader and get grey component.
glActiveTexture(GL_TEXTURE0);
Texture.bind();
glUniform1i(mShader.getUniformLocation("heightmap"), 0);
mShader.getUniformLocation uses glGetUniformLocation and work good for other uniforms values, that used in Fragment, Vertex Shaders. But for heightmap return -1...
VertexShader code:
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec4 color;
layout (location = 2) in vec2 texCoords;
layout (location = 3) in vec3 normal;
out vec3 Normal;
out vec3 FragPos;
out vec2 TexCoords;
out vec4 ourColor;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform sampler2D heightmap;
void main()
{
float bias = 0.25;
float h = 0.0;
float scale = 5.0;
h = scale * ((texture2D(heightmap, texCoords).r) - bias);
vec3 hnormal = vec3(normal.x*h, normal.y*h, normal.z*h);
vec3 position1 = position * hnormal;
gl_Position = projection * view * model * vec4(position1, 1.0f);
FragPos = vec3(model * vec4(position, 1.0f));
Normal = mat3(transpose(inverse(model))) * normal;
ourColor = color;
TexCoords = texCoords;
}
may be algorithm of getting height is bad, but error with getting uniformlocation stops my work..
What is wrong? Any ideas?
UPD: texCoords (not TexCoords) of course is using in
h = scale * ((texture2D(heightmap, texCoords).r) - bias);
my mistake, but it doesn't solve the problem. Having same error..
My bet is your variable has been optimized out by driver or the shader did not compile/link properly. After trying to compile your shader (on my nVidia) I got this in the logs:
0(9) : warning C7050: "TexCoords" might be used before being initialized
You should always check the GLSL compile/link logs ? see
How to debug GLSL Fragment shader
especially how the glGetShaderInfoLog is used.
In line
h = scale * ((texture2D(heightmap, TexCoords).r) - bias);
You are using TexCoords which is output variable and not yet set so the behavior is undefined and most likely your gfx driver throw that line away (and may be others) removing the TexCoords from shader completely but that is just my assumption.
What driver and gfx card you got?
What returns the logs on your setup?

Why do I have to calculate the transpose of the inverse of the model matrix in order to calculate the normal for the reflection texture?

I am following this tutorial to create a skybox/cubemap with environmental mapping. I am having some trouble understanding a calculation in the vertex shader:
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
out vec3 Normal;
out vec3 Position;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(position, 1.0f);
Normal = mat3(transpose(inverse(model))) * normal;
Position = vec3(model * vec4(position, 1.0f));
}
Here, the author is calculating the Normal before passing it to the fragment shader to calculate the reflection texture:
Normal = mat3(transpose(inverse(model))) * normal;
My question is, what exactly does this calculation do? Why do you have to calculate the transpose of the inverse of the model matrix before multiplying it with the normal?
If you don't do this, uneven scaling will distort the normal. I think this sums it up, with pictures, better than I possibly could: http://www.lighthouse3d.com/tutorials/glsl-12-tutorial/the-normal-matrix/

Vertex Shader -> Geometry Shader, error "Getting the location of inactive Uniform"

I have something like the following setup,
Vertex Shader (... for irrelevant stuff):
#version 330 core
uniform mat4 ModelViewMatrix;
...
in vec4 position;
...
out vec4 out_position;
...
void main()
{
...
out_position = ModelViewMatrix * position;
...
}
Geometry Shader (... for irrelevant stuff):
#version 330 core
...
uniform mat4 ProjectionMatrix;
...
layout(lines) in;
layout(triangle_strip, max_vertices = 4) out;
in vec4 out_position[];
...
void main()
{
vec4 lineDirection = out_position[1] - out_position[0];
vec4 scaledLineWidthDir = ...;
...
gl_Position = ProjectionMatrix * (lineDirection - scaledLineWidthDir);
EmitVertex();
gl_Position = ProjectionMatrix * (lineDirection + scaledLineWidthDir);
EmitVertex();
gl_Position = ProjectionMatrix * (-lineDirection + scaledLineWidthDir);
EmitVertex();
gl_Position = ProjectionMatrix * (-lineDirection - scaledLineWidthDir);
EmitVertex();
EndPrimitive();
}
but when I try to run the shader it appears as if the ModelViewMatrix is not being used (I get "Getting the location of inactive uniform" when trying to set it up), even thought I am using it to compute the gl_Position in the geometry shader. What gives?
It is my understanding that the geometry shader here takes in 2 vertices, and outputs 4, for the fragment shader to use, am I understanding and using geometry shaders correctly?
Ok I figured out my issue.
I was using the wrong shader, which had the same vertice shader as the shader I am trying to use, so some of the uniforms worked, and others didn't and I got confused.

GLSL - Object disappears when multiplying by matrix

I've got this vertex shader:
#version 400
layout(location=0) in vec4 vertPosition;
layout(location=1) in vec2 vertUV;
layout(location=2) in vec3 vertNormal;
uniform mat4 MVP;
out vec3 fragPosition;
out vec2 fragUV;
out vec3 fragNormal;
void main(void){
gl_Position = MVP * vertPosition;
fragPosition = (MVP * vertPosition).rgb;
fragUV = vertUV;
fragNormal = (MVP * vec4(vertNormal,0)).rgb;
}
As soon as I'm multiplying vertPosition by MVP the object to render disappears, even if MVP is an identity matrix.
Here's the code where I'm setting MVP:
mat4 model = translate(mat4(), vec3(0,0,0));
mat4 view = translate(mat4(), vec3(0,0,-10));
mat4 proj = perspective(90.0f, (float)1280/720, 0.001f, 1000.0f);
mat4 MVP = model * view * proj;
GLint uniform_loc = glGetUniformLocation(this->_shaderID, "MVP");
glUniformMatrix4fv(uniform_loc, 1, GL_FALSE, value_ptr(matrix));
I tried different multiplication orders and multiplicating in the shader.
You've got the order in which you multiple MVP reversed. OpenGL matrix multiplication is column major right associative, hence it should be
mat4 MVP = proj * view * model;
A near clipping plane distance of 0.0001 is far too low. Essentially you're compressing all of the depth buffer resolution into a very small range. Make near as large as possible.
I don't get why you're selecting .rgb for the fragPosition and fragNormal.
From the look of your example you have forgotten to set the shader program before setting the uniform. Try using glUseProgram(this->program); (depending on where you've stored your program) before setting the matrix!