繁体   English   中英

GLSL将均匀形式的其他光照位置传递给顶点着色器

[英]GLSL Passing Additional Light Positions in As Uniform Variables to Vertex Shader

假设您希望将其他灯光位置传递到顶点着色器(在固定功能管线提供的灯光之外),我看不到这些其他制服的功能正常。

例如,在我的顶点着色器中,我有:

...
uniform vec3 light_pos;

...
varying vec3 frag_light_pos;

void main() {
    ...

    frag_light_pos = vec3(0.0f, 100.0f, 0.0f);
    //frag_light_pos = light_pos;

    ...
}

下面可以看到我的场景中的差异。

为了设置统一变量,我以以下方式使用Qt的QOpenGLShaderProgam::setUniformValue

QVector3D light_pos(0.0f, 100.0f, 0.0f);
m_ShaderProgram->setUniformValue("light_pos", light_pos);

我所有的其他制服,mv,mvp和(trans(mv))^-1都可以使用,因此Qt没问题。 我要去哪里错了? 我希望使用任一版本都能看到相同的图像。

使用const vec3的屏幕截图: const vec3

使用统一vec3的屏幕截图: 统一vec3


更新资料

在代码中每次调用OpenGL之后,我都添加了glGetError,它包含一个函数。 不论是否使用Qt的API来设置制服,我只会收到一个错误,如下所示:

/*
    QVector3D light_pos(0.0f, 100.0f, 0.0f);
    m_ShaderProgram->setUniformValue("frag_light_pos", light_pos); GL_CALL
/*/
    GLint light_id = glGetUniformLocation(m_ShaderProgram->programId(),
        "frag_light_pos"); GL_CALL
    glUniform3f(light_id, 10.0f, 10.0f, 10.0f); GL_CALL
//*/

其中GL_CALL定义为:

#define GL_CALL GetGlErrors(__LINE__);

void GetGlErrors(int line)
{
    GLenum err_code;
    while ((err_code = glGetError()) != GL_NO_ERROR) {
#if __GL_WRAPPER_WINDOWS__
        char buffer[256];
        sprintf_s(buffer, "GL_ERROR is %d from %d\n", err_code, line);
        OutputDebugStringA(buffer);
#else
        printf("GL_ERROR is %d from %d\n", err_code, line);
#endif
    }
}

我程序的输出向我显示了给定错误的行:

GL_ERROR是263中的1282

由于制服在顶点着色器和片段着色器中均可访问,因此没有理由将其通过顶点着色器。 只需将统一声明移至片段着色器,然后在此处直接使用它即可。

您得到的结果可能是由于光栅化器中各种变量的插值所致,这意味着frag_light_pos对于每个像素(片段)将具有不同的值。 可能可以使用带有flat限定符的变化来“关闭”插值,但是我看不出为什么要这样做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM