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=" ...
随机推荐
- 高通MSM8909 Mutil-HAL Sensor 调试
Mutil-HAL的介绍: Sensors Multi-HAL 是一个框架,允许传感器 HAL 与其他传感器 HAL 一起运行. Sensors Multi-HAL 动态加载作为动态库存储在供应商分区 ...
- 为你的Blazor程序加入本地化多语言功能
本地化 本地化是为给定语言和地区定制应用程序的过程. BootstrapBlazor 组件允许您将其 UI 元素转换为所需的语言.这包括按钮.过滤器操作符属性等文本.组件内部默认使用当前请求 UI 文 ...
- biancheng-Thymeleaf教程
Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎.它与 JSP,Velocity,FreeMaker 等模板引擎类似,也可以轻易地与 Spring MVC 等 Web ...
- 性能飞跃!TensorRT-YOLO 6.0 全面升级解析与实战指南
一.核心升级亮点速览 多Context共享引擎:高效推理,最大化硬件资源利用率 TensorRT-YOLO 6.0 引入了创新的多Context共享引擎机制,允许多个线程共享同一个Engine进行推理 ...
- protocol buffers(protobuf)安装教程
本文按照mac讲解protobuf的安装,windows上比较好安装按照mac的基本流程就可以安装成功,mac上的安装有的时候比较容易出现问题 一.通过brew的方式安装(仅Mac) 需要mac中存在 ...
- Jenkins插件:Git
Jenkins插件:Git Jenkins,作为一款备受欢迎的持续集成和持续交付工具,在软件开发领域发挥着举足轻重的作用.它不仅能够与Git无缝集成,还能实现代码的自动化拉取.构建与部署,极大地提升了 ...
- Kali 修改root密码
Kali 修改root密码 进入 Kali 系统,切换 root 用户 sudo su 输入当前用户密码 成功切换到 root 用户后,进行修改密码 passwd root
- Linux下普通用户免密切换root
问题需求: Linux下普通用户doge免密切换root 问题解决: Linux下普通用户切换到root用户下,默认情况是需要输入密码很不方便,因此需要实现普通用户doge免密切换到root用户. 示 ...
- Iceberg 待学习链接
1.Iceberg事务特性解读 https://blog.csdn.net/naisongwen/article/details/123343566 2.FLink全链路时延-测量方式 https:/ ...
- Luogu P9055 [集训队互测 2021] 数列重排 题解 [ 紫 ] [ 构造 ] [ 数学 ]
数列重排:差点就场切的神仙构造,最后一步想假了,导致我模拟赛荣获 25+5+0 的好成绩! 这题部分分很有启发性,跟着一步一步打基本能想到正解的构造,但也有可能想偏部分分的意思,想假策略. 构造 先看 ...