繁体   English   中英

片段着色器中的平滑渐变

[英]Smooth gradient in fragment shader

我正在寻找某种方法来使用片段着色器获得平滑的渐变。 我有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);
}

但是使用这种方法,我只能得到逐步的颜色分布。

在此处输入图片说明

我期望的结果如下所示:

在此处输入图片说明

我知道如何通过仅将颜色作为属性传递的路径着色器来实现此目的,但这不是那样。 通过将单个float值传递到fragment shader我将获得如此平滑的分布。

您的混合功能在这里并不是真正有用的应用:

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

问题在于,尽管value在[0,1]中,但它不是适当的混合因子。 对于选定的子范围,需要将其缩放为[0,1]。 例如,当值在[ floorIndex=2 ,您的代码使用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作为纹理坐标,并获得所需的结果。 由于它将大多数操作移至专用纹理采样硬件,因此这将更加简单,并且可能还会更加高效。 因此,如果您没有不使用纹理的特定原因,强烈建议您这样做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM