Skip to content

【反向插值】

线性插值的反向功能,即通过混合的结果值获取t值。

公式

t = inverseLerp( a , b ,V)

t = (V - a ) / ( b - a )

  • 已知V,求 a b 之间的 t 值。
  • V等于 a 值时, t 为0。
  • V等于 b 值时, t 为1。
CSharp
public static float InverseLerp( float a, float b, float value ) => ( value - a ) / ( b - a );

应用示例

以下是一个反向插值使用例子,已知人和音源距离,求人能听见的音量。

参数A:多远处音频值为0

参数B:多远处音频值为1

参数C:人和音源的距离

结果值:人听到音量的大小(0~1)

注意:这个例子里,因为音量不能超出1也不能小于0,所以InverseLerp对结果值进行了Camp0~1

获取分段

另外一个使用 inverseLerp 的例子,比如有很多不同长度的分段subsections,也知道根据分段总长度内的一个值val,求出val是哪个分段以及对应分段内的t(0~1)。

javascript
/**
 * 获取子分段里的0~1之间的t值
 * @param subsections 段长度的数组
 * @param val 0~subsections的总长度
 * @returns index: 所在段的索引 subT:所在段内的t值(0~1)
 */
public getSubsectionT(subsections: number[], val: number): { index: number; subT: number } {
    let index = -1;
    let subT = 0;
    let tempStart: number = 0;
    for (let i = 0; i < subsections.length; i++) {
        const subsection = subsections[i];
        const tempEnd = tempStart + subsection;
        subT = Math.inverseLerp(tempStart, tempEnd, val);
        if (subT >= 0 && subT <= 1) {
            index = i;
            break;
        }
        tempStart = tempEnd;
    }
    return { index: index, subT: subT };
}

交互演示

平滑反向插值

如果想反向插值的坡度有平滑,可以使用smoothstep。

Markdown 图片

Markdown 图片

Markdown 图片

glsl
float smoothstep(float a,float b, float x)
{
    float t = saturate((x-a)/(b-a)); // saturate的作用是 clamp0~1
    return t*t*(3.0-(2.0*t));
}

迷雾使用反向插值

Markdown 图片

MIT Licensed