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=" ...
随机推荐
- 不为人知的网络编程(十八):UDP比TCP高效?还真不一定!
本文由LearnLHC分享,原始出处:blog.csdn.net/LearnLHC/article/details/115268028,本文进行了排版和内容优化. 1.引言 熟悉网络编程的(尤其搞实时 ...
- 网络编程懒人入门(十三):一泡尿的时间,快速搞懂TCP和UDP的区别
本文引用了作者Fundebug的"一文搞懂TCP与UDP的区别"一文的内容,感谢无私分享. 1.引言 网络协议是每个搞网络通信应用开发(比如IM.推送.网关等等)的程序员都必须要掌 ...
- Android增加USB Camera摄像头驱动支持
一般情况下kernel需要添加以下宏 ================================= CONFIG_VIDEO_DEV=yCONFIG_VIDEOBUF2_CORE=yCONFIG ...
- Solution Set - Codeforces Global Round 1~8
目录 Codeforces Global Round 1 A. Parity B. Tape C. Meaningless Operations D. Jongmah E. Magic Stones ...
- C# WinForm 托盘程序
实现步骤 创建 NotifyIcon 控件并设置属性: 编写 NotifyIcon 响应控制事件: 在主窗体的Load事件中将 NotifyIcon 添加到系统托盘: 程序退出时,移除系统托盘的 No ...
- Java中的流操作
1. 字符流 1.1字符输入流 - Reader - FileReader 涉及到连接的,用完了就要关闭. **为什么read方法 返回的值是 int,而不是char?因为读到结尾的时候,cha ...
- 分布式文件系统KFS基础知识介绍
Kosmos distributed file system,简称KFS,是一个类GFS的分布式文件系统,被设计用于分布式的结构化存储.下面将对KFS的体系结构进行简单介绍,最后给出一个使用KFS C ...
- leetcode-Linux 简介
https://leetcode-cn.com/leetbook/read/awesome-linux-handbook/eg4ecm/ Linux 系统是一种金字塔模型的系统,如下所示 应用程序发起 ...
- DAB实现中用到的主要设计模式
DAB C++ 版本设计模式应用实践 1. 命令模式 (Command Pattern) 设计目标 模块解耦:实现各模块独立编译.测试.运行,消除模块间直接依赖 扩展准备:为桥接模式实现奠定基础 依赖 ...
- 在SOUI4中使用非客户区自绘
前段时间用sdl嵌入SOUI做视频播放器,由于SOUI习惯屏蔽系统默认的非客户区,而在窗口自己的客户区分出一块来模拟非客户区,导致窗口在拉伸的时候,SOUI窗口会出现比较严重的闪烁(不光是SOUI这样 ...