2013-02-03 42 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; 

我不知道爲什麼你的着色器不同的計算機上執行不同,但我敢肯定沒有這些計算機的顯示任何遠程接近預期的結果。

真的需要重新讀你的着色器,每次你看到一個載體,問自己「什麼座標空間是這個載體有意義嗎?」每次你看到一個矩陣時,問自己「什麼座標空間這個矩陣是否可以轉換爲?「

相關問題