shader里面有个函数叫smoothstep,是用来做平滑插值的,dx的文档对其介绍如下
smoothstep (DirectX HLSL)
Returns a smooth Hermite interpolation between 0 and 1, if x is in the range [min, max].
ret smoothstep(min, max, x)
Parameters
-
min
[in] The minimum range of the x parameter.
-
max
[in] The maximum range of the x parameter.
-
x
[in] The specified value to be interpolated.
Return Value
Returns 0 if x is less than min; 1 if x is greater than max; otherwise, a value between 0 and 1 if x is in the range [min, max].
Use the smoothstep HLSL intrinsic function to create a smooth transition between two values. For example, you can use this function to blend two colors smoothly.
可以看介绍里说了,Smoothstep就是使用的Hermite插值,
三次Hermite插值公式是
P(t)=(2∗t3−3∗t2+1)P0+(t3−2∗t2+t)M0+(t3−t2)M1+(−2∗t3+3∗t2)P1
其中P0是起始点,P1是终结点,M0是起始点处的方向,M1是终结点处的方向。参数t从0变化到1的过程中P(t)形成的轨迹构成了从P0到P1的平滑曲线,而且这个曲线两端顶点处的切向量就是M0,M1,还要说明的就是M0,M1的大小会影响到曲线的形状,可以把这个过程想象成一个机车从P0开到P1,M0,M1更像是速度的表示,当M0比较大时,在P0附近的曲线会沿M0方向冲出去更多一些才会弯曲。
Smoothstep插值的公式是
Smoothstep(t)=−2∗t3+3∗t2
对于dx文档中的参数,我们可以使用
t=(x−min)/(max−min)
先计算得到t再使用前面的公式。
为什么Smoothstep的公式比Hermite简化的这么多,我尝试推导了一下,
把(0,0)代入P0,(1,1)代入P1,(1,0)代入M0,(1,0)代入M1,
用Px(t)表示Hermite插值的x分量,Py(t)表示Hermite插值的y分量,则有
Px(t)=(2∗t3−3∗t2+1)∗0+(t3−2∗t2+t)∗1+(t3−t2)∗1+(−2∗t3+3∗t2)∗1=t
Py(t)=(2∗t3−3∗t2+1)∗0+(t3−2∗t2+t)∗0+(t3−t2)∗0+(−2∗t3+3∗t2)∗1=−2∗t3+3∗t2
再把参数t消掉就可以得到
Py=−2∗Px3+3∗Px2
和Smoothstep插值公式是一致的。
我把这篇旧博文转过来主要为了测试在网页上渲染Markdown公式的表现 😛