如何在GLSL着色器中实现颜色矩阵滤镜

3
我希望在GLSL着色器中实现一个颜色矩阵滤镜,但找不到任何相关的文档。我完全是新手(从未编写过代码),所以请原谅我如果我的解释/词汇不太准确。
到目前为止,我能收集到的信息如下:
- 颜色矩阵由5列(RGBA + 偏移量)和4行组成。

enter image description here

第一到第四列的值分别与源红色、绿色、蓝色和透明度值相乘。第五列的值被添加(偏移)。
  • 我相信GLSL中最大的矩阵是4×4的mat4矩阵(不包括“偏移”列)

  • 我在着色器中看到的唯一一个mat4实现看起来像这样:

colorMatrix = (GPUMatrix4x4){{0.3588, 0.7044, 0.1368, 0.0},
                             {0.2990, 0.5870, 0.1140, 0.0},
                             {0.2392, 0.4696, 0.0912 ,0.0},
                             {0,0,0,1.0}
              };

问题:

  • 如何实现一个?如上所述,我从未编写过GLSL着色器,不幸的是我无法提供MCVE。我希望能看到一个示例,以便我可以从中学习。

谢谢

编辑:

我正在使用Processing,并且这是我找到的唯一一个用于颜色渲染的顶点和片段着色器示例:

colorvert.glsl:

uniform mat4 transform;

attribute vec4 position;
attribute vec4 color;

varying vec4 vertColor;

void main() {
  gl_Position = transform * position;
  vertColor = color;
}

colorfrag.glsl:

#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif

varying vec4 vertColor;

void main() {
  gl_FragColor = vertColor;
}
1个回答

3

作为开端,我建议尝试以下内容:

顶点(Vertex):

#version 410 core
layout(location = 0) in vec3 in_vertex;
layout(location = 3) in vec4 in_color;
out vec4 color;
void main()
    {
    const mat4x4 m=mat4x4               // RGBA matrix
        (
        0.3588, 0.7044, 0.1368, 0.0,
        0.2990, 0.5870, 0.1140, 0.0,
        0.2392, 0.4696, 0.0912 ,0.0,
        0.0   , 0.0   , 0.0    ,1.0
        );
    const vec4 o=vec4(0.0,0.0,0.0,0.0); // offset

       color    = (m * in_color) + o;   // transformation
    gl_Position = vec4(in_vertex,1.0);
    }

碎片:

#version 410 core
in vec4 color;
out vec4 out_color;
void main()
    {
    out_color=color;
    }

只需要更改#version、布局和输入属性/统一变量以满足您的需求(目前它使用默认的nVidia属性位置来进行固定管线)。
现在,例如要转换图像,只需在<-1,+1>顶点坐标x,y范围上渲染纹理四边形即可。
如果您的矩阵或颜色在片段中发生变化(例如由于某些过程生成的东西),那么只需将转换移动到片段着色器中即可。
您还可以将const更改为uniform(并将其移到main之前),这样您就可以在运行时传递自定义参数...
如果您需要一个GLSL起始示例,请参见:

非常清晰和全面的答案!不幸的是,对我没有用(我正在使用Processing,问题已被编辑)。1. 当混合颜色矩阵时,我看不到任何颜色变化。2. 我尝试将转换移动到片段着色器中,但我得到了多个错误“未声明的标识符”('m'、'in_color'、'o')。我在片段着色器中指定了"uniform vec4 in_color; uniform mat4x4 m; uniform vec4 o",但仍然出现“Left-hand-side of assignment must not be read-only”的错误。 - solub
1
@solub 尝试将 gl_Position 设置为顶点着色器代码的最后一行,因为GL实现可能会优化掉它之后的所有代码。为了使其工作,您还应该将您的行 vertColor = color; 更改为 vertColor = (m*color)+o;。当您使用uniform时,不能在着色器中声明值,而是需要从CPU端代码传递它们。如果您的着色器包含错误,则会使用固定管道,因此请检查着色器日志。我不使用processing,所以无法帮助处理CPU端代码。 - Spektre

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接