着色器值重新映射 - 混合衰减

时间:2015-09-23 18:40:26

标签: opengl directx glsl shader hlsl

我想知道是否可以像这样重新映射从0到1的值。

enter image description here

进入这些值(这些是示例)。

enter image description here

这可能是一些功能转换,但我找不到这样做的方法。我尝试过使用查找纹理,但在我看来,这不是最佳解决方案 非常感谢你。

2 个答案:

答案 0 :(得分:1)

一种方法是使用固定数量的线性渐变色标。例如,您可以有两个float4值,用于定义四个单独停靠点的位置和值:

cbuffer CB0
{
    float4 sp; // stop positions
    float4 sv; // stop values
}

float4 main(float2 coord : COORD) : SV_TARGET
{
    float x = coord.x;
    float v = 0;
    if(x < sp.x) v = sv.x;
    else if(x < sp.y) v = lerp(sv.x, sv.y, (x - sp.x) / (sp.y - sp.x));
    else if(x < sp.z) v = lerp(sv.y, sv.z, (x - sp.y) / (sp.z - sp.y));
    else if(x < sp.w) v = lerp(sv.z, sv.w, (x - sp.z) / (sp.w - sp.z));
    else v = sv.w;
    return float4(v,v,v,1);
}

示例重映射在下面,对于未使用的停靠点使用大于1的增加值,以避免在着色器中除以零。这不会影响结果,因为lerp无论如何都会捕捉到较低的值。

Remap1:sp = {0,0.45,0.55,1}; sv = {0,0,1,1};

Remap2:sp = {0,0.1,1,2}; sv = {0,1,1,1};

Remap3:sp = {0,0.9,1,2}; sv = {0,0,1,1};

Remap4:sp = {0,1,2,3}; sv = {0,0.5,1,1};

当然,如果您需要它们,可以使用不同数量的停靠点,具体取决于渐变的复杂程度。

答案 1 :(得分:0)

正如@dari所说,smoothstep功能是实现我需要的最佳解决方案。