布料渲染总结
前言
本来是想打算实现GAMES101
课程大作业中的布料渲染那种效果的,不知不觉就变成了随风飘动的窗帘布了😅;所以就是随便找了个BRDF
(Disney BRDF
)来实现,而非那篇参考论文[1]中提供的BRDF
,所以这里偷了个懒,虽然看起来有布料那么回事,但是高光部分显然不太合理;
demo
地址:https://xiexuefeng.cc/app/we/demo/cloth-render/
弹簧质点系统
构建质点网格
按照一般布料特点,基本上就是以一个类似围棋棋盘的结构构造一个矩形的网格,然后加上对角线连接,如:
我这里对角线只做了一个方向上的连接,其实也可以加上另一个方向上的连接,如:
其实增加对角线的连接就是增强质点之间力的约束,这里的每个连接就是一个弹簧;
约束条件
要让布料网格运动更接近现实,就需要对质点及弹簧之间的相互作用进行一个约束,大致可以分为以下两个方面:
- 力的约束:在弹簧质点系统里面指的就是各种弹簧的构造,在网格中来说具体就是:
- 结构弹簧:即网格中相邻两点之间的连接,模拟拉力或压力;
- 剪切弹簧:即网格中对角线之间的连接,模拟剪力;
- 弯曲弹簧:即网格中间隔一点之间的连接,模拟弯矩;
- 距离的约束:由于现实中的弹簧不可能无限拉伸或无限压缩,因此需要给定一个最长长度和最短长度,当出现要超过这个合理范围的长度时,此时弹簧表现为刚体,长度处于临界状态;其实也可以用距离约束来模拟布料的弹性,弹性大自然可以拉得更长,反之弹性小自然就拉得更短;
碰撞约束:按理说为了预防布料之间的质点进行穿模,应该要加上碰撞检测进行约束……
质点位置计算
已知质点质量,也能根据弹簧之间的距离来计算各自的弹簧力(胡克定律),那么根据牛顿第二定律就可以计算出质点的加速度;
因此,这里可以用Verlet
积分来计算质点位置;因为Verlet
积分只需要用到当前时刻()的位置、前一时刻()的位置加上当前时刻的加速度即可计算出下一时刻()的位置了,计算简单且精度也较高;
不过实际上可以加上一个阻尼系数()来模拟弹簧之间的摩擦力:
至于Verlet
积分计算的推导推荐看看这篇文章,竟然意外的只需要用到泰勒展开😂;
风力场
为了营造一种随风而动的效果,就需要模拟风力作用;这时候就可以构造一个力场函数,直接根据位置()和当前时间()来获取当前质点位置所受到的力:
实际上就是分别给定三个方向上的函数,计算各自分量,最后得到一个力;
示例
需要注意的地方
- 这里的系数实际上取决于每个质点的质量及弹簧力之间的相对关系;
- 构造力场得到力应该与其原本的力(弹簧力和重力等)处于同一数量级,不然很容易会让弹簧质点系统的运动处于不收敛状态;
BRDF
这个demo
的实现基本上采用了Disney BRDF
的配置[2]:
虽说按照这个BRDF
基本上能够模拟出一种类似丝绸等光滑布料的材质特点,但是还是没法模拟出更多粗糙程度的布料材质;
后话
基于弹簧质点系统做的仿真动画还是挺好玩的,虽然还是挺基础的应用,不过也能收获很多;主要是偷了个懒,没去实现基于微表面模型的BRDF
实现,渲染效果上就不尽人意了;
相关链接
- 布料模拟之基本原理 - 知乎
- 网格弹簧质点系统模拟(Spring-Mass System by Euler Integration) - 算法小丑 - 博客园
- BRDF理论及shader实现(下)_子宽的专栏-CSDN博客:强烈推荐看看,有常用的
PBR
的BRDF
实现及其对比,函数和各种参数作用讲解的比较详细 - 请通俗的解释一下什么是弯矩,带上个计算例子更好? - 莱维的回答 - 知乎