2014-06-05 49 views
2

我需要将标量值映射到范围为0到1的颜色。它将从绿色变为红色(从0到1)使用纹理坐标进行线性插值(范围从0到1)Fragment Shader GLSL中的颜色插值?

我是新的OpenGL和GLSL,到目前为止,我想通了,我需要写在

gl_FragColor 

是尺寸4的向量我不知道我怎么能计算出R色值, G和B通道的gl_FragColor只是一个范围为0到1.0的标量值(它将从绿色变为红色并且在0.5它将变为白色)

+0

您是使用1D纹理还是采用> = 2D UV的标量? – Jessy

+0

2D纹理中的每个像素都会给出从0到1的值。 – ammar26

+0

好吧。坐标与当时的问题无关。 – Jessy

回答

1
#version 120 

... 

float remap(float minval, float maxval, float curval) 
{ 
    return (curval - minval)/(maxval - minval); 
} 

... 

const vec4 GREEN = vec4(0.0, 1.0, 0.0, 1.0); 
const vec4 WHITE = vec4(1.0, 1.0, 1.0, 1.0); 
const vec4 RED = vec4(1.0, 0.0, 0.0, 1.0); 

float u = <whatever, grabbed from a uniform?>; 
u = clamp(u, 0.0, 1.0); 
if(u < 0.5) 
    gl_FragColor = mix(GREEN, WHITE, remap(0.0, 0.5, u)); 
else 
    gl_FragColor = mix(WHITE, RED, remap(0.5, 1.0, u)); 

或者您可以采样3像素1D纹理。

+1

永远不要在fs中分支也不是绝对可以避免的。即使是最现代化的硬件碎片也是以4个块为单位进行评估的,并且所有分支或其中任何一个分支都会强制gpu对每个碎片进行评估,而不管是否需要。此外,这完全是关于一致性。接近另一个的碎片应该尽可能“一致”(采用相同的分支),因为这可能导致仅运行必要的分支。 – RecursiveExceptionException

+0

为了解决避免分支的问题,应该总是使用'mix','step','smoothstep'等函数,因为它们更快,即使分支尽可能一致。当然,有些情况并非如此,但一般来说,这些建议值得黄金分析。 – RecursiveExceptionException

3

如果你的范围为0到1的值被命名为val

if (val < 0.5) 
{ 
    gl_FragColor = vec4(2.0 * val, 1.0, 2.0 * val, 1.0); 
} 
else 
{ 
    gl_FragColor = vec4(1.0, 2.0 * (1.0 - val), 2.0 * (1.0 - val), 1.0); 
} 

或者,如果你想避免分支语句:

如果
gl_FragColor = vec4(min(2.0 * val, 1.0), 
        min(2.0 * (1.0 - val), 1.0), 
        2.0 * min(val, 1.0 - val), 
        1.0); 

不知道这实际上是更快。正如@Jessy指出的那样,如果颜色缓冲区具有标准化格式,则可以简化该操作,因为在这种情况下,输出颜色会自动限制为[0,1]范围,因此不需要调用几个min调用:

gl_FragColor = vec4(2.0 * val, 
        2.0 * (1.0 - val), 
        2.0 * min(val, 1.0 - val), 
        1.0); 
2

您不必担心手动夹紧,因为gl_FragColor夹在0-1之间。

float red = 2. * texel; 
float green = 2. - red; 
gl_FragColor = vec4(red, green, min(red, green), 1.); 
+0

确实如此,至少只要颜色缓冲区具有标准化格式,就可以简化。我没有想到这一点。 –