简体   繁体   English

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

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

Assuming you want to pass in additional light positions to the vertex shader (outside of the lights provided by the fixed functional pipeline) I am not seeing these additional uniforms functioning correctly. 假设您希望将其他灯光位置传递到顶点着色器(在固定功能管线提供的灯光之外),我看不到这些其他制服的功能正常。

For example in my vertex shader I have: 例如,在我的顶点着色器中,我有:

...
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;

    ...
}

Where the difference in my scene can be seen below. 下面可以看到我的场景中的差异。

To set the uniform variable I am using Qt's QOpenGLShaderProgam::setUniformValue in the following manner. 为了设置统一变量,我以以下方式使用Qt的QOpenGLShaderProgam::setUniformValue

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

All my other uniforms, the mv, mvp, and (trans(mv))^-1 all work so it is not a problem with Qt. 我所有的其他制服,mv,mvp和(trans(mv))^-1都可以使用,因此Qt没问题。 Where am I going wrong? 我要去哪里错了? I would expect to see the same image using either version. 我希望使用任一版本都能看到相同的图像。

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

Screenshot using uniform vec3: 使用统一vec3的屏幕截图: 统一vec3


Update 更新资料

I have added glGetError after every call to OpenGL in my code, which consists of one function. 在代码中每次调用OpenGL之后,我都添加了glGetError,它包含一个函数。 I only get an error when I go to set the uniform both with, or without the use of Qt's API, as seen below: 不论是否使用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
//*/

Where GL_CALL is defined as: 其中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
    }
}

The ouput of my program shows me the line with the given error: 我程序的输出向我显示了给定错误的行:

GL_ERROR is 1282 from 263 GL_ERROR是263中的1282

Since uniforms are accessible in both the vertex shader and the fragment shader there's no reason to pass it through the vertex shader. 由于制服在顶点着色器和片段着色器中均可访问,因此没有理由将其通过顶点着色器。 Just move the uniform declaration to the fragment shader and use it there directly. 只需将统一声明移至片段着色器,然后在此处直接使用它即可。

The result you get is probably due to the interpolation of varying variables in the rasterizer, which means that frag_light_pos will have a different value for each pixel (fragment). 您得到的结果可能是由于光栅化器中各种变量的插值所致,这意味着frag_light_pos对于每个像素(片段)将具有不同的值。 It might be possible to use the varying with the flat qualifier to 'turn off' interpolation, but I can't see a reason why you would do that. 可能可以使用带有flat限定符的变化来“关闭”插值,但是我看不出为什么要这样做。

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

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