0

I would like to know if there's a way to remap a value that goes from 0 to 1 constantly like this.

enter image description here

Into those values (those are examples).

enter image description here

This might be some function transformation but I can't find the way to do that. I've tried using a lookup texture but in my opinion this is not the best solution.
Thank you very much.

MaT
  • 1,556
  • 3
  • 28
  • 64

2 Answers2

1

One way to do this is to use a fixed number of linear gradient stops. For example, you could have two float4 values which define the position and value for four individual stops:

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);
}

Example remappings are below, using increasing values greater than 1 for unused stops to avoid division by zero in the shader. This won't affect the result, as the lerp will snap to the lower value anyway.

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};

Of course you could use a different number of stops if you need them depending on the complexity of your gradient.

MooseBoys
  • 6,641
  • 1
  • 19
  • 43
0

As @dari said, the smoothstep function is the best solution to achieve what I need.

MaT
  • 1,556
  • 3
  • 28
  • 64