image-processing - OpenGL GLSL : How to implement the concept of gradient map in photoshop using fragment shader?

标签 image-processing glsl photoshop

这可能不是 stackoverflow 的完美问题,但我在 stackexchange 的图形设计网络中提出了这个问题,但没有得到任何答案,所以在这里发布。 我正在尝试使用 glsl 片段着色器以编程方式实现 Photoshop 的渐变图。考虑下面显示的渐变图,其中所有白色分量都被绿色替换,黑色被蓝色替换。对于其他颜色成分,Photoshop 根据蓝色和绿色之间的线性渐变进行计算。我知道这个计算背后有一个数学。有谁知道找到特定输入颜色值的输出颜色的公式吗?

enter image description here

最佳答案

根据图像和描述,看起来这是将图像的原始灰度值映射到蓝绿色渐变。

有多种方法可以将颜色转换为灰度,具体取决于所使用的颜色系统。许多简单的只是RGB分量的加权和。例如,一个广泛使用的将 RGB 转换为亮度 (Y) 的公式是:

Y = 0.299 * R + 0.587 * G + 0.114 * B

Grayscale wikipedia page有关该主题和所有不同选项的更多背景信息。

然后你可以使用以灰度值作为参数的蓝色和绿色的线性插值。无论如何,这个数学很容易,但 GLSL 甚至为此目的内置了一个 mix() 函数。

一些可能的 GLSL 代码片段,基于使用纹理坐标 TexCoord 从纹理 Tex 读取原始颜色:

uniform sampler2D Tex;
in vec2 TexCoord;
out vec4 FragColor;
...
    vec4 origColor = texture(Tex, TexCoord);
    float grayscaleValue = dot(origColor.rgb, vec3(0.299, 0.587, 0.114));
    FragColor = mix(vec4(0.0, 0.0, 1.0, 1.0), vec4(0.0, 1.0, 0.0, 1.0), grayscaleValue);

在此代码中,vec3(0.299, 0.587, 0.114) 包含上述从 RGB 到灰度(亮度)公式的系数。 mix() 函数的前两个参数是渐变的开始和结束颜色:

  • 蓝色:vec4(0.0, 0.0, 1.0, 1.0)
  • 绿色:vec4(0.0, 1.0, 0.0, 1.0)

请注意,RGB 空间中两种颜色之间的简单线性插值并不理想,尤其是在颜色非常不同的情况下。通过在 HLS 等不同的色彩空间中操作,您可以使其更精细,并有可能获得更好的质量。

另一个可能改善视觉外观的选项是使用两种以上的颜色来指定渐变。例如,您可以将蓝色指定为亮度 0.0,将青色指定为亮度 0.5,将绿色指定为亮度 1.0。它比上面的 GLSL 代码需要更多的逻辑,但它只是相同原理的扩展。

关于image-processing - OpenGL GLSL : How to implement the concept of gradient map in photoshop using fragment shader?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30815364/

相关文章:

javascript - 使用 Javascript 在浏览器中编辑图像,然后将图像保存在 Google App Engine 中

php - 使用 PHP GD/Imagick 获取/设置 DPI?

python - 在python中创建圆圈来掩盖图像并计算每个圆圈内的像素

mobile - 不同芯片组的GLSL指令限制

opengl - 确定相邻像素的纹理位置

ios - Xcode渲染不同的颜色

r - 将ggplot对象保存为环境中的图像作为对象/值

GLSL Shadertoy,如何存储变量数据?

iphone - 为 iPhone 转换为 sRGB?

css - 如何计算 css px 或 rem 中的 Photoshop 字母间距?