着色器值重新映射 - 混合衰减
Shader value remap - Blend Falloff
我想知道是否有一种方法可以像这样不断地重新映射从 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
无论如何都会捕捉到较低的值。
重新映射 1:sp = {0,0.45,0.55,1}; sv = {0,0,1,1};
重新映射 2:sp = {0,0.1,1,2}; sv = {0,1,1,1};
重新映射 3:sp = {0,0.9,1,2}; sv = {0,0,1,1};
重新映射 4:sp = {0,1,2,3}; sv = {0,0.5,1,1};
当然,如果需要,您可以根据渐变的复杂性使用不同数量的停靠点。
正如@dari 所说,smoothstep 函数是实现我所需要的最佳解决方案。
我想知道是否有一种方法可以像这样不断地重新映射从 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
无论如何都会捕捉到较低的值。
重新映射 1:sp = {0,0.45,0.55,1}; sv = {0,0,1,1};
重新映射 2:sp = {0,0.1,1,2}; sv = {0,1,1,1};
重新映射 3:sp = {0,0.9,1,2}; sv = {0,0,1,1};
重新映射 4:sp = {0,1,2,3}; sv = {0,0.5,1,1};
当然,如果需要,您可以根据渐变的复杂性使用不同数量的停靠点。
正如@dari 所说,smoothstep 函数是实现我所需要的最佳解决方案。