1.作用
SDF (Sign Distance Functions)主要思想是计算点到目标模型的最近距离.
在RayMarching中,如果已知射线点到场景中的左右物体的最短距离,就可以知道我们是否已经碰到的了物体,如果没有碰到场景,可以利用这个信息优化下一步步进的距离。
2.概要
代码包含在SDF.cginc中 基本函数实现来自Inigo’s Quilez大神的blog
整个SDF建模API,包含4部分
1.基本模型(如球长方体,圆锥等) 2.集合操作(并集,交集,差集)
3.Transform 操作(位移,旋转,缩放)
4.变形操作(Twist,blend)
5.镜像复制 (repeat SDF特性)
6.曲线相关(Bezier)
熟悉3D建模工具如3ds max之类的工具,将会发现,这些函数基本上建模工具也有,不过这些建模工具额外还包含了顶点,边,面的操作。
顺便提一下,在raymarching中对不规律事物的建模是低效的。在游戏中不建议使用。
3.API
代码位于SDF.cginc文件中
API 沿袭iq的版本.
1.基本模型
SdXxx形式
2.集合操作
OpU,OpI,OpS
3.Transform
OpMove, OpRot,OpScale
4.变形操作
OpTwist,OpBend
5.镜像操作
OpRep OpRepX
6.曲线
SdBezier
4.SdBezier曲线
其中的一种实现方式的思想:来自这里
bezier公式 t~[0,1]
P(t) = (1-t)²P0 + 2t(1-t)P1 +t²P2
求导
dP/dt(t) = -2(1-t)P0 + 2(1-2t)P1 + 2tP2
简化为
dP/dt(t) = 2(A+Bt)
其中 A = (P1-P0) B = (P2-P1-A)
如图,点M到曲线的最近点P,设点P处的切线为T = dp/dt(t),则向量MP一定垂直于T即
dot(MP,T)= 0
展开
(M - (1-t)²P0 + 2t(1-t)P1 +t²P2).(A+Bt) = 0
继续展开
at3 + bt² + ct + d = 0
其中
M' = P0-M,a = B², b = 3A.B, c = 2A²+M'.B, d = M'.A
接下来是一元三次方程的求解,有公式可以直接求得:
具体可以参考 Mathematics for 3D Game Programming and Computer Graphics (Third Edition)中的 6.1.2 Cubic Polynomials
或者自己去google,最后获得的三个解中找到一个在范围[0,1]中的解即可
具体实现cg版本代码请看SDF.cginc
glsl版本:
2D版本的请看这里
3D版本的请看这里