1
votes

When I run the program on my computer, it works exactly how I expected it to be working. However, when I try to run it on my campus lab computers, the fragment shader is all kinds of strange.

Right now it's just a simple Phong lighting calculation with a point source light at the origin. However, on the lab computers, it looks more like some strange cross between cel shading and a flashlight. I run an ATI graphics card, while the lab computers run NVIDIA. The shading works as expected on Macs as well (no idea about the graphics card).

The NVIDIA cards support up to OpenGL 3.1, though I run it on this Linux distribution at 2.1. I've tried clamping the shader version to 1.2 (GLSL), among a slew of other things, but they achieve the same results. The strangest thing is that when I do vertex shading rather than pixel shading, the result is the same on both computers...I've exhausted my ideas about how to fix this.

Here's the vertex shader:

#version 120

  attribute vec2 aTexCoord;
  attribute vec3 aPosition;
  attribute vec3 aNormal;
  attribute vec3 camLoc;
  attribute float mat;

  varying vec3 vColor;
  varying vec2 vTexCoord;
  varying vec3 normals;
  varying vec3 lightPos;
  varying vec3 camPos;
  varying float material;


uniform mat4 uProjMatrix;
uniform mat4 uViewMatrix;
uniform mat4 uModelMatrix;
uniform mat4 uNormMatrix;

uniform vec3 uLight;
uniform vec3 uColor;

void main()
{
  //set up object position in world space
  vec4 vPosition = uModelMatrix * vec4(aPosition, 1.0);
  vPosition = uViewMatrix * vPosition;
  vPosition = uProjMatrix * vPosition;
  gl_Position = vPosition;

  //set up light vector in world space
  vec4 vLight = vec4(uLight, 1.0) * uViewMatrix;
  lightPos = vLight.xyz - vPosition.xyz;

  //set up normal vector in world space
  normals = (vec4(aNormal,1.0) * uNormMatrix).xyz;

  //set up view vector in world space
  camPos = camLoc.xyz - vPosition.xyz;

  //set up material shininess
  material = mat;

  //pass color and vertex
  vColor = uColor;
  vTexCoord = aTexCoord;
}

And the fragment shader:

#version 120

  varying vec3 lightPos;
  varying vec3 normals;
  varying vec3 camPos;
  varying vec2 vTexCoord;
  varying vec3 vColor;
  varying float material;

uniform sampler2D uTexUnit;

uniform mat4 uProjMatrix;
uniform mat4 uViewMatrix;
uniform mat4 uModelMatrix;

void main(void) 
{
  float diffuse;
  float diffuseRed, diffuseBlue, diffuseGreen;
  float specular;
  float specRed, specBlue, specGreen;
  vec3 lightColor = vec3(0.996, 0.412, 0.706); //color of light (HOT PINK) **UPDATE WHEN CHANGED**
  vec4 L; //light vector
  vec4 N; //normal vector
  vec4 V; //view vector
  vec4 R; //reflection vector
  vec4 H; //halfway vector
  float red;
  float green;
  float blue;
  vec4 texColor1 = texture2D(uTexUnit, vTexCoord);

      //diffuse calculations
        L = vec4(normalize(lightPos),0.0);
        N = vec4(normalize(normals),0.0);
        N = uModelMatrix * N;

        //calculate RGB of diffuse light
        diffuse = max(dot(N,L),0.0);
        diffuseRed = diffuse*lightColor[0];
        diffuseBlue = diffuse*lightColor[1];
        diffuseGreen = diffuse*lightColor[2];

      //specular calculations
        V = vec4(normalize(camPos),0.0);
        V = uModelMatrix * V;

        R = vec4(-1.0 * L.x, -1.0 * L.y, -1.0 * L.z, 0.0);
        float temp = 2.0*dot(L,N);
        vec3 tempR = vec3(temp * N.x, temp * N.y, temp * N.z);
        R = vec4(R.x + tempR.x, R.y + tempR.y, R.z + tempR.z, 0.0);
        R = normalize(R);

        H = normalize(L + V);

        specular = dot(H,R);
        specular = pow(specular,material);
        specRed = specular*lightColor[0];
        specBlue = specular*lightColor[1];
        specGreen = specular*lightColor[2];

      //set new colors
        //textures
        red = texColor1[0]*diffuseRed + texColor1[0]*specRed*0.7 + texColor1[0]*.05;
        green = texColor1[1]*diffuseBlue + texColor1[1]*specBlue*0.7 + texColor1[1]*.05;
        blue = texColor1[2]*diffuseGreen + texColor1[2]*specGreen*0.7 + texColor1[2]*.05;

        //colors
        red = vColor[0]*diffuseRed + vColor[0]*specRed*0.7 + vColor[0]*.05;
        green = vColor[1]*diffuseBlue + vColor[1]*specBlue*0.7 + vColor[1]*.05;
        blue = vColor[2]*diffuseGreen + vColor[2]*specGreen*0.7 + vColor[2]*.05;

      gl_FragColor = vec4(red, green, blue, 1.0);
}
1
Can you post your code, and/or screenshots? It's tough to debug graphics code blind. - user149341
I've added the code, but I can't currently post screenshots. I'm working from home at the moment and don't have access to the other computer. - Bhargav B
Anything in the GLSL compilation/link logs? - genpfault
On my computer (ATI card) it compiles cleanly. On the NVIDIA, sometimes it'll warn me about using deprecated variable declarations (varying and attribute as opposed to in and out), and it'll do this even with the version clamp at 1.2. It might also complain about using the deprecated gl_FragColor (which I know how to replace) sometimes. - Bhargav B
Also good would be to have the GL_RENDERER strings of the machines (glGetString). - datenwolf

1 Answers

3
votes

Your code looks wrong in many, many ways.

The following code is wrong. The comment is misleading (it’s in clip space, not world space). But the major problem is that you overwrite vPosition with the clip space coordinates while using it as if it was in view space several lines after this part.

//set up object position in world space
vec4 vPosition = uModelMatrix * vec4(aPosition, 1.0);
vPosition = uViewMatrix * vPosition;
vPosition = uProjMatrix * vPosition;
gl_Position = vPosition;

The following code is wrong, too. First you need matrix * vector, not vector * matrix. But also, the comment says world space, yet you compute vLight in view space and add vPosition which is in clip space!

//set up light vector in world space
vec4 vLight = vec4(uLight, 1.0) * uViewMatrix;
lightPos = vLight.xyz - vPosition.xyz;

Again here, matrix * vector:

//set up normal vector in world space
normals = (vec4(aNormal,1.0) * uNormMatrix).xyz;

Now what is this? camPos is computed in world coordinates, yet you apply the model matrix which converts model space to world space.

//specular calculations
V = vec4(normalize(camPos),0.0);
V = uModelMatrix * V;

I have no idea why your shader performs differently on different computers, but I am pretty sure none of these computers shows anything remotely close to the expected result.

You really need to read your shaders again, and each time you see a vector, ask yourself “in what coordinate space is this vector meaningful?” and each time you see a matrix, ask yourself “what coordinate spaces does this matrix convert from and to?”