本笔记仅为个人的理解,如果有误欢迎指出。
Particle-Based Simulation of Material Aging
基于粒子模拟材料老化
本文通过模拟粒子的运动来模拟物体老化的流程,文章主要内容可以分为两个部分。一个是在程序上如何模拟粒子,一个是在程序上如何把粒子的影响应用到渲染上。
简单来说程序每帧计算粒子运动轨迹,在粒子与材质表面碰撞后修改物体的材质数据

一,模拟粒子
粒子在这篇文章中被称为gammatons,并且预设了三种粒子碰撞物体表面的行为,反弹、滑动、吸收。

粒子的运动和碰撞检测通过 CUDA 实现。粒子在代码中的结构定义如下:

可以看到一个粒子结构里面包含了粒子的标记ID(GamaPayLoad),粒子当前的位置,速度以及一些后续模拟老化的数据。
模拟粒子的流程代码如下:

这段代码主要做一件事,每执行一次就更新一次粒子的状态。或是更新位置,更新自身的材质数据,或是生成一个新的粒子。此时应该是在别的地方保存管理当前所有粒子供CUDA执行的时候读写粒子的数据。
迭代粒子位置直到粒子命中表面,或者达到未命中条件:
是否命中表面的代码如下:

当接近表面的时通过速度更新粒子状态
判断粒子丢失的代码如下:

命中表面后的材质传输是这篇文章的关键之一,代码如下:



代码上看就是将当前表面数据和粒子里面的材质数据进行混合,但有些不明白CUDA编程中是不是可以对物体材质数据进行读写的,因为在Unity渲染中贴图一般是在CPU中进行读写的,这里的CUDA流程应该是类似的。
在粒子和表面的材质传输有两种类型,一种是从粒子里的材质更新到物体表面(PS_SurfaceUpdate),一种是从物体表面更新到粒子里(GS_GammatonUpdate)。这两个流程关键代码都是transferRate,混合两边的材质数据。
以上便是粒子模拟的大概流程,思路其实很简单,就是用CUDA每帧更新物体表面和粒子的材质数据,模拟粒子本质上也只是迭代更新数据。
二,把老化影响应用到渲染上
这部分就更自由发挥了,文章中将老化操作抽象出一个接口,方便运行时选择具体的规则实现,这部分更接近编程的思想。下面是接口定义:

老化相关的操作都通过实现接口的着色器代码实现,具体操作文章并没有给相关代码示例 。
最后合成这些纹理渲染出最终结果。

相关公式:


可以看到文章里只是将每个材质加权计算而已。
最后是这篇文章整个流程的总结:

模拟粒子运动-》更新碰撞表面材质信息-》更新粒子里的材质信息-》根据老化规则调整材质-》合并物体各材质计算出最终颜色。
参考资料: