计算机图形学【GAMES-101】5、几何(距离函数SDF、点云、贝塞尔曲线、曲面细分、曲面简化)

快速跳转:
1、矩阵变换原理Transform(旋转、位移、缩放、正交投影、透视投影)
2、光栅化(反走样、傅里叶变换、卷积)
3、着色计算(深度缓存、着色模型、着色频率)
4、纹理映射(重心坐标插值、透视投影矫正、双线性插值MipMap、环境光遮蔽AO)
5、几何(距离函数SDF、点云、贝塞尔曲线、曲面细分、曲面简化)
6、阴影映射(Shadow Mapping)
7、光线追踪原理(线面求交、预处理光追加速)
8、辐射度量学与光线追踪
9、蒙特卡洛路径追踪(Path Tracing)(光源采样)
10、材质(BRDF)(折射、菲涅尔项、微表面模型、各向异性材质)
11、渲染前沿技术介绍(双向路径追踪BDPT、MLT、光子映射、实时辐射度、外观建模)
12、相机(视场、曝光、光圈(F-Stop)、薄棱镜近似、CoC、景深)
13、光场、颜色与感知
14、动画(物理模拟、质点弹簧系统、粒子系统、运动学、动作捕捉、欧拉方法)


1 几何图形的表示方式

1.1 几何的隐式表示法

优点:

  • 容易表述(一个函数就行),对于存储空间来说非常有利
  • 判断一个点在几何内/外特别快
  • 与光线求交点特别容易
  • 对于简单的形体,描述非常准确,不容易出现误差
  • 处理变化的拓扑结构非常容易,比如流体模拟

缺点:很难用函数描述一个复杂的模型,复杂的模型只能用显示表示(三角面模型)

1.1.1 函数

不告诉点的具体位置,只描述点的关系,即只给一个函数,表示一个几何形体

缺点:非常抽象,不能马上知道是个什么样的几何模型。

如下,前两个还好,后面一个光看公式你能知道是个什么三维图形么,不知道!
在这里插入图片描述

1.1.2 Constructive Solid Geometry(CSG)

用布尔运算来组合模型
在这里插入图片描述

1.1.3 距离函数SDF

SDF:Signed Distance Function

  • 不直接描述几何的表面,而是描述空间中任何一个点到该表面的最近距离(垂直)
  • signed表示有正负,0表示就在几何表面上,+表示在外部,-则在内部
  • 这种表示非常适合做圆滑过度的边界,比如下图,实现过程为描述几何图形->算出各自的距离函数->对距离函数做融合->恢复成新的几何图形。

这里看不明白的话,可以结合这篇文章的 【5.1 有向距离场SDF(Signed Distance Field)】

在这里插入图片描述

非常重要的原理图
输入:某种物体的边界,A图的物体覆盖屏幕的1/3,B物体覆盖屏幕2/3
在这里插入图片描述
希望:做个线性融合,求出中间状态
操作:
(1)求出A,B的距离函数,如A 在1/3处是边界所以边界上的点全是0;边界左边的点在物体内部,所以为负数且越远负值越大,边界右边的点则正数递增。B同理。
(2)然后对这两个函数做一个线性的融合,然后就可以找到融合的新的边界(数值为0的那些点),并且负数表示物体内部,正数表示外部,进而得到新的几何形体。

在这里插入图片描述

对任意的两个几何模型,算出其距离函数->做函数线性混合->再变回几何模型->得到混合的模型

总而言之言而总之,就是两个距离函数F1,F2混合得出新的距离函数SDF,这个距离函数呢,在空间中所有为0的点就是新的边界了,为负的点就是几何内部,为正就是几何外部,从而得到新的融合之后的图形
在这里插入图片描述

距离函数的应用

下面这个是纯用像素着色器实现的
在这里插入图片描述
在这里插入图片描述

如何从距离函数得到几何体的表面呢?

1.1.4 水平集(Level Set)

从距离函数,反求几何表面就是,类似的隐函数告诉了函数式f(x,y,z) = 0,求物体是个啥样

以2D空间为例,在不同的格子中心有不同的值,格子之间的值用双线性插值可以求出来;在这样一个平面中里面找函数值为0的点连起来就是物体边界了
在这里插入图片描述
3D空间中的水平集,跟3D纹理联系起来了,3D纹理就是描述的三维中物体的任意一个点的属性。由于纹理定义了空间所有点的密度,比如骨骼的密度是5,空气为0,那么找到梯度最大的那些点就可以作为边界
在这里插入图片描述

1.2 几何的显式表示法

直接给出所有点在空间的位置。可以通过纹理映射的方式给出、一张纹理图的每个uv坐标对应空间中一个点,遍历所有uv即得到几何形体
在这里插入图片描述

  • 显示表示的优缺点
    优点:很容易、快速得到几何模型
    缺点:判断点是否在几何内/外很困难

1.2.1 点云(Point Cloud)

最简单的表示方法:点(x,y,z)列表。点云可以表示任何类型的几何体,但很少用,一般扫描出来的原始数据是点云数据,之后会将其转换成三角面模型再计算着色
在这里插入图片描述

在这里插入图片描述

1.2.2 多边形模型

用得最广泛的方法,一般用三角形或者四边形来建模
在这里插入图片描述
在代码中怎么表示一个三角形组成的模型?

.obj文件:描述了“顶点、法线、纹理坐标、顶点组合关系”。比如下面代码,描述的就是个立方体

  • v:顶点8个
  • vt:纹理坐标,其中有共用的纹理坐标,下面代码是用软件生成的,会有重复问题。
  • vn:法线,6个面有6个法线,但vn却有8个,重复定义,3 4行、5 6行是一样的(忽略精度)
  • f:顶点索引,定义哪三个点组成三角形,后面分别是定义顶点对应的纹理坐标、法线。
    在这里插入图片描述

对显示几何模型的处理

  • 网格细分:增加模型面数
  • 网格简化:减少模型面数
  • 网格正规化:让网格大小更均匀、接近正三角形
  • 游戏引擎中的LOD技术不就是动态的进行网格细分/简化么。

1.2.3 贝塞尔曲线

以三次贝塞尔曲线为例
起点P0,终点P3, 起点切线P0P1,终点切线P2P3
P1和P2其实没啥关系,但是一般还是给他们俩连个线的
在这里插入图片描述

  • 如何用三个控制点确定一条二次贝塞尔曲线???————de Casteljau算法
    (1)认为时间从0~1,从0开始每个时刻都找到曲线的一个点,到1时就得到整个贝斯尔曲线
    (2)任取一个时刻t,根据t在时间的比例,分别插值三次(两个线段分别做一次,对得到的两个点之间再做一次插值),最终得到的点就是曲线的一个点。
    在这里插入图片描述
  • 2次贝塞尔曲线(动图是偷来的…)

请添加图片描述)

  • 3次贝塞尔曲线

请添加图片描述

  • 贝塞尔曲线的代数公式
    比如2阶曲线是由3个顶点和时间t 做计算得到的,那么一定可以写出一个公式来表述。
    在这里插入图片描述
  • 更一般,给n个控制点,在t时刻的曲线点的计算公式
    在这里插入图片描述
    伯恩斯坦多项式:i = 1,2,3,…,n
    在这里插入图片描述在这里插入图片描述
    最终就算是3D空间的点,只需要更改每个点为三维坐标即可
    在这里插入图片描述
    在这里插入图片描述
    具体伯恩斯坦多项式推导可看这篇文章
  • 贝塞尔曲线好用的性质
    (1)首/尾两个控制点一定是起点/终点
    (2)对控制点做仿射变换,再重新画曲线,跟原来的一样,不用一直记录曲线上的每个点
    (3)凸包性质:画出的贝塞尔曲线一定在控制点围成的线之内
  • 请逐段使用贝塞尔曲线(一般用4个控制点、3次曲线)这在各种游戏引擎中很常见
    在这里插入图片描述

1.2.4 Splines样条线

一条由一系列控制点控制的曲线
在这里插入图片描述

  • B-splines 基样条
    对贝塞尔曲线的一种扩展,比贝塞尔曲线好的一点是:局部性,可以更局部的控制变化。
  • NURBS
    比B样条更复杂的一种曲线,了解即可。

1.2.5 贝塞尔曲面

  • 将贝塞尔曲线扩展到曲面
    依然是用多段贝塞尔曲线对应曲面进行无缝拼接的。
    在这里插入图片描述
  • 三次贝塞尔曲面
    下面这个曲面 是4x4=16个控制点应用双线性插值形成的
    在这里插入图片描述
  • 插值
    很容易理解,每4个控制点可以绘制出一条贝塞尔曲线,贝塞尔曲线上时刻t的值是通过3次插值得来的,这样在t时刻一共4条贝塞尔曲线又能分别提供1个控制点,一共4个控制点,再插值画一条贝塞尔曲线(下图蓝色部分),这条线就是t时刻的平面的线,然后每个时刻都画一条线则得到贝塞尔曲面。
    在这里插入图片描述
    容易理解
    在这里插入图片描述
    注意时间那个变量变成二维了,t1 、t2用uv表示也行
    (u,v)对应两个时间,u时刻算的是4个控制点的位置,v时刻则是这四个控制点控制的贝塞尔曲线的点的位置,即最终曲面的位置。
  • 因为用(u,v)表示最终位置,所以贝塞尔曲面也是一种显示的表示
    在这里插入图片描述

2 几何的操作方式

2.1 曲面细分

2.1.1 Loop细分(Loop Subdivision)

Loop是人名
两步:先增加三角形个数,后调整位置
如下图,够明显了吧,不仅仅是增加三角形的个数,还要调整新/旧顶点的位置。
在这里插入图片描述

  • 新顶点调整方法
    对于中间那个白点,处于共线的A、B顶的权重相对C、D高一些
    在这里插入图片描述
  • 旧顶点调整方法
    n:旧的顶点连接的边的数量为,度越多,则自身位置的权值越小
    u:u就是个影响系数系数,n=3时,u=3/16;否则u=3/8n
    在这里插入图片描述
  • loop细分的结果
    很明显确实光滑了不少
    在这里插入图片描述

2.1.2 Catmull-Clark细分

这种细分对于更一般的情况效果也很好,(全三角形、全四边形、三角形四边形混合)
·

  • 细分步骤
    1)给每个面增加1个顶点
    2)给每条边增加1个中点
    3)连接所有新增加的点
  • 一次细分后
    奇异点增加了2个(有多少个非四边形面就增加多少个)
    非四边形面0个(不管多少个全部消失)
    在这里插入图片描述
  • 再细分下去
    奇异点不会再增加,因为首次细分后全是四边形了 顶点的度也不会变
    在这里插入图片描述
  • 顶点位置更新规则
  • 新顶点,分为面新增点和边新增点
    在这里插入图片描述
  • 旧顶点,不光受8个新顶点影响还有4个旧顶点的影响
    在这里插入图片描述
  • 最终效果特别好
    在这里插入图片描述

2.2 曲面简化

减少三角形数量的同时保持原有的基本形状
可以看到,如果离得很远3万面和3000面甚至是300面根本看不出啥区别,仅仅笑掉大牙而已
所以在大型项目中应用LOD技术是非常有必要的!
在这里插入图片描述
如果说MipMap是纹理上的层次结构——根据不同距离(覆盖像素区域的大小)选择不同层的纹理
那么LOD就是几何的层次结构——根据不同距离(覆盖像素区域的大小)选择不同的模型面数

2.2.1 边坍缩

  • 如下图,其实是对两条边进行坍缩了
    首先,三角形的任意一条边坍缩,则两个顶点合成了一个顶点
    然后,只剩2个顶点1条边了,再坍缩这条边则成了右图模样
    并且坍缩一条边,跟边的两个顶点相连的别的边也都会受到影响
    在这里插入图片描述
  • 新的点放哪?
    -直接取平均(原本所有相邻的几个点的平均),毫无疑问误差特别大 原本是E,现在A了,不妥!
    在这里插入图片描述

2.2.2 二次误差网格简化

  • 二次误差度量
    二次误差:即新点跟原本几个相邻面的距离的平方。
    找到一个位置,使得这个点到原本相邻几个面的距离平方最小
    在这里插入图片描述

  • 根据二次误差选择坍塌目标——贪心算法
    (1)计算每条边的二次误差,从小到大存起来
    (2)每次取二次误差最小的边,由于会影响到其他边,因此须动态更新其他边的二次误差
    (3)存放每条边的二次误差的数据结构采用 小顶堆 (每次取最小,并且动态更新)

  • 因为每一次都坍塌局部误差最小的边,希望得到一个轮廓变化不大但是面数降低很多的模型
    这就是贪心算法——希望通过对局部做最优解试图得到全局最优解

  • 二次误差网格简化结果
    在这里插入图片描述

  • 12
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在Matlab中,可以使用libigl或者cgal库中的函数来调用SDF(Signed Distance Function)函数。具体来说,可以使用cgal库中的sdf_values函数来计算SDF值。在编译gptoolbox时,可以使用cmake来生成sdf_values.mexw64文件。然后,在Matlab客户端中,可以通过以下命令调用该函数: [~, fsdf] = sdf_values(V1', F1', 2*pi/3, 8, 1); 这将计算出V1和F1表示的三维几何体的SDF值,并将结果存储在fsdf变量中。请注意,为了使用该函数,需要先启动Matlab进程。如果Matlab进程已经启动,则MLOpen函数不进行任何操作;如果关闭了Matlab进程,则可以使用MLOpen来重新启动Matlab。此外,sdf_values函数只能在宏子例程中使用,因此需要在MLAutoStart函数中使用"no"参数,手动使用Matlabinit来初始化ExcelLink和启动Matlab进程。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span> #### 引用[.reference_title] - *1* *2* [matlab编译并使用sdf_values](https://blog.csdn.net/zjf6738/article/details/127574835)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* *4* [matlab sdf文件怎么打开,sdf文件格式变成excel后如何还原](https://blog.csdn.net/weixin_36477752/article/details/115940276)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

宗浩多捞

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

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

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

打赏作者

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

抵扣说明:

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

余额充值