Opengl 替换颜色的着色器

Opengl 替换颜色的着色器,opengl,glsl,shader,Opengl,Glsl,Shader,我想制作一个着色器来替换要应用于纯彩色角色的颜色,但我不能只替换颜色,因为图像包含两种边界颜色的平均值的像素。 例如,图像如下所示: 假设我想更改衬衫的颜色,我想将红色替换为绿色,但在边缘有非红色的像素: 你知道如何计算其中一个像素的合成颜色吗 Let Rx, Gx, Bx = Pixel values of color X (Red in your case) to be removed/replaced. Let Ry, Gy, By = Pixel values of color Y (G

我想制作一个着色器来替换要应用于纯彩色角色的颜色,但我不能只替换颜色,因为图像包含两种边界颜色的平均值的像素。 例如,图像如下所示:

假设我想更改衬衫的颜色,我想将红色替换为绿色,但在边缘有非红色的像素:

你知道如何计算其中一个像素的合成颜色吗

Let Rx, Gx, Bx = Pixel values of color X (Red in your case) to be removed/replaced.
Let Ry, Gy, By = Pixel values of color Y (Green in your case) to be used as new color.
然后,您将迭代所有像素,并使用下面的巧妙条件,确定需要处理的像素

如果Rc是所选像素颜色的当前值,而不管红色和黄色的组合是什么,则像素的最终值为:

Rf = Rc - Rx + Ry
Gf = Gc - Gx + Gy
Bf = Bc - Bx + By
当然,这种处理不适合所有像素。仅识别相关像素的聪明条件可能是:如果像素颜色为红色或至少一个相邻像素为红色/黄色

更新:仅使用当前像素的另一个聪明条件:

这包括从当前颜色中删除边框颜色黄色或黑色,并检查其是否为红色

Rc - R(yellow) == R(RED) AND
Gc - G(yellow) == G(RED) AND
Bc - B(yellow) == B(RED) 

OR 

Rc - R(black) == R(RED) AND
Gc - G(black) == G(RED) AND
Bc - B(black) == B(RED) 
然后,您将迭代所有像素,并使用下面的巧妙条件,确定需要处理的像素

如果Rc是所选像素颜色的当前值,而不管红色和黄色的组合是什么,则像素的最终值为:

Rf = Rc - Rx + Ry
Gf = Gc - Gx + Gy
Bf = Bc - Bx + By
当然,这种处理不适合所有像素。仅识别相关像素的聪明条件可能是:如果像素颜色为红色或至少一个相邻像素为红色/黄色

更新:仅使用当前像素的另一个聪明条件:

这包括从当前颜色中删除边框颜色黄色或黑色,并检查其是否为红色

Rc - R(yellow) == R(RED) AND
Gc - G(yellow) == G(RED) AND
Bc - B(yellow) == B(RED) 

OR 

Rc - R(black) == R(RED) AND
Gc - G(black) == G(RED) AND
Bc - B(black) == B(RED) 

你事先知道主要的颜色是什么吗

如果没有,那么找到它们的一个简单解决方案是生成一个直方图,扫描整个图像,对于与所有四个相邻像素相同的每个像素,为其包含的颜色计数添加一个。最后,仅保留那些至少填充显示器不可忽略部分的颜色,例如至少5%的不透明像素

处理黑色边框很容易:使用亮度/色度颜色空间,始终不使用亮度,只重新映射色度。分解亮度有一个好处:它将颜色替换从3d问题分解为2d问题

如果这不是GLSL,那么固溶体可能是每个像素,而不是选定的主要颜色之一,可能是我找到最近的像素,这是主要颜色;ii然后找到最接近的像素,该像素是主色,但不是i中的像素。使用普通线性代数计算2d线上该像素从一种颜色到另一种颜色的距离。替换颜色,重新插入并输出

因为它是GLSL,所以找到最近的颜色并不特别现实,假设主颜色的数量很小,那么就按照与这些线的距离来做。假设你有五种颜色。这一共是10种可能的颜色转换——从五种颜色中的每种颜色中,有四种其他选项,建议20种转换,但其中一半与另一半完全相同,因为它们只是例如红色到蓝色,而不是蓝色到红色。那么十个

把它们装成制服,然后找出颜色最接近的渐变色。替换基本颜色。输出

因此,在净额中:

将R、G、B变换为Y、x、Y——无论是YUV、YIQ还是Y都无关紧要,只需选择一个; 执行与x、y线的距离,以及为该图像确定的颜色过渡梯度; 找到该像素最接近的过渡及其沿该过渡的距离后,替换端点,重新映射; 与原始Y重新组合,转换回RGB并输出。
这是每个颜色过渡梯度建立两个点积,然后一个混合生成输出x,y/

您提前知道哪些是主要颜色吗

如果没有,那么找到它们的一个简单解决方案是生成一个直方图,扫描整个图像,对于与所有四个相邻像素相同的每个像素,为其包含的颜色计数添加一个。最后,仅保留那些至少填充显示器不可忽略部分的颜色,例如至少5%的不透明像素

处理黑色边框很容易:使用亮度/色度颜色空间,始终不使用亮度,只重新映射色度。分解亮度有一个好处:它将颜色替换从3d问题分解为2d问题

如果这不是GLSL,那么固溶体可能是每个像素,而不是选定的主要颜色之一,可能是我找到最近的像素,这是主要颜色;然后找到最近的主色像素 但不是在我身上找到的。使用普通线性代数计算2d线上该像素从一种颜色到另一种颜色的距离。替换颜色,重新插入并输出

因为它是GLSL,所以找到最近的颜色并不特别现实,假设主颜色的数量很小,那么就按照与这些线的距离来做。假设你有五种颜色。这一共是10种可能的颜色转换——从五种颜色中的每种颜色中,有四种其他选项,建议20种转换,但其中一半与另一半完全相同,因为它们只是例如红色到蓝色,而不是蓝色到红色。那么十个

把它们装成制服,然后找出颜色最接近的渐变色。替换基本颜色。输出

因此,在净额中:

将R、G、B变换为Y、x、Y——无论是YUV、YIQ还是Y都无关紧要,只需选择一个; 执行与x、y线的距离,以及为该图像确定的颜色过渡梯度; 找到该像素最接近的过渡及其沿该过渡的距离后,替换端点,重新映射; 与原始Y重新组合,转换回RGB并输出。
那就是每两个点积建立最接近的颜色过渡梯度,然后一次混合生成输出x,y/

非常好,谢谢!假设所有的边缘都有一个黑色的斯托克,你认为这是一种使条件只依赖于当前像素的方法吗?在这种情况下,Rc必须重新计算,G和B也一样,对吗?或者我错过了什么?太好了,谢谢!假设所有的边缘都有一个黑色的斯托克,你认为这是一种使条件只依赖于当前像素的方法吗?在这种情况下,Rc必须重新计算,G和B也一样,对吗?或者我遗漏了什么?你是否事先知道有限的重要颜色集,例如特定的红色、特定的黄色,或者你需要计算它们?是否要求所有阶段都出现在GLSL中?您是否提前知道有限的有效颜色集,例如特定的红色、特定的黄色,或者您是否需要计算它们?是否要求所有阶段都发生在GLSL中?