GLSL:如何根据Photoshops曲线值计算片段输出RGB值?

时间:2015-06-11 05:27:07

标签: android opengl-es glsl

我正在使用Android中的OPENGL进行图像编辑,现在我已经使用photoshop曲线对图像应用了滤镜,现在我想使用glsl在Android中重现相同的效果。有没有使用photoshops曲线输出值计算单片段颜色的公式?

修改

在这个问题中已经回答了photoshop曲线背后的数学问题 How to recreate the math behind photoshop curves但我不清楚如何在glsl fragment shader中重现相同内容。

我的photoshop曲线的屏幕截图 enter image description here

1 个答案:

答案 0 :(得分:2)

您正在使用函数fragColour = curves(inColour, constants...)。如果您只有一条红色,绿色和蓝色曲线,则将相同的曲线分别应用于每条曲线。 This answer在代码中有一个链接(下方),用于绘制函数中的点。关键是:

double y = ...

您将从curves返回。循环中的变量x是您的inColour。您现在需要的只是来自points和二阶导数sd数组的常量。这些你必须以uniforms传递。该函数首先要弄清楚每个颜色x介于哪一点(查找curnextsd[i]sd[i+1]),然后评估并返回{ {1}}。

<强> 编辑:
如果您只想应用一些您在photoshop中创建的曲线,那么问题就更简单了。最简单的方法是创建一个提供类似形状的简单函数。我使用these作为起点。 gamma correction曲线也很常见。

这有点过分,但是如果你确实需要一个更精确的结果,你可以创建一个带有线性斜坡的图像(例如从黑到白的255像素),在photoshop中将滤镜应用到它,结果变为查找表。将所有255个值传递到着色器是很昂贵的,因此如果它是平滑曲线,您可以尝试一些曲线拟合工具(for example)。

一旦有了功能,只需将其应用于GLSL中的颜色即可。例如,应用伽玛曲线like this

y

<强> EDIT2:

你所拥有的曲线看起来非常相似:

fragColour = vec4(pow(inColour.rgb, 1.0 / gamma.rgb), inColour.a);

甚至更简单:

fragColour = vec4(pow(inColour.rgb, 1.0 / vec3(0.6)), inColour.a);

为了防止the link死亡,我会在这里复制代码(不是我测试过的):

fragColour = vec4(inColour.rgb * inColour.rgb, inColour.a);

二阶导数:

Point[] points = /* liste de points, triés par "x" croissants */

double[] sd = secondDerivative(points);

for(int i=0;i<points.length-1;i++) {
    Point cur   = points[i];
        Point next  = points[i+1];

        for(int x=cur.x;x<next.x;x++) {
        double t = (double)(x-cur.x)/(next.x-cur.x);

        double a = 1-t;
        double b = t;
        double h = next.x-cur.x;

        double y= a*cur.y + b*next.y + (h*h/6)*( (a*a*a-a)*sd[i]+ (b*b*b-b)*sd[i+1] );

        draw(x,y); /* ou tout autre utilisation */
    }
}