当我在我的计算机上运行该程序时,它完全按照我的预期运行。然而,当我尝试在我的校园实验室计算机上运行它时,片段着色器有各种各样的奇怪之处。
现在它只是一个简单的 Phong 光照计算,在原点有一个点光源。然而,在实验室计算机上,它看起来更像是 cel shading 和手电筒之间的一些奇怪的交叉。我运行 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);
}
最佳答案
您的代码在很多很多方面看起来都是错误的。
下面的代码是错误的。该评论具有误导性(它在剪辑空间中,而不是世界空间中)。但主要问题是您在使用剪辑空间坐标时用 vPosition
覆盖它,就好像它在这部分之后几行的 View 空间中一样。
//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
。而且,评论说 world space,但您在 view space 中计算 vLight
并添加 vPosition
剪辑空间!
//set up light vector in world space
vec4 vLight = vec4(uLight, 1.0) * uViewMatrix;
lightPos = vLight.xyz - vPosition.xyz;
同样,矩阵 * 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;
我不知道为什么你的着色器在不同的计算机上表现不同,但我很确定这些计算机都没有显示出任何与预期结果相差甚远的东西。
您真的需要再次阅读您的着色器,每次看到一个 vector 时,问问自己“这个 vector 在什么坐标空间中有意义?”每次看到矩阵时,问问自己“这个矩阵从什么坐标空间转换到什么坐标空间?”
关于c++ - 片段着色器在不同的计算机上执行不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14677992/