cover_image

周杰伦MV同款水体特效的背后技术

快手Y-tech团队 快手大模型
2022年07月22日 09:14

 


图片


快手Y-tech

最新技术干货分享


摘要


知名歌手周杰伦在7月6日发布了新专辑《最伟大的作品》,其MV中周杰伦穿越水面引起水面波动的效果涉及了流体力学、光学、计算机图形学等大量物理和计算机知识。快手Y-tech团队对该特效中的水体模拟渲染技术进行了探索。
图片
图1 周杰伦最新专辑《最伟大的作品》MV中穿越水面特效
实时水体交互模拟和渲染是游戏行业以及计算机图形学领域的重要研究方向。为向用户呈现真实的水面波动效果,我们需要对水体形态进行实时模拟,并根据折射反射光线对水体进行渲染。业界常用的水体模拟技术大致可分为波形叠加、波动公式近似、预渲染FlowMap等[1],此类技术的核心思路在于通过一系列数学计算模拟水波扩散,生成动态水体高度场。为在移动端有限算力基础上给用户带来尽可能真实的水体效果,快手Y-tech团队对以上水体模拟算法进行探索,开发实现了一套实时水体交互模拟方法并将其应用于快手app特效中(如图2)。

图片

图2 快手app上线“神奇水之门”特效



技术拆解



我们预期实现一款人物与水面交互产生波纹向外扩散的效果,并输出较为真实的水面渲染效果。为实现该目标,我们需要首先捕捉用户与水体的交互,在用户身体与水面的碰撞区域生成波纹;之后根据物理规律实时模拟水波在水面上的扩散现象;最后将模拟的水体绘制到屏幕上。整体流程如图3所示,接下来我们将分实时水体模拟、用户与水体交互和水体渲染这三个部分介绍我们水体效果的实现方案。
图片
图3 水体交互模拟渲染流程图



实时水体模拟



试想向水中投掷一枚石子,生成的圆形水波会由小到大逐渐向外扩散。将水体简化至一维时,水面可以看作一根有弹性的绳子,在绳子一处突然施加一段位移时,这段位移会由近至远逐渐扩散生成波形(如图4所示),使绳子抖动起来。同理,对一维水面施加扰动时,该扰动也会向外扩散产生水波。
图片

图4 一维波动扩散示意图[2]

为模拟水体表面波纹向外扩散的物理现象,一种常见的做法是使用波动公式对水波扩散进行拟合。其中,波动方程是一种二阶线性偏微分方程,主要用于描述自然界中对各种波动现象[3]。一维波动方程将水面近似为若干质量为  的质点,相邻质点间使用长度为  弹性系数为  的弹簧连接(如图5)。

图片
图5 一维波动方程推导[3]

使用  表示  处质点偏离平衡位置的距离(即水体在  处的水面高度)。根据胡克定律,相邻质点施加在中间质点上的弹簧作用力为:

  

根据牛顿第二定律,弹簧作用力对  处质点造成的加速度为:

  

从而得到一维波动方程:

  
游戏开发者大会(GDC08[4])上Müller等人将一维波动方程扩展到二维并应用于水体高度模拟。其将水面近似为平铺的二维质点网格(如图6),每个质点受其上下左右四个质点弹力影响。
图片
图6 二维水面波动方程模拟

每帧对水面每个质点进行遍历,根据其受周围四个质点影响计算弹力,从而更新该水面在质点处波动速度和高度:

  

  
  

考虑到水面每个质点的实时状态更新是互不干扰的,我们使用GPU对各质点状态进行并行计算以提高处理效率。我们使用一张纹理图存储水面每个质点的波动状态,并分颜色通道存储波动速度和水面高度。在每帧绘制时,将上一帧水体状态纹理存储到FrameBuffer中,并根据上一帧水体状态纹理调用着色器更新渲染当前帧水体状态。在着色器中,我们依照波动方程,根据当前像素与周围四个像素的水面高度差计算弹力,从而更新水面波动速度和高度。

// 水体状态着色器float height_avg = (getHeight(uv - dx) + getHeight(uv - dy) + getHeight(uv + dx) + getHeight(uv + dy)) * 0.25;velocity += (height_avg - height) * VELOCITY_MULTIPLIER;velocity *= DECAY_FACTOR;height += velocity;
使用如上方法生成的实时水体高度模拟结果如图7所示(亮度越亮表示水体高度越大),图中可以看出环形水波会向四周扩散产生波纹。
图片

图7 实时水体高度模拟结果



用户与水体交互



尽管通过上文方法我们可以得到动态水体的实时模拟,但如果不向水面加入初始扰动,我们只能得到一滩静止的死水。结合我们想要用户身体可以与水面进行交互的需求,于是我们使用人体分割技术抠出人像作为输入,并根据该分割人像估计人体与水面的碰撞区域即人体剖面。为了生成该剖面,我们首先将算法输出的人体分割mask与水面分界线求交,得到一条二值的交线(如图8红线)。为了使生成的水波形状尽可能接近人体在水面上的真实投影形状,我们将交线根据连通性划分为若干连贯的线段,并相应计算圆心半径构造为圆(如图8白色区域),从而作为用户身体探入水中的估计区域。
图片
图8 用户身体探入水中的估计区域
当用户将身体伸入水中时,身体会将水向周围挤开造成身体周围的水体高度升高(如图9)。为表示该水体高度变化,我们使用着色器将水体表面每一像素的高度变化渲染至一纹理图中。该着色器以用户身体探入水中的估计圆形区域作为输入,并输出圆心向外逐渐减弱的高亮区域,以表示用户身体周围的水体高度升高,且距离用户身体越远高度变化幅度越小。绘制水体高度变化的着色器经验公式可概括为:
  
图片
图9 用户身体伸入水中造成水体高度变化示意图
考虑到用户身体伸入水中保持不动时周围水体也会保持静止,只有用户伸入水中身体区域发生变化才会产生波纹(如图9绿色箭头表示身体变化产生的水体波动),故我们使用FrameBuffer存储每帧的水体高度变化,并使用当前帧和上一帧水体高度变化的差异来表示用户身体动作产生的水波。每帧将该水波累加至当前水体高度上作为用户对水体的实时交互:
  
将用户与水面交互生成的水波累加在水体高度上,并通过水体模拟更新水波扩散效果,得到的用户与水体实时交互模拟结果如图10所示。

图片

图10 用户与水体实时交互模拟结果



水体渲染



得到水体的实时高度图后,我们的最后一个步骤是根据高度纹理图将水体渲染到屏幕上。凹凸贴图(bump mapping)是计算机图形学的一项常用技术,其在每个像素渲染前预先叠加一个从高度图中采样的扰动,从而使渲染结果表面呈现凹凸感更加真实[5]

凹凸贴图技术包括高度图、法线图等。我们之前步骤得到的水体高度纹理图即可认为是一张高度图。为增强渲染真实感,凹凸贴图技术根据物体表面高度/法线,改变光线的传播方向从而营造物体表面的凹凸感。在进行水体渲染时,我们引入凹凸贴图技术,通过水体高度图来折射和反射光线,从而实现水体的渲染。

为计算水面波动对折射和反射光线的影响,我们需要计算水面法线,并根据入射光和法线方向计算折射和反射方向。考虑到水体高度梯度越大的地方,其法线偏移也越大,相应地对折射和反射光线角度的影响也就越大。因此我们简化为直接使用水面梯度计算折射和反射光线的偏移,首先计算水体高度图中每个像素与相邻像素间差异得到水体在该位置的梯度,之后根据梯度大小对折射和反射光线的采样uv进行偏移:

vec2 gradient = getGradient(tex_height, uv);vec4 color_refract = texture2D(tex_input, uv_refract + gradient);vec4 color_reflect = texture2D(tex_input, uv_reflect + gradient);

此外,为了模拟阳光照射水面产生的高光,我们使用Blinn-Phong光照模型对高光区域颜色进行了高亮处理。为简化光照计算,我们假设入射光从视线一侧斜射向水面,此时依据光照模型水面会在水波左侧产生高光,且该高光在水面坡度最大的区域最为强烈。因此为简化计算,我们依据水体表面梯度方向和大小为水波的左侧添加了高光:

vec4 color_specular = vec4(max(-gradient.x, 0.0));

最后将折射、反射光以及高光进行混合生成最终水体渲染颜色。根据菲涅尔原理,距离水面越近入射角越大折射光强度越大,距离水面越远则反射光强度越大。依据以上原则对折射、反射光进行混合并叠加高光颜色:

vec4 color = mix(color_refract, color_reflect, FRESNEL_FACTOR) + color_specular;

混合得到的水体渲染结果如图11所示,其左侧为水体渲染,右侧为水体高度图。
图片

图11 水体渲染结果



总结与展望



我们利用现有计算机图形学技术,在移动端有限算力基础上实现了一套水体模拟、交互、渲染流程。相较于基于流体力学的水体模拟,我们并没有使用过多复杂算法,而是在保障性能的基础上,优先选择了可以通过GPU并行计算的水面波动方程及交互方式。此外我们通过对各种光照渲染效果的精细打磨,混合得到了较为真实的水面质感。我们的水体模拟渲染技术也陆续应用上线了多款快手app特效(图12 从左到右:出水泳池、神奇水之门、踩水花、穿梭水之门)。

图片

图12 快手Y-tech团队水体模拟渲染技术上线多款特效

后续我们将继续在现有水体技术的基础上,进一步优化水体模拟算法使其更加贴近真实物理结果,同时开发更多新玩法将此类技术更大范围落地。



参考文献

[1] 游戏中的实时水体模拟技术 https://zhuanlan.zhihu.com/p/21573239

[2] File:1D-Wave.gif https://commons.wikimedia.org/wiki/File:1D-Wave.gif

[3] 波动方程 https://zh.wikipedia.org/wiki/波动方程

[4] Müller-Fischer M. Fast water simulation for games using height fields[C]//Proceedings of the Game Developer’s Conference. 2008: 24.

[5] 凹凸贴图 https://zh.m.wikipedia.org/zh-sg/凹凸贴图



你可能还想看

图片

风格化变老—遇见变老的你

动态化技术在快手特效业务上的应用

一甜涂鸦笔灵活性的实现



图片

    等你来 

Y-tech

快手Y-tech部门致力于通过计算机视觉、计算机图形学、深度学习、AR/VR/HCI等多领域的交叉,帮助每个人更好地表达、创作以及互动。Y-tech在北京、深圳、Palo Alto均有研发团队。如果你对我们做的事情感兴趣,欢迎联系并加入我们!

Y-tech长期招聘(全职或实习生):计算机视觉、计算机图形学、UE/Unity开发、技术美术、AI推理引擎、AI工程架构、美颜/特效技术、平台/工具开发、技术产品经理等方向的优秀人才。联系方式:ytechservice@kuaishou.com

Y-tech///

继续滑动看下一个
快手大模型
向上滑动看下一个