GLSL 片段着色器中的颜色插值?

问题描述 投票:0回答:3

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

我发现我需要在

gl_FragColor
中写入颜色值,这是一个维度为 4 的向量。我不确定如何仅通过一个标量值来计算
gl_FragColor
的 R、G 和 B 通道范围为 0 到 1.0(从绿色到红色,0.5 时为白色)

opengl glsl fragment-shader
3个回答
5
投票
#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 纹理进行采样。


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.);
© www.soinside.com 2019 - 2024. All rights reserved.