【问题标题】:Smooth gradient in fragment shader片段着色器中的平滑渐变
【发布时间】:2014-08-13 00:16:13
【问题描述】:

我正在寻找如何使用片段着色器获得平滑渐变的方法。我有带有11 颜色和value 的调色板,用于定义颜色(它的范围从0.01.0)。

我正在尝试使用这样的fragment shader 获得平滑的颜色翻译:

#version 150 core

in float value;    
uniform vec3 colors[11];

out vec4 out_Color;

void main(void) 
{
    int index = int(round(value * 10));

    int floorIndex = 0; 

    if (index != 0) floorIndex = index - 1;

    out_Color = vec4(mix(colors[floorIndex], colors[index], value), 1.0f);
}

但是使用这种方法我只能得到阶梯式颜色分布。

我想要的结果如下:

我知道如何通过仅将颜色作为属性传递的路径着色器来获得它,但事实并非如此。我将通过传递给fragment shader 的单个浮点值获得如此平滑的分布。

【问题讨论】:

  • 一个建议:将if (index != 0) floorIndex = index - 1;改为floorIndex = max(index-1, 0),避免分支,提高性能。
  • @三十二上校:真的,很好的建议。

标签: opengl shader fragment-shader


【解决方案1】:

您的混合功能在这里并没有真正有用:

mix(colors[floorIndex], colors[index], value)

问题在于,虽然value 在 [0,1] 中,但它不是正确的混合因子。对于您选择的子范围,您需要将其缩放到 [0,1]。例如,当值为 [0.25, 0.35) 时,您的代码使用 floorIndex=2index=3,所以现在您需要一个混合因子,当值为 0.25 时为 0.0,当值为 0.3 时为 0.5,当它达到 0.35 时接近 1.0 (当然,在 3.5 回合将切换到下一步)。

所以你需要这样的东西:

float blend=(value * 10.0) - float(floorIndex) - 0.5;
mix(colors[floorIndex], colors[index], blend)

这可能可以通过使用fract() 操作进行一些优化。

想到的另一件事是,您可以为调色板使用 (1D) 纹理并启用GL_LINEAR 过滤。在这种情况下,您可以直接使用value 作为纹理坐标,并会得到您需要的结果。这将更简单,并且可能也更有效,因为它将大部分操作移至专门的纹理采样硬件。因此,如果您没有不使用纹理的具体原因,我强烈建议您这样做。

【讨论】:

  • 您的混合变体正是我想要的。谢谢!
猜你喜欢
  • 1970-01-01
  • 2018-05-02
  • 2023-03-25
  • 2018-07-21
  • 1970-01-01
  • 2013-04-02
  • 1970-01-01
  • 2012-08-23
  • 1970-01-01
相关资源
最近更新 更多