SDF Line相关公式推导

SDF Line相关公式推导

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

image-20240712114012533 image-20240712114050014

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

那么对于空间中的点P1,P2,P3,他们的分布有如下三种

image-20240715102521984

其中P1到线段的距离是|P1Q|P2到线段的距离是|P2A|P3到线段的距离是|P3B| |P1Q|的求法,

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

在这里插入图片描述

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

|BQ|=BP1BA|BA|

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

|BQ|=BP1BA|BA|2

熟悉这个求解投影长度的代码之后,在看一下另外两个点P2,P3我们会发现一个投影长度占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,此时求得是向量bpba也就是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

posted @   CuriosityWang  阅读(35)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示

请作者喝杯咖啡