本文作者:木的树

关于小区域水波渲染以及焦散的技术原理,推荐下面两篇资源:
https://github.com/martinRenou/threejs-caustics
https://zhuanlan.zhihu.com/p/240797747

上面那篇知乎文章基本就是对英文原文的翻译。这里把相关文字直接拿过来

什么是焦散 caustics

焦散是光从表面(在我们的情况下是空气/水界面)折射和反射时出现的光的模式。

由于在水波上发生反射和折射,水起了动态放大镜的作用,形成了这些光的图案。


本文中主要讨论由光的折射引起的焦散,主要是水下发生的事情。

为了能够得到稳定的 60 帧,使用 GLSL 编写的 shaders 在 GPU 上计算。

为了计算焦散,我们需要:

• 计算水面的折射光线(GLSL 中有内置函数)

• 求交算法,计算光线照射到环境的位置

• 通过检查光线会聚的位置来计算焦散强度


我发现图形学很多理论知识相当复杂,各种求导求偏导,到最后能够得到一个非常简单的公式,往往只是加减乘除。

还是一边结合代码一边结合原理来讲比较明白

https://github.com/martinRenou/threejs-caustics/blob/master/index.js

从上上下看,这里先设置了从光源处看环境的相机,这里用的是正视相机。

image.png


这个场景中有几个物体:水的三角网(waterGeometry)、水地面图形(floorGeometry)、鲨鱼(shark)、两块石头(rock1、rock2)、水草植物(plant)、天空盒(skybox)

现在要制作焦散,就要回到上面说到的理论了,首先要计算出折射光线与物体的交点。如果按照纯物理方式来计算,这个方法计算量非常大。所以想要一种简单有效,虽然不符合物理规律但是能够快速模拟的效果。想想阴影不就是利用阴影贴图的原理,从光源位置看场景中的物体,先得到一张深度贴图,然后在实际渲染时,比较每个像素的深度在光源相机坐标系下的深度来判定是否在阴影中。

这里其实利用了类似的思路,先渲染一张环境纹理。在纹理中渲染水下环境,然后使用该纹理来计算光线与环境之间的交点。除了渲染片段深度之外,还渲染了环境图中的片段位置,RGB 信道存储 XYZ 位置,alpha 信道存储深度:


先对照代码来看环境部分,这里是把上面说的物体都加入到了环境中去:

这里的顺序也注意一下,environmentMap没有添加到scene中,他是自己单独渲染到fbo中。

environment顺序在前,water顺序在后。

设置完初始环境之后,给水面加几个小的震动模拟水面波动效果


接着进入主渲染逻辑


先看这部分,挺麻烦的。


一、根据drop生成波动纹理,将波动纹理传递给water作为渲染用。

drop方面涉及的知识点看另一篇文章,这里不赘述


文档:水波渲染demo.note

链接:http://note.youdao.com/noteshare?id=1697c823a2e1270dc6c5bd092252c2c4&sub=1641A27DB586489B8A5A97FEFB3C167A

二、生成上文所说的环境纹理,RGB 信道存储 XYZ 位置,alpha 信道存储深度:

需要注意这里存贮的坐标是世界坐标系,所以这里的纹理也应该是浮点纹理。

顶点着色器:


片元着色器:

image.png

现在将水下环境渲染到了纹理中,然后使用该纹理来计算光线与环境之间的交点

三、渲染得到纹理之后将水波的waterSimulation纹理和环境纹理传递给焦散渲染成焦散纹理


上文说到要计算焦散,先要计算光线与环境的交点。这里的方式如下:

  1. 计算光纤与水面的交点(如果是逐顶点计算,那么每个方格顶点就是交点;如果是逐像素计算需要计算每个像素对应的水面点位置,其实也不难)

  2. 计算光线在水内部的折射光线(知道光线向量、水面法线向量,glsl有内置函数来计算)

  3. 从当前位置沿折射射线方向移动环境图纹理的一个像素(这里是不太好理解,射线是三维向量,纹理是二维图片,这里利用了一种方式将射线方向映射到二维纹理中)

  4. 将存储在当前环境纹理像素中的环境深度与当前深度进行比较。如果环境深度大于当前深度,则意味着我们需要走得更远,因此我们再次运行步骤 3。如果环境深度小于当前深度,则意味着光线在您从中读取的位置击中了环境

  5. 找到交点之后利用这篇文章中的技术来计算焦散强度,生成焦散纹理(https://medium.com/@evanwallace/rendering-realtime-caustics-in-webgl-2a99a29a0b2c),这个纹理包含3D空间中每个点焦散光照强度信息。

  6. 进行最后的环境渲染时,从焦散纹理中读取光照强度信息来进行渲染

下面进行焦散渲染的着色器处理解析

顶点着色器:


片元着色器:


这里片元着色器的那两个面积比率,就是对应开头图片中光线的汇合和散开现象,可以看到当newArea的面积越小强度越大,面积越大强度越低,这也比较符合认知。


四、根据焦散强度渲染水下环境

下面将焦散纹理传递给environment


environment中有几个物体:水的三角网(waterGeometry)、水地面图形(floorGeometry)、鲨鱼(shark)、两块石头(rock1、rock2)、水草植物(plant)、天空盒(skybox)

下面部分先将水波设置为不可见,然后渲染整体场景


来看下水下environment的顶点着色器和片元着色器

这里的positon是environment中的几个模型的顶点坐标

顶点着色器:


片元着色器:

这里主要是利用焦散强度结合光照强度对环境中的物体模型的颜色进行着色


五、渲染水波

  1. 将environment环境渲染成纹理交给water(注意这里不是environmentMap)

  2. 将水波设置为可见来渲染水波

    水波的光照模拟也是难得一逼,这里这个还是简单的。只适用于小水塘、海波渲染还不涉及。。。还有海波荡漾出来的白色泡沫

顶点着色器:

片元着色器:

这里通过水面看到水底模型扭曲,感觉是因为波动水的法向量在变动,对应的折射光线也在变,所以折射取得的水底纹理的像素颜色也不一样。


其中还有这种油膜的效果应该是上面三个不同折射系数的rgb影响的吧


❤️爱心三连击1.看到这里了就点个在看支持下吧,你的「点赞,在看」是我创作的动力。
2.关注公众号程序员成长指北,回复「1」加入Node进阶交流群!「在这里有好多 Node 开发者,会讨论 Node 知识,互相学习」!
3.也可添加微信【ikoala520】,一起成长。“在看转发”是最大的支持

WebGL 水波及焦散(刻蚀)的渲染总结相关推荐

  1. ue4光追降噪_【魔改UE4】后记_焦散效果总结

    我了解的的焦散共有三种做法: 贴图动画 实时焦散:Normal 挤出网格[我感觉非常漂亮,可以低成本模拟rtx效果] 实时焦散:rtx,主动点亮场景 以UE4 为例. 一.贴图动画 UE4 有一个实例 ...

  2. Caustics焦散

    Caustics焦散 转自百度百科 焦 散是一种很容易识别的间接照明效果.焦散的产生原理其实很简单:间接照明光线(即光子)从光源发射出来后,先经过一次(或多次) Specular 表面反.折射作用,再 ...

  3. Maya Mental Ray焦散效果

    在灯光开启焦散效果 在渲染器中开启焦散效果 焦散效果

  4. webgl 基础渲染demo_WebGL + ThreeJS 实现实时水下焦散 Part 1

    知乎视频​www.zhihu.com 采用 WebGL 和 ThreeJS 运行实时焦散运算,需要一点相关基础.本文主要介绍焦散的原理以及计算方法 原作者 https://github.com/mar ...

  5. GPU_GEMS_自然态_渲染水焦散

    文章目录 前言 一.简介 二.数学物理依据 三.理论方法 五.实际方法 1.OPENGL 2.HLSL 总结 前言 第二篇,我看了下比上一篇短一点 b( ̄▽ ̄)d 直接正题罢. 一.简介 焦散是指当光 ...

  6. 3dmax:3dmax三维VR渲染设置(VR发光贴图、VR灯光缓存、V-Ray焦散,渲染图中出现黑斑点的原因、插值类型)之详细攻略

    3dmax:3dmax三维VR渲染设置(VR发光贴图.VR灯光缓存.V-Ray焦散,渲染图中出现黑斑点的原因.插值类型)之详细攻略 目录 [VR发光贴图] 1.渲染图中出现黑斑点.杂点的几个原因: 1 ...

  7. UE4 Material 101学习笔记——23-29 水涟漪/水深/折射反射/Gerstner海浪/波光焦散/泡沫/FlowMap

    UE4 Material 101学习笔记--23-29 水涟漪/水深/折射反射/Gerstner海浪/波光焦散/泡沫/FlowMap Lec23 水的表面涟漪 Water Ripples Shader ...

  8. Maya mental ray 焦散

    什么是焦散? 焦散是三维软件中的一个名词,它主要在后期渲染的时候,才会被提及.它的主要作用就是产生水波纹的光影效果,为了达到真实的效果,它可以计算很精致.准确的光影.但是好的效果,都是要付出渲染时间的 ...

  9. arnold 调用 mantra的光子 做GI全局光和caustic焦散

    arnold 调用 mantra的光子 做GI全局光和caustic焦散 关键字:arnold;mantra;photon;GI;caustic;光子;全局光;焦散;global illuminati ...

最新文章

  1. 李开复:AI行业正在回归商业本质,技术公司要有服务心态落地为王
  2. mac 安装 nginx
  3. Sublime Text 4首个稳定版发布:全新UI、多选项卡、支持GPU渲染
  4. 基于FPGA的HDB3数字编码器设计
  5. 选择海外数据中心是否等级越高越好
  6. Redis命令:SETNX key value(SET if Not eXists)
  7. 设置新生代与老年代比例关系
  8. linux系统普通用户ssh不能登陆,关于CentOS普通用户无法登录SSH问题
  9. js二维数组传递java,ActiveX获取JavaScript传递的二维数组
  10. 网页中嵌入JavaScript+事件触发程序
  11. python多线程教程_Python多线程编程教程【2小时学会】
  12. Mysql学习总结(54)——MySQL 集群常用的几种高可用架构方案
  13. 为什么黑客都用python-黑客编程为什么首选Python语言?这里告诉你答案!
  14. Visual C#中用WMI编写网络应用程序
  15. 交通灯倒计时c语言程序,交通灯C语言程序,T89S52单片机控制,倒计时,红黄绿灯.doc...
  16. php 三菱plc,三菱plc编程
  17. RouterOS PPTP和L2TP的配置
  18. 以心换心,将心比心----项目经理要学会站在客户的角度上看问题
  19. CleanMyMac4.11.1中文完整语言版本
  20. DNS劫持原理,DNS劫持如何解决?

热门文章

  1. 随笔(2015.11)
  2. 线程池踩坑记 --load飙高的原因
  3. 玩转Linux之dd命令操作详解
  4. ms721调试总结及光电传感器板测试总结
  5. 手机微信语音批量转文字 使用百度语音识别
  6. Google Adsense api 推荐介绍 ~!没有网站照样赚钱!
  7. Python机器学习个人总结
  8. 如何高效访问OneDrive个人存储空间?三种方法
  9. ArcGIS空间插值方法反距离权重法(IDW)的工作原理
  10. pppoe服务器账号和密码是什么,路由器的PPPOE拨号宽带账号和密码是多少?