Appearance
【反向插值】
线性插值的反向功能,即通过混合的结果值获取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。
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));
}