从GLSL获取插值颜色

时间:2014-06-02 17:23:39

标签: opengl glsl

所以我试图修改当前的着色器以允许我在顶点之间进行插值。我现在的设置只允许我定义每个三角形的颜色,我相信这是因为我在片段着色器而不是Vertex着色器中设置颜色。

代码:

GLuint MakeSphereShader ()
{
    const GLchar* _vertexShaderCode = "\
     #version 130\n                                                                                                     \
     in vec4 Position;                                                                                                  \
     in vec4 Normal;                                                                                                        \
     uniform mat4 ModelMatrix;                                                                                          \
     uniform mat4 ViewMatrix;                                                                                           \
     uniform mat4 PerspectiveMatrix;                                                                                        \
     uniform mat4 Rotations;                                                                                                \
     uniform vec4 Light;                                                                                                    \
     uniform float Red;                                                                                                 \
     uniform float Green;                                                                                               \
     uniform float Blue;                                                                                                    \
     out vec3 NormalVector;                                                                                             \
     out vec3 LightVector;                                                                                              \
     out vec4 ColorVector;                                                                                              \
     void main () {                                                                                                     \
        NormalVector = (Rotations*Normal).xyz;                                                                          \
        LightVector = Light.xyz;                                                                                        \
        gl_Position = PerspectiveMatrix*ViewMatrix*ModelMatrix*Position;                                                \
        ColorVector = vec4(Red, Green, Blue, 1.0);                                                                      \
    }";
    const GLchar* _fragmentShaderCode = "\
        #version 130\n                                                                                                      \
        in vec3 NormalVector;                                                                                               \
        in vec3 LightVector;                                                                                                \
        in vec3 ColorVector;                                                                                                \
        uniform bool Lighting;                                                                                              \
        out vec4 Color;                                                                                                     \
        void main () {                                                                                                      \
            vec3 _normal = normalize(NormalVector);                                                                         \
            vec3 _light = normalize(LightVector);                                                                           \
            float _diffuseIntensity = max(abs(dot(_normal, _light)), 0.1);                                                  \
            float _alpha = 0.4;                                                                                             \
            if (!Lighting)                                                                                                  \
            {                                                                                                               \
                _diffuseIntensity = 1.0;                                                                                    \
                _alpha = 0.6;                                                                                               \
            }                                                                                                               \
            Color = vec4(_diffuseIntensity/5 + ColorVector[0], _diffuseIntensity/5 + ColorVector[1], _diffuseIntensity/5 + ColorVector[2], _alpha);     \
        }";
    GLuint _vertShaderID = makeVertexShader(_vertexShaderCode);
    GLuint _fragShaderID = makeFragmentShader(_fragmentShaderCode);
    return makeShaderProgram(_vertShaderID, _fragShaderID);
    }

所以我之前一直在做的就是这样画画:

glUniform1f(glMatrices.RedID, _red);
glUniform1f(glMatrices.GreenID, _green);
glUniform1f(glMatrices.BlueID, _blue);

glBegin(GL_POLYGON);
    for (k=0; k<3; k++) 
    {
        glVertexAttrib3d(glMatrices.PositionID, _x[k], _y[k], _z[k]);
        glVertexAttrib3d(glMatrices.NormalID, _unitv.X, _unitv.Y, _unitv.Z);
    }
glEnd();

所以有意义的是,如果我告诉片段着色器使用它的颜色,它将为每个像素着色我指定的颜色。所以我一直在尝试将颜色变量移动到顶点着色器,但我并不认为正确的方法是什么。我之前正在研究它,并且只能在我的Nvidia机器上工作,而不是在ATI上,所以我一定是在滥用一些我不知道我在做的规则。

我尝试将out vec4 ColorVector添加到顶点着色器并将其发送到片段但开始抛出无效值并崩溃。

定义每个顶点的颜色而不是每个三角形的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

你的正常需要来到这个职位之前。使用立即模式时,声明顶点属性 0 是最终确定顶点的原因。虽然您没有显示绑定属性位置的代码,但我必须假设该位置绑定到 0 ,否则您将在屏幕上看不到任何内容。

现在,整个着色器中唯一的颜色来源是均匀(常量)。您的颜色不是每个顶点,甚至不是每个三角形,它们是每个程序。当您处理的每个顶点具有相同的输入颜色时,插值不会改变任何内容。

您需要使用per-vertex属性才能工作:

in vec4 Color;

...

ColorVector = Color;

然后您的绘图代码将如下所示:

glBegin(GL_POLYGON);
    for (k=0; k<3; k++) 
    {
        glVertexAttrib3d(glMatrices.NormalID,   _unitv.X, _unitv.Y, _unitv.Z);
        glVertexAttrib3f(glMatrices.ColorID,    _red,     _green,   _blue);
        glVertexAttrib3d(glMatrices.PositionID, _x[k],    _y[k],    _z[k]);
    }
glEnd();

当然,颜色仍然是不变的,我会把它留给你来弄清楚如何修复。但是,一旦你想出来,这确实可以让你传递一个独特的每顶点颜色。