我正在开发初学者级别的GLSL着色器程序。我正在关注this教程。但是我的球体总是以灰度显示,而不像我预期的那样是红色。
顶点着色器:
varying vec3 normal, lightDir;
void main() {
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
normal = gl_NormalMatrix * gl_Normal;
vec4 vertex_in_modelview_space = gl_ModelViewMatrx * gl_Vertex;
lightDir = vec3(gl_LightSource[0].position – vertex_in_modelview_space);
}
Frag Shader:
varying vec3 normal, lightDir;
void main()
{
const vec4 AmbientColor = vec4(0.1, 0.0, 0.0, 1.0);
const vec4 DiffuseColor = vec4(1.0, 0.0, 0.0, 1.0);
vec3 normalized_normal = normalize(normal);
vec3 normalized_lightDir = normalize(lightDir);
float DiffuseTerm = clamp(dot(normal, lightDir), 0.0, 1.0);
gl_FragColor = AmbientColor + DiffuseColor * DiffuseTerm;
}
代码只是复制并粘贴教程。
从frag着色器中,漫反射颜色为红色,但我的球体为灰度。我知道着色器已正确加载,因为如果我取出frag着色器中的代码并使用以下内容:
gl_FragColor = vec4(0.0,1.0,0.0,1.0);
然后我的球体像预期的那样呈绿色。我不知道openGL代码(如Renderer.cpp)中是否存在导致冲突的问题,或者是否存在其他错误。
这是我第一次使用GLSL进行编码,我很担心gl_Enable需要打开/关闭才能使着色器正常工作。
感谢您的反馈!
修改 好吧,如果我在渲染之前调用glColor3f,我可以得到正确的颜色。但是光的颜色不会直接导致球体颜色的变化吗?我担心我实际上并没有在着色器中调用函数......
EDIT2: 所以事实证明,每当我在顶点着色器或frag着色器中放置任何代码(gl_Color = ...除外)时,我得到的纯色消失......我想这意味着我的着色器出现了可怕的错误?< / p>
EDIT3: 这是设置我的着色器的代码(由我的TA提供):
char *vs = NULL,*fs = NULL;
v = glCreateShader(GL_VERTEX_SHADER);
f = glCreateShader(GL_FRAGMENT_SHADER);
vs = textFileRead(vert);
fs = textFileRead(frag);
const char * ff = fs;
const char * vv = vs;
glShaderSource(v, 1, &vv,NULL);
glShaderSource(f, 1, &ff,NULL);
free(vs);
free(fs);
glCompileShader(v);
glCompileShader(f);
p = glCreateProgram();
glAttachShader(p,f);
glAttachShader(p,v);
glLinkProgram(p);
int infologLength = 0;
int charsWritten = 0;
char *infoLog;
glGetProgramiv(p, GL_INFO_LOG_LENGTH,&infologLength);
if (infologLength > 0)
{
infoLog = (char *)malloc(infologLength);
glGetProgramInfoLog(p, infologLength, &charsWritten, infoLog);
printf("%s\n",infoLog);
free(infoLog);
}
EDIT4: 使用kvark建议的着色器日志,我设法修复着色器中的错误(原来有几个错误)。如果您想查看最终代码,请发表评论或给我留言(这个问题已经很久了)。
答案 0 :(得分:2)
不仅要检查链接日志,还要检查每个着色器的日志以及编译/链接结果,这是一个好主意:
glGetShaderInfoLog(...)
glGetShaderiv(...,GL_COMPILE_STATUS,...)
glGetProgramiv(...,GL_LINK_STATUS,...)
确保结果为正,日志为空(或好)。
在您的示例中,漫反射项的计算方法不正确。它应具有以下值:
float DiffuseTerm = max(0.0, dot(normalized_normal,normalized_lightDir) );
您不需要clamp(),因为标准化矢量的dot()结果不能超过1。
如果你确定着色器程序是正确链接的,那么在绘图上激活它并且结果仍然很奇怪,尝试选择最终颜色方程的不同组件以找出错误的组件:
gl_FragColor = DiffuseColor; //can't be grayscale
gl_FragColor = vec4(DiffuseTerm); //should be diffuse grayscale
BTW,glColor3f应该与你的着色器无关,因为你没有在里面使用gl_Color。如果调用时结果发生变化 - 这意味着着色器激活失败(它没有链接或根本没有使用)。
祝你好运!
答案 1 :(得分:0)
可能这是由于您的Alpha通道结果出现了不受欢迎的行为。
你实际上是在alpha通道上计算灯光,实际上有类似的东西:g
gl_FragColor.a = 1.0 + 1.0 * DiffuseTerm
将为您提供&gt; = 1.0值。
您应该注意不要在输出中包含Alpha通道(甚至在计算中)。
尝试确保禁用混合,或者将着色器修复为:
varying vec3 normal, lightDir;
void main()
{
const vec3 AmbientColor = vec3(0.1, 0.0, 0.0);
const vec3 DiffuseColor = vec3(1.0, 0.0, 0.0);
vec3 normalized_normal = normalize(normal);
vec3 normalized_lightDir = normalize(lightDir);
float DiffuseTerm = clamp(dot(normal, lightDir), 0.0, 1.0);
gl_FragColor = vec4(AmbientColor + DiffuseColor * DiffuseTerm, 1.0);
}