shader 反射 水面_【博物纳新】水面涟漪反射效果开源库测评
【博物纳新】是UWA重磅推出的全新栏目,旨在为开发者推荐新颖、易用、有趣的开源项目,帮助大家在项目研发之余发现世界上的热门项目、前沿技术或者令人惊叹的视觉效果,并探索将其应用到自己项目的可行性。很多时候,我们并不知道自己想要什么,直到某一天我们遇到了它。
大千世界,无奇不有!更多精彩内容尽在开源库:lab.uwa4d.com
导读
WaveProvider是一个组件和着色器库,可以使用Unity轻松表达波形,利用该组件可以实现受物理影响的水面动态涟漪效果,
效果展示
实现原理
1. 添加用于绘制倒影图像的反射相机
考虑到主摄像机的位置可能会动态地改变,所以反射摄像机也需要使用脚本控制使其动态移动到合适位置(与主相机相对水面对称)以绘制正确的反射图像。
2. 根据投影面编写一个水面投影反射的着色器
投影时,需要统一投影侧的空间并确定投影面(项目中的这个投影面就是水面)。使用反射相机的变换矩阵变换,并渲染每个对象。当使用主摄像机在水面上绘制对象时,使用反射相机的变换矩阵来转换对象顶点。
下面的代码段是水面投影反射着色器的一部分:
1 struct v2f
2 {
3 float2 uv : TEXCOORD0;
4 float4 vertex : SV_POSITION;
5 float4 ref : TEXCOORD1;
6 };
7
8 sampler2D _MainTex;
9 float4 _MainTex_ST;
10 sampler2D _RefTex; //反射绘制的纹理
11 float4x4 _RefVP; //反向VP矩阵输入
12 float4x4 _RefW; //反射对象的局部变换矩阵
13
14 v2f vert (appdata v)
15 {
16 v2f o;
17 o.vertex = UnityObjectToClipPos(v.vertex);
18 o.ref = mul(_RefVP, mul(_RefW, v.vertex));
19 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
20 return o;
21 }
22
23 fixed4 frag (v2f i) : SV_Target
24 {
25 return tex2D(_RefTex, i.ref.xy / i.ref.w * 0.5 + 0.5);
26 }
其中_ RefTex是反射绘制的纹理,_ RefVP是反向VP矩阵输入,_RefW是反射对象的局部变换矩阵。顶点着色器使用_RefW将顶点转换为世界坐标,再通过_RefVP将世界坐标转换为反射相机的投影空间,片元着色器将其转换为普通坐标转换+纹理坐标,并用于主摄像机渲染。
然后,我们得到了如下效果:
这样,即使相机移动或反射物体移动,旋转或缩放,也可以在没有违和感的情况下显示正确的投影图像。
3. 在投影着色器的基础上编写一个根据法线扭曲的着色器
接下来,我们添加扭曲投影的代码,这里通过引用法线贴图的方式实现。
1float2 offset = bump * _BumpAmt * _RefTex_TexelSize.xy;
2i.ref.xy = offset * i.ref.z + i.ref.xy
其中_BumpAmt是可调节的影响系数,_BumpAmt越大,则涟漪越强烈,但同时会影响到水面的反射效果,因此建议将参数控制在300以下,并按自己的需求进行调整。
_BumpAmt参数对效果的影响示意图
4. 根据脚的运动输入波动方程
利用波动方程,使波浪的高度可以作为纹理。(此处不对波动方程进行详细介绍)
左边区域是波纹输入纹理的调试界面,接下来,将存储在此纹理中的波的高度(被视为高度图)解析为法线并扭曲反射纹理,实际上,当从高度图计算法线贴图时,也可以直接求解偏导数,从而输出正常值作为着色器的凹凸。感兴趣的朋友可以参考该作者的另一篇相关文章:http://esprog.hatenablog.com/entry/2016/10/24/183733
同时根据角色脚的运动输入更改波动方程
作者在人物的脚点上附上了Collider组件和一个改造了InkPainter的CollisionPainter的脚本,可以理解为在人物的脚点上各加了一个笔刷,具体实现可以参考InkPainter插件里的Brush类。
PS:InkPainter插件链接附在文末,喜欢Splatoon的,或者想实现类似Splatoon效果的朋友,该插件可以提供不错的参考价值。
性能测试
使用UWA GOT Online对这个效果进行了性能测试。为了更真实地反映这个项目的渲染开销,我们使用了非多线程渲染的版本。
同时准备了4个版本的场景作比较:
版本A:即原版,3个角色加水面涟漪反射效果;
版本B:3个角色,去除涟漪反射效果,同时将地板Shader更换成简单的Diffuse;
版本C:9个角色加水面涟漪反射效果;
版本D:9个角色,去除涟漪反射效果,同时将地板Shader更换成简单的Diffuse。
测试4个版本的场景后,通过UWA GOT Online解析数据,最终得到对比数据如下:
我们观察到,有无涟漪反射的效果,对场景的帧率有一定的影响,但随着角色数量的上升,场景帧率发生了明显的下降,通过逻辑代码的分析我们发现开销主要集中在渲染模块上,接下来我们具体看一下Camera.Render的耗时均值对比:
下面我们以版本A为例具体看一下渲染耗时曲线:
可以观察到渲染耗时在8ms左右波动,其中不透明渲染在5ms左右,半透明渲染在1ms左右。然后再来对比一下四个版本的不透明和半透明渲染的平均耗时:
这里我们可以看到,开启效果后,不透明渲染和半透明渲染开销均有上升,且影响较大,开启效果会额外增加40%左右的渲染开销。
考虑到项目中的角色材质比较复杂,会对测试结果造成一定影响,对红米Note3这类低性能机型而言,能跑到这个数据,该效果的性能还是可以接受的,但建议开发者在使用时控制反射场景的复杂度,同时可以考虑优化水波反射的Shader以达到很好的优化效果。
注意事项
1)文章前两图素材来源于《LOST SPHEAR》,图三来自推主オノッチ利用该组件制作出来的效果,twitter链接:https://twitter.com/onotchi_/status/958188421045866496(仅做效果参考,并非项目内容);
2)该项目需要搭配InkPainter(nv1.2.1或更高版本)使用。
该项目来自UWA开源库,您可以下载、收藏或评论Waveform Provider项目。开源库传送门:https://lab.uwa4d.com/
shader 反射 水面_【博物纳新】水面涟漪反射效果开源库测评相关推荐
- 【博物纳新】Isaura—光环特效开源库评测
[博物纳新]是UWA重磅推出的全新栏目,旨在为开发者推荐新颖.易用.有趣的开源项目,帮助大家在项目研发之余发现世界上的热门项目.前沿技术或者令人惊叹的视觉效果,并探索将其应用到自己项目的可行性.很多时 ...
- 【博物纳新】Unity海洋场景构建
[博物纳新]是UWA重磅推出的全新栏目,旨在为开发者推荐新颖.易用.有趣的开源项目,帮助大家在项目研发之余发现世界上的热门项目.前沿技术或者令人惊叹的视觉效果,并探索将其应用到自己项目的可行性.很多时 ...
- android view设置按钮颜色_建议收藏!最全 Android 常用开源库总结!
作者 | i小灰地址 | https://www.jianshu.com/p/3fde87405411 前言 收集了一些比较常见的开源库,特此记录(已收录350+).另外,本文将持续更新,大家有关 ...
- java 反射机制_详解Java中的反射机制的优缺点
一.什么是反射? 对于程序员来说,应该很少需要直接使用反射工具:之所以在语言中提供它们,是为了支持其他Java特性,比如对象序列化.Java Beans以及RMI.还有就是在很多框架中,也是应用到了反 ...
- 反射 字段_一次简单的Go反射实战经历分享
反射是所有面向对象语言的一个重点,它为开发者提供了灵活的操作可能.利用反射可以获取不同对象/结构体的信息,制定不同的策略,实现复杂的操作. go与java的反射操作思维大有不同,学习的时候也遇到过一些 ...
- java反射构造函数_【译】3. Java反射——构造函数
==================================================================================================== ...
- shader 反射 水面_【Unity Shader】模拟水面包含折射与反射与波浪动画
最近研究了一下Unity官方的BoatAttack案例,他们模拟的海浪效果很厉害,用的是Gerstner波来模拟水面起伏和波峰的白浪还有浮力系统,还做加入了焦散效果(Caustics)和平面反射(Pl ...
- cesium结合shader系列之有倒影的流动水面
有倒影的流动水面 若仅想实现动态水面效果,利用cesium的相关接口配置material的uniforms就可以实现了.但这种方式调配出的水面相对失真,无法实现现实水面具反射周围地物效果.为了更逼真的 ...
- 安卓移动应用开发实例_移动应用开发协会纳新 ||掌握信息,赢得未来
移动应用开发协会纳新 ||掌握信息,赢得未来 寻梦,是每个人心中的那一片橄榄叶?, 用有限的力量,放出无限的光芒✨. 有人的地方就会有生活, 有生活的地方就会有我们, 我们真诚期待你们的加入! Com ...
最新文章
- 《强化学习周刊》第8期:强化学习应用之自然语言处理
- pytorch 加载模型:
- Codeforces 610C:Harmony Analysis(构造)
- 查找删除Code First Entity Framework基本与最佳添加(add/create),删除(delete/remove),修改(update/modify)操作...
- 解决 kindle 书籍字体颜色偏淡问题的方法
- 8-Python3从入门到实战—基础之数据类型(集合-Sets)
- 深入认识Tigase XMPP Server(上)
- 小熊派折叠开发板Docker编译烧录安装HAP
- 【CodeForces】947 D. Picking Strings
- win10开移动热点让手机使用上网
- java系统属性_java 系统属性
- 【树莓派之旅】第01期:一根网线搞定树莓派可视化界面
- POS系统example.launch 的位置_关于信用卡用户使用个人POS机的建议!
- java小红球下载_小红球闯关下载_小红球闯关合集版下载-游戏下载
- c语言c2056错误,C语言中文网_c.biancheng.net - 爱站网站排行榜
- 基础sql语句大全(详细解析,注意事项)
- 中国矿业大学教务系统服务器,中国矿业大学教务系统入口:http://jwb.cumt.edu.cn/...
- C语言数据类型及运算符
- [c++primer][14]重载操作符与转换
- C语言实现二进制与十进制的互转(带小数)
热门文章
- windows7注册表项Userinit键值删除导致不能登录解决的简单办法
- 五月联考的总(lao)结(sao)
- 逗号运算符的简单分析和用法
- 解决SecureCRT(linux远程访问工具)中中文乱码问题
- Postgresql设置远程访问(需要设置防火墙或者关闭防火墙)
- 前端使用node存入数据库emoji表情报错
- 智能路由器安全特性分析
- 解决windows10下无法安装.net framework 3.5,错误代码0x8024401C
- 【组成原理-数据】浮点数的编码与运算
- validate验证长度 vue_vue+VeeValidate 校验范围(部分校验,全部校验)