PDA

View Full Version : Help converting from glsl 400 to 130



kaboom
09-20-2015, 01:25 PM
I need to convert these shaders from #version 400 core to #version 130 successfully but for some reason when I do it my models are not rendering properly when I load more then one type and I cant find any other issues with my code

Version 400 (vertexShader):


#version 400 core

in vec3 position;
in vec2 textureCoords;
in vec3 normal;

out vec2 pass_textureCoords;
out vec3 surfaceNormal;
out vec3 toLightVector;
out vec3 toCameraVector;
out float visibility;

uniform mat4 transformationMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform vec3 lightPosition;

uniform float useFakeLighting;
uniform vec2 offset;

const float density = 0.004;
const float gradient = 1.5;

void main(void) {

vec4 worldPosition = transformationMatrix * vec4(position, 1.0);
vec4 positionRelativeToCam = viewMatrix * worldPosition;
gl_Position = projectionMatrix * positionRelativeToCam;
pass_textureCoords = textureCoords;

vec3 actualNormal = normal;
if(useFakeLighting > 0.5) {
actualNormal = vec3(0.0, 1.0, 0.0);
}

surfaceNormal = (transformationMatrix * vec4(actualNormal, 0.0)).xyz;
toLightVector = lightPosition - worldPosition.xyz;
toCameraVector = (inverse(viewMatrix) * vec4(0.0, 0.0, 0.0, 1.0)).xyz - worldPosition.xyz;

float distance = length(positionRelativeToCam.xyz);
visibility = exp(-pow((distance * density), gradient));
visibility = clamp(visibility, 0.0, 1.0);

}

and heres my version 130 vertexShader:


#version 130

in vec3 position;
in vec2 textureCoords;
in vec3 normal;

out vec2 pass_textureCoords;
out vec3 surfaceNormal;
out vec3 toLightVector;
out vec3 toCameraVector;
out float visibility;

uniform mat4 transformationMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform vec3 lightPosition;

uniform float useFakeLighting;
uniform vec2 offset;

const float density = 0.004;
const float gradient = 1.5;

void main(void) {

vec4 worldPosition = transformationMatrix * vec4(position, 1.0);
vec4 positionRelativeToCam = viewMatrix * worldPosition;
gl_Position = projectionMatrix * positionRelativeToCam;
pass_textureCoords = textureCoords;

vec3 actualNormal = normal;
if(useFakeLighting > 0.5) {
actualNormal = vec3(0.0, 1.0, 0.0);
}

surfaceNormal = (transformationMatrix * vec4(actualNormal, 0.0)).xyz;
toLightVector = lightPosition - worldPosition.xyz;
toCameraVector = (transpose(viewMatrix) * vec4(0.0, 0.0, 0.0, 1.0)).xyz - worldPosition.xyz;

float distance = length(positionRelativeToCam.xyz);
visibility = exp(-pow((distance * density), gradient));
visibility = clamp(visibility, 0.0, 1.0);

}


I swapped out the inverse for transpose as its not supported in glsl 130 apparently. Theres also a small change in the fragment shaders as below:
Core 400 version fragment:


#version 400 core

in vec2 pass_textureCoords;
in vec3 surfaceNormal;
in vec3 toLightVector;
in vec3 toCameraVector;
in float visibility;

out vec4 out_Color;

uniform sampler2D modelTexture;
uniform vec3 lightColour;
uniform float shineDamper;
uniform float reflectivity;
uniform vec3 skyColour;

void main(void) {

vec3 unitNormal = normalize(surfaceNormal);
vec3 unitLightVector = normalize(toLightVector);

float nDot1 = dot(unitNormal, unitLightVector);
float brightness = max(nDot1, 0.2);
vec3 diffuse = brightness * lightColour;

vec3 unitVectorToCamera = normalize(toCameraVector);
vec3 lightDirection = -unitLightVector;
vec3 reflectedLightDirection = reflect(lightDirection, unitNormal);

float specularFactor = dot(reflectedLightDirection, unitVectorToCamera);
specularFactor = max(specularFactor, 0.0);
float dampedFactor = pow(specularFactor, shineDamper);
vec3 finalSpecular = dampedFactor * reflectivity * lightColour;
vec4 textureColour = texture(modelTexture, pass_textureCoords);

if(textureColour.a < 0.5) {
discard;
}

out_Color = vec4(diffuse, 1.0) * textureColour + vec4(finalSpecular, 1.0);
out_Color = mix(vec4(skyColour, 1.0), out_Color, visibility);

}


and the 130 version:


#version 130

in vec2 pass_textureCoords;
in vec3 surfaceNormal;
in vec3 toLightVector;
in vec3 toCameraVector;
in float visibility;

out vec4 out_Color;

uniform sampler2D modelTexture;
uniform vec3 lightColour;
uniform float shineDamper;
uniform float reflectivity;
uniform vec3 skyColour;

void main(void) {

vec3 unitNormal = normalize(surfaceNormal);
vec3 unitLightVector = normalize(toLightVector);

float nDot1 = dot(unitNormal, unitLightVector);
float brightness = max(nDot1, 0.2);
vec3 diffuse = brightness * lightColour;

vec3 unitVectorToCamera = normalize(toCameraVector);
vec3 lightDirection = -unitLightVector;
vec3 reflectedLightDirection = reflect(lightDirection, unitNormal);

float specularFactor = dot(reflectedLightDirection, unitVectorToCamera);
specularFactor = max(specularFactor, 0.0);
float dampedFactor = pow(specularFactor, shineDamper);
vec3 finalSpecular = dampedFactor * reflectivity * lightColour;
vec4 textureColour = texture2D(modelTexture, pass_textureCoords);

if(textureColour.a < 0.5) {
discard;
}

out_Color = vec4(diffuse, 1.0) * textureColour + vec4(finalSpecular, 1.0);
out_Color = mix(vec4(skyColour, 1.0), out_Color, visibility);

}

You can't use texture in the 130 core so I used texture2d and it works fine when I am loading only one model type but when I add the other models, they lose vertex positions and I am not sure as to why so i want to make sure these are converted properly. Thanks in advance.

GClements
09-20-2015, 03:58 PM
I swapped out the inverse for transpose as its not supported in glsl 130 apparently.

A matrix' inverse and its transpose are only equivalent if the matrix is orthonormal. This is true for a matrix constructed from a combination of rotations and uniform scalings. It isn't true for a 4x4 matrix which has a translation component.

To invert an matrix constructed solely of rotations and translations, transpose the upper-left 3x3 submatrix, then transform the translation component (the first three rows of the right-hand column) by the transposed 3x3 submatrix and negate the result. e.g.



void restricted_inverse(mat4 src, out mat4 dst)
{
mat3 m = transpose(mat3(src));
vec3 v = vec3(src[3]);
dst = mat4(m);
dst[3] = vec4(-m*v,1.0);
}

kaboom
09-23-2015, 03:12 PM
I tried to add this in my vertexShader as suggested

void restricted_inverse(mat4 viewMatrix, out mat4 realViewMatrix) {
mat3 m = transpose(mat3(viewMatrix));
vec3 v = vec3(viewMatrix[3]);
dst = mat4(m);
dst[3] = vec4(-m * v, 1.0);
}


toCameraVector = (realViewMatrix * vec4(0.0, 0.0, 0.0, 1.0)).xyz - worldPosition.xyz;

and when I run it I get this error (in eclipse):
Wed Sep 23 15:08:39 CST 2015 INFO:Use Java PNG Loader = true
Could not compile shader.ERROR: 0:42: '{' : syntax error parse error

I am new to using glsl shading programs. What am I doing wrong here? I don't expect people to write my code for me for my game, but this bug has been bugging me for a while now and I cant seem to figure it out. Thanks in advance.

mbentrup
09-24-2015, 02:49 AM
A matrix' inverse and its transpose are only equivalent if the matrix is orthonormal. This is true for a matrix constructed from a combination of rotations and uniform scalings.

This is only true if the scaling factor is 1 or -1, so only rotations and mirroring is allowed.


I tried to add this in my vertexShader as suggested

void restricted_inverse(mat4 viewMatrix, out mat4 realViewMatrix) {
mat3 m = transpose(mat3(viewMatrix));
vec3 v = vec3(viewMatrix[3]);
dst = mat4(m);
dst[3] = vec4(-m * v, 1.0);
}



This is a function definition which may not be placed inside the main() function. You can put this function definition before main() and then call it with
mat4 realViewMatrix;
restricted_inverse(viewMatrix, realViewMatrix);.

GClements
09-24-2015, 05:16 AM
A matrix' inverse and its transpose are only equivalent if the matrix is orthonormal. This is true for a matrix constructed from a combination of rotations and uniform scalings.
This is only true if the scaling factor is 1 or -1, so only rotations and mirroring is allowed.
Indeed. That's implied by "orthonormal"; the "and uniform scalings" part was an editing failure on my part, left over from an earlier draft (a matrix constructed only from rotations and uniform scalings will be orthogonal but not orthonormal).

Getting back to the original problem: something which hasn't yet been mentioned is that, as the matrix being inverted is a uniform variable, another option is to pass the inverse of the view matrix as a separate uniform variable. This avoids the overhead of re-calculating the inverse for each vertex in the vertex shader.

kaboom
09-24-2015, 10:29 AM
I updated my shader to just have the code and I can call the construction with no code in it, but as soon as I add the code it throws this error in my console:
Thu Sep 24 10:26:17 CST 2015 INFO:Use Java PNG Loader = true
ERROR: 0:29: 'dst' : undeclared identifier
ERROR: 0:29: 'assign' : cannot convert from '4X4 matrix of float' to 'float'
ERROR: 0:30: 'dst' : left of '[' is not of type array, matrix, or vector
ERROR: 0:30: 'assign' : cannot convert from '4-component vector of float' to 'float'

Here is what I put in my shader file. As you can see I have the constructor there but I am not even calling it anywhere yet I get these errors. As I said I am new to using GLSL shaders.


#version 130

in vec3 position;
in vec2 textureCoords;
in vec3 normal;

out vec2 pass_textureCoords;
out vec3 surfaceNormal;
out vec3 toLightVector;
out vec3 toCameraVector;
out float visibility;

uniform mat4 transformationMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform vec3 lightPosition;

uniform float useFakeLighting;
uniform float numberOfRows;
uniform vec2 offset;

const float density = 0.004;
const float gradient = 1.5;

void restricted_inverse(mat4 viewMatrix, out mat4 realViewMatrix) {
mat3 m = transpose(mat3(viewMatrix));
vec3 v = vec3(viewMatrix[3]);
dst = mat4(m);
dst[3] = vec4(-m * v, 1.0);
}

void main(void) {

vec4 worldPosition = transformationMatrix * vec4(position, 1.0);

vec4 positionRelativeToCam = viewMatrix * worldPosition;
gl_Position = projectionMatrix * positionRelativeToCam;
pass_textureCoords = (textureCoords / numberOfRows) + offset;

vec3 actualNormal = normal;
if(useFakeLighting > 0.5) {
actualNormal = vec3(0.0, 1.0, 0.0);
}

surfaceNormal = (transformationMatrix * vec4(actualNormal, 0.0)).xyz;
toLightVector = lightPosition - worldPosition.xyz;

toCameraVector = (transpose(-(viewMatrix)) * vec4(0.0, 0.0, 0.0, 1.0)).xyz - worldPosition.xyz;

float distance = length(positionRelativeToCam.xyz);
visibility = exp(-pow((distance * density), gradient));
visibility = clamp(visibility, 0.0, 1.0);

}

Here is my source code:
megafileupload.com/5c1v/Redwall.rar

GClements
09-24-2015, 03:16 PM
I updated my shader to just have the code and I can call the construction with no code in it, but as soon as I add the code it throws this error in my console:
Thu Sep 24 10:26:17 CST 2015 INFO:Use Java PNG Loader = true
ERROR: 0:29: 'dst' : undeclared identifier
ERROR: 0:29: 'assign' : cannot convert from '4X4 matrix of float' to 'float'
ERROR: 0:30: 'dst' : left of '[' is not of type array, matrix, or vector
ERROR: 0:30: 'assign' : cannot convert from '4-component vector of float' to 'float'

The example I posted used "src" and "dst" for the parameter names. You changed these to viewMatrix and realViewMatrix respectively. But you only changed dst to realViewMatrix in the argument declaration, and left it unchanged in the function body.

kaboom
09-25-2015, 11:38 AM
The example I posted used "src" and "dst" for the parameter names. You changed these to viewMatrix and realViewMatrix respectively. But you only changed dst to realViewMatrix in the argument declaration, and left it unchanged in the function body.

Wow thanks lol. I feel like an absolute bell end.