OpenGL GLSL:如何使用片段着色器在 photoshop 中实现渐变贴图的概念?
OpenGL GLSL: How to implement the concept of gradient map in photoshop using fragment shader?
这可能不是 Whosebug 的完美问题,但我已经在 stackexchange 的图形设计网络中问过这个问题,但没有得到任何答案,因此将其张贴在这里。
我正在尝试使用 glsl
片段着色器以编程方式实现 Photoshop 的渐变贴图。考虑下面显示的渐变图,其中所有白色组件都被绿色替换,黑色被蓝色替换。对于其他颜色分量,Photoshop 会根据蓝色和绿色之间的线性渐变进行计算。我知道这个计算背后有一个数学。有谁知道为特定输入颜色值查找输出颜色的公式吗?
根据图像和描述,它看起来像是将图像的原始灰度值映射到蓝绿色渐变。
有多种方法可以将颜色转换为灰度,具体取决于所使用的颜色系统。许多简单的只是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 space 中两种颜色之间的简单线性插值并不理想,尤其是当颜色差异很大时。您可以通过使用不同的颜色 space(例如 HLS)来使它更精细,并可能获得更好的质量。
另一个可能改善视觉外观的选项是使用两种以上的颜色来指定渐变。例如,您可以将蓝色指定为亮度 0.0,将青色指定为亮度 0.5,将绿色指定为亮度 1.0。它比上面的 GLSL 代码需要更多的逻辑,但它只是相同原理的扩展。
我在 Photoshop 中尝试了不同的渐变贴图,我的设置接缝与 OP 中的不同。在我的例子中,将渐变图滤镜应用于从黑到白的渐变图像表明黑色仍然是黑色,而白色仍然是白色。中间的每个灰色阴影都被绿色和蓝色之间的某种颜色所取代。如果将灰色阴影直接映射到线性渐变,黑色和白色将消失。 Photoshop 渐变贴图接缝保留原始颜色的发光。
这是我为我的设置匹配 Photoshop 渐变贴图的公式。
给定 (Rg1,Gg1,Bg1)
和 (Rg2,Gg2,Bg2)
渐变值,(Ro,Go,Bo)
原始颜色值和 (Rr,Gr,Br)
生成的颜色。
- 获取HSL中要转换的颜色space:
(Ho, So, Lo) = rgb2hsl(Ro, Go, Bo)
- 计算 Lo 值的梯度(RGB)的线性插值:
(Rt,Gt,Bt) = (Rg1+[Rg2-Rg1]*Lo, Gg1+[Gg2-Gg1]*Lo), Bg1+[Bg2-Bg1]*Lo)
- 在 HSL 中获取此值 space :
(Ht,St,Lt) = rgb2hsl(Rt, Gt, Bt)
- 保留原始颜色的L值
(Rr,Gr,Br) = hsl2rgb(Ht,St,Lo)
rgb2hsl 和 hsl2rgb 代码示例可在此处找到:HSL to RGB color conversion
这可能不是 Whosebug 的完美问题,但我已经在 stackexchange 的图形设计网络中问过这个问题,但没有得到任何答案,因此将其张贴在这里。
我正在尝试使用 glsl
片段着色器以编程方式实现 Photoshop 的渐变贴图。考虑下面显示的渐变图,其中所有白色组件都被绿色替换,黑色被蓝色替换。对于其他颜色分量,Photoshop 会根据蓝色和绿色之间的线性渐变进行计算。我知道这个计算背后有一个数学。有谁知道为特定输入颜色值查找输出颜色的公式吗?
根据图像和描述,它看起来像是将图像的原始灰度值映射到蓝绿色渐变。
有多种方法可以将颜色转换为灰度,具体取决于所使用的颜色系统。许多简单的只是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 space 中两种颜色之间的简单线性插值并不理想,尤其是当颜色差异很大时。您可以通过使用不同的颜色 space(例如 HLS)来使它更精细,并可能获得更好的质量。
另一个可能改善视觉外观的选项是使用两种以上的颜色来指定渐变。例如,您可以将蓝色指定为亮度 0.0,将青色指定为亮度 0.5,将绿色指定为亮度 1.0。它比上面的 GLSL 代码需要更多的逻辑,但它只是相同原理的扩展。
我在 Photoshop 中尝试了不同的渐变贴图,我的设置接缝与 OP 中的不同。在我的例子中,将渐变图滤镜应用于从黑到白的渐变图像表明黑色仍然是黑色,而白色仍然是白色。中间的每个灰色阴影都被绿色和蓝色之间的某种颜色所取代。如果将灰色阴影直接映射到线性渐变,黑色和白色将消失。 Photoshop 渐变贴图接缝保留原始颜色的发光。
这是我为我的设置匹配 Photoshop 渐变贴图的公式。
给定 (Rg1,Gg1,Bg1)
和 (Rg2,Gg2,Bg2)
渐变值,(Ro,Go,Bo)
原始颜色值和 (Rr,Gr,Br)
生成的颜色。
- 获取HSL中要转换的颜色space:
(Ho, So, Lo) = rgb2hsl(Ro, Go, Bo)
- 计算 Lo 值的梯度(RGB)的线性插值:
(Rt,Gt,Bt) = (Rg1+[Rg2-Rg1]*Lo, Gg1+[Gg2-Gg1]*Lo), Bg1+[Bg2-Bg1]*Lo)
- 在 HSL 中获取此值 space :
(Ht,St,Lt) = rgb2hsl(Rt, Gt, Bt)
- 保留原始颜色的L值
(Rr,Gr,Br) = hsl2rgb(Ht,St,Lo)
rgb2hsl 和 hsl2rgb 代码示例可在此处找到:HSL to RGB color conversion