2013-02-03 38 views
1

当我在计算机上运行该程序时,它的工作原理与我预期的一样。但是,当我尝试在校园实验室计算机上运行它时,片段着色器各种奇怪。片段着色器在不同的计算机上执行的方式不同

现在,它只是一个简单的Phong照明计算,其中点光源在原点。但是,在实验室电脑上,它看起来更像是cel阴影和手电筒之间的一种奇怪的交叉。我运行ATI显卡,而实验室电脑运行NVIDIA。阴影在Mac上也按预期工作(不知道显卡)。

NVIDIA卡支持OpenGL 3.1,尽管我在2.1版本的Linux发行版上运行它。我已经尝试将着色器版本固定为1.2(GLSL),其中包括其他许多东西,但它们的效果相同。最奇怪的是,当我使用顶点着色而不是像素着色时,两台计算机的结果都是一样的......我已经用尽了我的想法来解决这个问题。

这里的顶点着色器:

#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; 
} 

而片段着色器:

#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

你可以发布你的代码和/或屏幕截图吗?盲目调试图形代码很困难。 – duskwuff

+0

我已添加代码,但目前无法发布屏幕截图。目前我正在家工作,无法访问其他计算机。 –

+0

GLSL编译/链接日志中的任何内容? – genpfault

回答

3

你的代码看起来错在很多很多方面。

以下代码错误。评论是误导性的(它在剪辑空间,而不是世界空间)。但是主要的问题在于,在使用剪辑空间坐标的同时,您将覆盖vPosition,就好像它在视图空间中一样。

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

以下代码也是错误的。首先你需要matrix * vector,而不是vector * matrix。但同时,该评论说世界空间,但你在视图空间计算vLight并添加vPosition这是夹空间

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

此处同样matrix * vector

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

现在这是什么? camPos以世界坐标计算,但您应用将模型空间转换为世界空间的模型矩阵。

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

我不知道为什么你的着色器不同的计算机上执行不同,但我敢肯定没有这些计算机的显示任何远程接近预期的结果。

真的需要重新读你的着色器,每次你看到一个载体,问自己“什么坐标空间是这个载体有意义吗?”每次你看到一个矩阵时,问自己“什么坐标空间这个矩阵是否可以转换为?“

相关问题