SDF Line相关公式推导

SDF Line相关公式推导

线段是SDF形状的基元之一,可以被用来建模一些形状,比如昆虫的腿,植物的根茎等。

image-20240712114012533
image-20240712114050014

下面这篇文章介绍一下Line公式的推导,首先记住我们要求的变量,点到形状最近的距离

那么对于空间中的点\(P_1, P_2, P_3\),他们的分布有如下三种

image-20240715102521984

其中\(P_1\)到线段的距离是\(|\vec{P_1Q}|\)\(P_2\)到线段的距离是\(|\vec{P_2A|}\)\(P_3\)到线段的距离是\(|\vec{P_3B}|。我们先看\) \(|\vec{P_1Q}|\)的求法,

其实本质是一个向量在另一个向量上的投影长度,此处借用云飞Ran的推导过程:

在这里插入图片描述

这里我们采用第二种方法,因此定义向量,\(\vec{BA},\vec{ BP_1}\),然后使用如下公式便可以求出\(\vec{BQ}\)的长度。

\[|\vec{BQ}| = {\vec{BP_1} \cdot \vec{BA}\over |\vec{BA}| } \]

此时投影长度的比例可以定义为:

\[|\vec{BQ}| = {\vec{BP_1} \cdot \vec{BA}\over |\vec{BA}|^2 } \]

熟悉这个求解投影长度的代码之后,在看一下另外两个点\(P_2, P_3\)我们会发现一个投影长度占BA的比例小于0,另一个大于1。

熟悉完上面的内容之后,我们就可以看一下SDF Line的实现了:

// Original SDF line segment function
float sdSegmentRegular( in vec2 p, in vec2 a, in vec2 b)
{
  vec2 bp = b-p, ba = b-a; //求解向量
  float h = clamp( dot(bp,ba)/dot(ba,ba), 0.0, 1.0 );
  return length(bp - ba*h );
}                            


void SDFLine(in vec2 p, in vec2 a, in vec2 b,  in float r, out float sdf) {
  sdf = sdSegmentRegular(p, a, b, r);
}
float h = clamp( dot(bp,ba)/dot(ba,ba), 0.0, 1.0 );

这段代码巧妙的地方在于通过这行代码统一了三种分布的点,当p在a,b点的左侧时,h = 1,此时求得是向量\(\vec{bp}-\vec{ba}\)也就是\(\vec{ap}\)的长度,这里大致如图:

image-20240715104318978

但是这段代码运行起来是看不到任何东西的,我们还需要减去一个 width,才能得到LineSegment;

// Original SDF line segment function
float sdSegmentRegular( in vec2 p, in vec2 a, in vec2 b, in float r )
{
  vec2 bp = b-p, ba = b-a;
  float h = clamp( dot(bp,ba)/dot(ba,ba), 0.0, 1.0 );
  return length( bp - ba*h ) - r;
}                            


void SDFLine(in vec2 p, in vec2 a, in vec2 b,  in float r, out float sdf) {
  sdf = sdSegmentRegular(p, a, b, r);
}

具体的原理我们可以看一下这篇博客圆角矩形小节。此处就不再赘述啦。

refer

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王行知

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值