【问题标题】:iOS - How to create custom GPUImageFilters with OpenGLESiOS - 如何使用 OpenGLES 创建自定义 GPUImageFilters
【发布时间】:2016-05-03 02:07:14
【问题描述】:

我想知道如何为 GPUImage 创建自定义过滤器。现在我可以从这段代码中创建一个棕褐色自定义过滤器(这是由 Brad Larson 在 GitHub 上作为示例提供的):

varying highp vec2 textureCoordinate;

uniform sampler2D inputImageTexture;

void main()
{
    lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
    lowp vec4 outputColor;
    outputColor.r = (textureColor.r * 0.393) + (textureColor.g * 0.769) + (textureColor.b * 0.189);
    outputColor.g = (textureColor.r * 0.349) + (textureColor.g * 0.686) + (textureColor.b * 0.168);    
    outputColor.b = (textureColor.r * 0.272) + (textureColor.g * 0.534) + (textureColor.b * 0.131);
    outputColor.a = 1.0;

    gl_FragColor = outputColor;
}

我很想知道 Brad Larson 是如何知道这些数字的,以及这意味着什么。我到处搜索,没有找到这方面的教程。有人可以指导我使用 Photoshop 创建自己的自定义照片滤镜,然后将其转换为 .fsh 代码文件吗?

例如,如果我要在 Photoshop 中将图像更改为粉红色。如何在上面的代码中得到这些数字?

【问题讨论】:

    标签: ios objective-c c opengl-es gpuimage


    【解决方案1】:

    你的问题有点宽泛,你可以直接write an entire book on how to create custom shaders,但这是一个常见问题,所以我至少可以为人们指出正确的方向。

    GPUImage 中的滤镜是用 OpenGL 着色语言 (GLSL) 编写的。 OpenGL 目标(Mac、桌面 Linux)和 OpenGL ES 目标(iOS、嵌入式 Linux)之间存在细微差别,后者的着色器使用前者缺少的精度限定符。除此之外,语法是一样的。

    着色器程序由一对匹配的顶点着色器和片段着色器组成。顶点着色器对每个顶点进行操作,通常处理几何操作。片段着色器对每个片段(通常是像素)进行操作,并计算要在该片段处输出到屏幕的颜色。

    GPUImage 处理图像处理,因此大多数时候您将只使用片段着色器并依赖于库存顶点着色器之一。上面是一个片段着色器示例,它接收输入纹理的每个像素(处理管道中上一步的图像),操纵其颜色值,并将结果写入gl_FragColor 内置函数。

    main() 函数的第一行:

    lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
    

    使用texture2D() 函数在给定坐标处读取inputImageTexture 中的像素颜色(从第一阶段的顶点着色器传入)。这些坐标被归一化为 0.0-1.0 范围,因此与输入图像大小无关。

    这些值被加载到一个向量类型 (vec4) 中,该类型在一个类型中包含多个组件。在这种情况下,红色、绿色、蓝色和 alpha 的颜色分量存储在这个四分量向量中,并且可以通过 .r、.g、.b 和 .a 访问。如果您习惯于使用 0-255 的值,颜色分量值也会标准化为 0.0-1.0 范围。

    在棕褐色调滤镜的特殊情况下,我尝试将a well-known color matrix 用于棕褐色调效果,以将传入的颜色转换为传出的颜色。这需要矩阵乘法,我在上面的代码中明确地这样做了。在实际框架中,这是使用着色器中的内置类型作为矩阵数学来完成的。

    有很多很多方法可以操纵颜色来实现某些效果。 GPUImage 框架充满了它们,主要基于 Adob​​e 或其他组织发布的颜色转换标准。对于给定的效果,在着手编写自己的实现之前,您应该确定这些现有实现之一是否能满足您的需求。

    如果您确实想编写自己的代码,请首先计算将传入颜色转换为您想要的任何输出所需的数学运算。有了这些,编写着色器代码就很容易了。

    GPUImage 中的查找过滤器采用另一种方法,即从您在 Photoshop 中在您希望模仿的过滤条件下操作的查找图像开始。然后,您获取过滤后的查找图像并将其附加到查找过滤器。它在传入颜色和查找中的等效颜色之间进行转换,以提供任意颜色操作。

    一旦你有了你的着色器,你就可以用几种不同的方式围绕它创建一个新的过滤器。如果你愿意放弃一些向后兼容性,我应该说我的新 GPUImage 2 framework 大大简化了这个过程。

    【讨论】:

    • 嗨布拉德!一如既往的好答案,但是是否可以通过在 GPUImage shadertoy.com/view/XtK3W3 中使用 GLSL 来创建这种效果?因为看起来要创建这个自定义着色器,我们需要有更多的变量,比如播放时间和其他一些东西?但在 GPUImage 示例中,我只能看到它提供了纹理坐标?对不起,我以前不熟悉这些着色器。
    • @Huy.Vu - 你应该能够提供这些额外的变量作为制服,尽管通常在 GPUImage 中制服保持相对恒定,帧到帧。在像这样的时间相关效果的情况下,您需要在每一帧上更新与时间相关的制服。可以通过修改基本过滤器来完成,但我目前没有这样的模板示例。
    猜你喜欢
    • 2022-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-27
    • 1970-01-01
    • 2016-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多