【问题标题】:WebGL: Change color saturation or luminosity in fragment shaderWebGL:更改片段着色器中的颜色饱和度或亮度
【发布时间】:2015-12-08 07:00:51
【问题描述】:

我发现了这个很棒的页面hls picker,我想知道是否有可能在 WebGL 中实现类似的效果。我正在向我的片段着色器传递一些颜色,例如#FF7400,将其转换为 hsl 并更改其亮度或平滑过渡到黑色(亮度 equel 0)的最简单方法是什么。我想在我的页面中制作具有不同颜色(亮度)的云,这取决于它们离太阳的距离。提前感谢您的帮助。

【问题讨论】:

  • Different color(luminosity) depends how far they are from sun. 这通常通过一个基本的闪电系统和一些基于到光源的距离的衰减来完成。可能存在透明度问题。如果要解决透明度问题,解决方案很复杂。
  • 好的,很好的提示,但我想在着色器中改变颜色,太阳只是一个例子,这个颜色转换器对我有很大帮助,我认为它会更有效。

标签: three.js webgl fragment-shader hsl


【解决方案1】:

感谢 geat 链接,但我认为我找到了更简单的方法来轻松进行颜色转换,我只需要使用 webGL 方法 T mix(T x, T y, float a) - x 和 y 的线性混合。

我在shadertoy editor中使用的这段代码:

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
     vec2 uv = gl_FragCoord.xy / iResolution.xy;
     vec4 orange = vec4(0.533, 0.25, 0.145, 1.0);
     vec4 blue = vec4(0.18, 0.23, 0.27, 1.0);
     vec4 black = vec4(0.0, 0.0, 0.0, 1.0);
     vec4 white = vec4(1.0, 1.0, 1.0, 1.0);

     float ratio = iResolution.x / iResolution.y;
     float PI = 3.14159265359;

     vec4 mixC = mix(orange, blue, sin(ratio * uv.y));
     mixC = mix(mixC, black, cos(2.0 * PI * uv.x) / ratio);
     mixC = mix(mixC, black, cos(2.0 * PI * uv.y) / ratio);
     mixC = mix(mixC, white, 0.1);
     fragColor = mixC;   
}

如您所见,我只用几行代码就在四种颜色之间进行了转换,结果如下所示:

【讨论】:

    【解决方案2】:

    我认为片段着色器是一个小 Photoshop。每个 Photoshop 操作都应该可以使用 WebGL。

    如果我们谈论的是相对于太阳位置的 2D 图像,并且您只想使用一些基本的图像处理,您可以使用函数 from this answer rgb2hsvhsv2rgb。我认为它应该适用于 GLSL 1。 然后您可以将 Sat、Lum 或 Hue 相乘,然后将其转换回 RGB。

    如果没有,您可能需要从常用公式重新实现它,使用 wiki 或此链接:http://www.rapidtables.com/convert/color/rgb-to-hsl.htm

    如果你想做更多的图像处理,当需要相邻像素时,我推荐这个很棒的教程,你可以轻松地做一些边缘锐化、模糊等:http://webglfundamentals.org/webgl/lessons/webgl-image-processing.html

    【讨论】:

    • 这些着色器在 WebGL 中工作得很好。我已经使用它们一段时间了。 This game uses those function to colorize the characters(警告:有声音)。我为饱和度和值添加了一个钳位。它们还用于vertexshaderart.com 的许多样本。一些更有趣的色彩空间着色器是 herehere
    • 嗨,谢谢你的回答,但我想我找到了更简单的方法来进行颜色转换。
    【解决方案3】:

    original image

    大家好,我想我找到了一种非正统但简单的方法来降低 RGB 图像的饱和度,我们只需要找到像素的平均颜色, 平均 _color = (R+G+B)/3 保持 Alpha... vec4(average_color,average_color,average_color, Alpha);

        void main()
    {
        //write a color of the current fragment to a variable
        lowp vec4 color_of_pixel = texture2D(texture_sampler, var_texcoord0.xy);
    
        //Find the average among red, green and blue and it keeps the "force" of the color...
        float average_color = ((color_of_pixel.r + color_of_pixel.g + color_of_pixel.b)/3);
    
        lowp vec4 color_of_pixel_final = vec4(average_color,average_color,average_color,color_of_pixel.a);
        gl_FragColor = color_of_pixel_final;  // write the color_of_pixel to the output gl_FragColor
    }
    

    Desaturated image

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-29
      • 1970-01-01
      • 1970-01-01
      • 2012-08-23
      • 2018-04-01
      • 2023-03-25
      • 2011-05-17
      • 1970-01-01
      相关资源
      最近更新 更多