我正在寻找一些如何使用片段着色器获得平滑渐变的方法。我有11
颜色的调色板和用于定义颜色的value
(它的范围从0.0
到1.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
。
答案 0 :(得分:1)
您的混音功能在这里并没有真正有用:
mix(colors[floorIndex], colors[index], value)
问题是,虽然value
在[0,1]中,但它不是正确的混合因子。对于您选择的子范围,您需要将其缩放为[0,1]。例如,当值为[0.25,0.35]时,您的代码使用floorIndex=2
和index=3
,因此现在需要一个混合因子,当值为0.25时为0.0,当为0.3时为0.5,且goint接近1.0当它达到0.35时(在3.5时,该轮将切换到下一步,当然)。
所以你需要这样的东西:
float blend=(value * 10.0) - float(floorIndex) - 0.5;
mix(colors[floorIndex], colors[index], blend)
使用fract()
操作可以稍微优化一下。
我想到的另一件事是您可以为调色板使用(1D)纹理并启用GL_LINEAR
过滤。在这种情况下,您可以直接使用value
作为纹理坐标,并获得所需的结果。这将更加简单,并且可能更高效,因为它将大多数操作移动到专用纹理采样硬件。因此,如果您没有使用纹理的具体原因,我强烈建议您这样做。