FishMan的技术专栏 Game Developer/Technical Artist

中级Shader教程10 shader建模工具--SDF

2018-04-23
Jiepeng Tan

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版本的请看这里

配套视频


Similar Posts

Comments