SDF矩形(附圆角)公式推导
SDF矩形(附圆角)公式推导
矩形
一般情况下,我们会使用(top_left, top_bottom), (width, height)来定义一个矩形,但是对于SDF而言,使用(centerX, centerY), (HalfSizeX, HalfSizeY)会更方便一些。
假设一个矩形,我们先定义原点在(0, 0),那图像如下:

记住要计算的内容:点与形状最近边缘之间的距离。
那么会出现两种情况,当要计算矩形内的点与矩形最近边缘的距离时,我们可以看下下图的表示:

找到最近的边缘,然后做垂线就可以计算出SDF值,A,B,C点皆是如此。
但是对于形状外的点,情况就有些不同:

对于AB点来说,情况是一致的,找到最近的边缘,然后就可以得到距离了。
但是我们发现,对于C,D点,矩形内点与矩形最近边缘的距离其实是到角点E的距离。所以当计算矩形SDF时候,要考虑这种特殊情况,在第一象限的时候,代码如下:
float sdf_rect(vec2 point, vec2 half_size) {
point = abs(point);
// 计算每个点到两个边的距离
float x_dist = point.x - half_size.x;
float y_dist = point.y - half_size.y;
// 如果一正一负,或者全是负数
// 则可以直接取max(x_dist, y_dist)作为对应点的SDF值
// distance to corner
float c_dist = length(point - half_size); // 求到corner的距离
// 如果都为正数,说明是C、D点的情况,则要返回到corner的距离
float res = x_dist > 0.0 && y_dist > 0.0 ?
c_dist :
max(x_dist, y_dist);
return res;
}
那对于其他象限呢,要知道,一个矩形是对称的,所以要求的其他象限的点的SDF值,可以都映射到第一象限去求:

最终的代码是这样的:
float sdf_rect(vec2 point, vec2 half_size) {
point = abs(point);
// 计算每个点到两个边的距离
float x_dist = point.x - half_size.x;
float y_dist = point.y - half_size.y;
// 如果一正一负,或者全是负数
// 则可以直接取max(x_dist, y_dist)作为对应点的SDF值
// distance to corner
float c_dist = length(point - half_size); // 求一下到corner的距离
// 如果都为正数,说明是C、D点的情况,则要返回到corner的距离
float res = x_dist > 0.0 && y_dist > 0.0 ?
c_dist :
max(x_dist, y_dist);
return res;
}

进一步探讨
圆角矩形
现在的设备设计都开始讲究一个圆角矩形了,比如苹果的各种设备,我们也希望得到的矩形是一个圆角。

答案很简单,就是将最终的SDF值减去一个r,对的,就是这么简单。

我们知道,处在矩形边缘上的点的SDF值是0,如果把所有相同值的SDF化成一条线,则可以得到一个类似这样的等高线图。

其实问题的关键(问题的关键就是关键的问题?)在角点处,角点处相同的SDF值连成的等高线是一个圆,所以SDF值做减法的时候,形状会变成圆角,这里的r一般情况下可以根据矩形的边长进行线性的设置大小。
提供一种比较好理解的方式就是因为SDF是一个函数,输入的是一个平面上每一个点的坐标,输出是每个点到0平面的距离。当减去一个r的时候,要再得到0平面,则原先的SDF值需要扩大到原来的r位置。
如果是做加法呢,矩形会变得比之前小,但是不是圆角。
镂空矩形


具体的解释和上面圆角矩形的设置是一样的,核心是找到+r 和 -r所在的那个等高线,然后分析一下值的变化。
相关代码: https://www.shadertoy.com/view/MXVXDc
refer
SDF矩形(附圆角)公式推导的更多相关文章
- 详解使用CSS3绘制矩形、圆角矩形、圆形、椭圆形、三角形、弧
1.矩形 绘制矩形应该是最简单的了,直接设置div的宽和高,填充颜色,效果就出来了. 2.圆角矩形 绘制圆角矩形也很简单,在1的基础上,在使用css3的border-radius,即可. 3.圆 根据 ...
- java在线聊天项目 使用SWT快速制作登录窗口,可视化窗口Design 更换窗口默认皮肤(切换Swing自带的几种皮肤如矩形带圆角)
SWT成功激活后 new一个JDialog 调整到Design视图 默认的视图模式是BorderLayout,无论你怎么拖拽,只能放到东西南北中的位置上 所以,我们把视图模式调整为AbsoluteLa ...
- Android之圆角矩形
安卓圆角矩形的定义 在drawable文件夹下,定义corner.xml <?xml version="1.0" encoding="utf-8"?> ...
- CODESOFT中的圆角矩形的弧度该怎样设置?
CODESOFT标签设计软件提供多种图形制作按钮,方便用户更为快捷的制作标签.其中就包括矩形,圆角矩形的快捷创建按钮.本文将介绍如何设置CODESOFT圆角矩形的弧度. 若有疑问可直接访问:htt ...
- libgdx学习记录12——圆角矩形CircleRect
libgdx提供了ShapeRenderer这个工具,用它可以画点.画线.画圆.画矩形.画椭圆.画扇形,但是没有提供画圆角矩形的方法. 刚开始自己尝试分成8端,4端画直线,4端画扇形,发现多了半径几部 ...
- css+div制作圆角矩形的四种方法
圆角矩形一向是设计师最倾心的一种设计,因为他们可以让整个网页生动起来,不那么死板,所以,作为一个优秀的网页设计师,学会一种或多种编辑圆角矩形的方法是必不可少的,而且圆角矩形应用范围极广,一个网页内的所 ...
- 在Microsoft Expression Blend 2 中绘制圆角矩形按钮
原文:在Microsoft Expression Blend 2 中绘制圆角矩形按钮 /* 声明:转载请保留此信息:http://www.BrawDraw.com, http://www.ZPXP.c ...
- CSS中设置元素的圆角矩形
圆角矩形介绍 在CSS中通过border-radius属性可以实现元素的圆角矩形. border-radius属性值一共有4个,左上.右上.左下.右下. border-radius属性值规则如下:第一 ...
- android 自定义控件——(一)圆角按钮
----------------------------------矩形或圆角类型(源代码下有属性解释)------------------------------------------------ ...
- [翻译svg教程]svg中矩形元素 rect
svg 元素<rect> 是一个矩形元素,用这个元素,可以你可以绘制矩形,设置矩形宽高,边框的宽度颜色,矩形的填充颜色,是否用圆角等 rect 示例 <svg xmlns=" ...
随机推荐
- 在Eclipse配置并编译worldwind java2.1.0源码,选中Src目录下gov.nasa.worldwindx.examples包下ApplicationTemplate.java类文件run时提示“javax.xml.parsers.DocumentBuilderFactory.setFeature(Ljava/lang/String;Z)V”异常的解决办法
问题现象: 在Eclipse配置并编译worldwind java2.1.0源码,选中Src目录下gov.nasa.worldwindx.examples包下ApplicationTemplate.j ...
- 飞书lark机器人 自动化发版
飞书lark机器人 自动化发版 #1 介绍 开发飞书机器人接收消息并调用构建接口, 实现自动化发版 发送指令 -> 机器人接收指令 -> 调用jenkins-job远程构建与部署 jenk ...
- docker导入和导出
save和export 镜像导入和导出有2种方式,分别为 save和load.export和import save导出的是镜像:export导出的为容器 save导出会保存镜像所有的提交记录:expo ...
- 小程序获取定位完整的封装js(uniapp)
1.小程序获取定位,首先需要在微信公众平台,申请getLocation接口(开发管理->接口设置) 2.在manifest.json打开源码视图,增加代码 "mp-weixin&quo ...
- Nginx配置文件及默认配置说明
默认安装的1.16.1版本的主配置文件nginx.conf如图: 业务性配置引入额外的配置文件/etc/nginx/conf.d/default.conf如图: 现在可以在默认的根目录下找到2个页面 ...
- SM4代码实现
算法过程 更多的原理介绍参考:SM4原理介绍 代码实现 S盒实现 #include <stdio.h> /* SM4-S盒实现: 由三个复合函数组成,S(x)=L(I(L(x))),其中L ...
- ctfshow--web2 sql注入
这题是考sql注入,我们先用个万能语句注入 发现它上面会出现 欢迎你,ctfshow 那么这就很明显了,这个用户的名字就是ctfshow 那么猜测flag会不会是在flag的用户里面呢我们提交一下 如 ...
- nginx basic验证
打开个生成htpasswd的网站 输入信息生成结果 将结果保存到nginx一个文件里面 修改nginx的conf文件 auth_basic "webA"; #这个"&qu ...
- 掌握Python的hasattr()函数
掌握Python的hasattr()函数 在Python编程中,hasattr()函数是一个非常实用的内置函数,它允许我们动态地检查一个对象是否拥有某个属性.这个功能在编写灵活.可扩展的代码时尤为重要 ...
- FLink09的RichFlatMap和RichMap使用
一.数据源配置 pom文件:https://www.cnblogs.com/robots2/p/16048648.html 二.RichFlatMap代码,输入单行输出多行 package net.x ...