[英]Smooth gradient in fragment shader
我正在寻找某种方法来使用片段着色器获得平滑的渐变。 我有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);
}
但是使用这种方法,我只能得到逐步的颜色分布。
我期望的结果如下所示:
我知道如何通过仅将颜色作为属性传递的路径着色器来实现此目的,但这不是那样。 通过将单个float值传递到fragment shader
我将获得如此平滑的分布。
您的混合功能在这里并不是真正有用的应用:
mix(colors[floorIndex], colors[index], value)
问题在于,尽管value
在[0,1]中,但它不是适当的混合因子。 对于选定的子范围,需要将其缩放为[0,1]。 例如,当值在[ floorIndex=2
,您的代码使用floorIndex=2
和index=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
作为纹理坐标,并获得所需的结果。 由于它将大多数操作移至专用纹理采样硬件,因此这将更加简单,并且可能还会更加高效。 因此,如果您没有不使用纹理的特定原因,强烈建议您这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.