水的渲染一直是图形学需要解决的问题,本篇博客主要介绍用傅里叶变换算法实现的水反射,也是一种假反射效果,目的是优化效率。实现的效果如下图所示:

使用傅里叶系数来表示地形高度的假反射效果,在我们开发的游戏中使用水着色器,告诉读者我将如何利用引擎处理水的反射,我们自己开发水渲染效果,需要在优化方面考虑,计算每帧渲染时间。我们要处理渲染简化的低分辨率反射地图,因为我们还要渲染对于流动的水平面。算法的实现其实都是源于生活,大家如果平时出去旅游,经常会看到山丘的反射,近处反射的比较清晰,但在远处它只是一个黑色的斑点。试想一下,如果我们能够记录每个水点周围的水面上方的地形的角度,然后我可以在水着色器中使用这个反射光线,它应该是从“天空”过渡到“地形”的点。(Spherical harmonics)球面谐波是一种众所周知的技术,通常用于全局照明。非常简要地总结:每个顶点存储一组预先计算的系数,这允许我们重建击中对象的环境光。这些系数基本上存储从每个方向照射该点的光的映射图。反射/环境光通常是非常低的频率,因此这是这些系数如何包含这么“多”的信息原因。我决定用我引擎中的水尝试类似的技术,每个顶点保存一组小系数,描述地形在水上方围绕该点的每个方向上升的角度。这可以用一个四元系列的系数来描述 - 基本上是球面谐波的2d方程。当在顶点之间插值时,这些傅里叶系数就可以计算出来了,给读者展示一下效果图吧。

在水上的一个点周围的采样方向上的各种角度。

我们计算每个水顶点的系数,这涉及每个顶点的操作:

1、在点周围选择  k个均匀间隔的采样方向。k的值只影响计算,因此您可以将其设置为一定

的高以实现其仿真度,我目前使用13。

2、对于每个采样方向,执行光线跟踪。一次执行一个高度地图像素,测量水面上方的地形角度。你想要精确的反射取决于你离岸的距离,在本文的示例应用程序中,我目前使用5个像素。如果你的游戏涉及从低水平面的不同的水观察视角,你将需要使用更多(后面更多)。

3、现在我们有一个函数(每2π循环)表示点周围的地形高度。

4、为了获得表示该函数的傅里叶系数,我们需要对每个系数的表达式进行积分计算,确切的表达式可以在网上找到。我使用数值积分,分辨率为400(例如每个函数400个样本),使用的数字仅影响计算。

5、我计算前8个系数,这个数字直接影响效果的品质和性能。8对我的目的来说肯定够好了,当然我们会尽量降低。

我把我的系数作为16位浮点存储在我的顶点结构中(因此每个顶点占用16个字节)。

在水着色器中,我使用反射向量来确定我设置的角度,代码如下:

float3 reflectionRay = reflect(worldPosition - CameraPosition, normal);float angle = atan2(-reflectionRay.z, -reflectionRay.x) + PI;//这给出了0和2π之间的角度,然后我们能够使用它来查找地形高度。

本文实现的傅里叶评估函数看起来像这样(t是角度):

float EvaluateFourier(float t, float4 coefs1, float4 coefs2){  float4 sins;  float4 coses;  sincos(float4(t, 2 * t, 3 * t, 4 * t), sins, coses);  float value = coefs1.r; // a0  value += coefs1.g * coses.r; // a1  value += coefs1.b * sins.r; // b1  value += coefs1.a * coses.g; // a2  value += coefs2.r * sins.g; // b2  value += coefs2.g * coses.b; // a3  value += coefs2.b * sins.b; // b3  value += coefs2.a * coses.a; // a4  return value;}

方程给了我一个角度,这也是算法与编程结合的函数实现,然后我可以比较水面上的反射光线的角度,以确认我们是否应该绘制天空或反射的地形,目前我只是使用黑色的反射地形,效果似乎满足需求。如果我们想要更好的效果,还可以存储地形的颜色,除了高度。当然这将使所需的数据量增加四倍。

那它是如何工作的呢?您可以查看本文顶部的照片作为示例。这里有一个版本的顶点网格绘制。每个顶点存储16字节的数据在我当前的实现。

上图显示了我使用的顶点分辨率效果。

在水面上使用的法线贴图有助于实现这种假反射效果,实现的效果如下所示:

以上实现的效果在性能方面也给读者分析一下,这也有助于读者优化Shader的渲染效果:上面给读者实现了一种假反射,以避免渲染昂贵的反射贴图,因此它需要具有高性能。不幸的是,这需要大量的着色器指令在我当前的实现中评估。atan2约有20条指令。HLSL产生4个标量sincos指令,其实际上每个占用8个指令槽。总共,它为像素着色器添加了约64个指令槽。针对上述问题,我们的下一步任务是找到一种减少指令数量的方法。可以使用atan,然后是正弦和余弦,我可以通过做一些三角取代来减少这一点。或者我可以考虑使用e与虚数的幂的和来评估该系列。当然我们还可以减少系数的数量。另外,我将看到我是否可以存储每个系数在单个字节而不是16位浮点。最后总结一下,对于具有更多不同视图的游戏,这可能不是一个很好的选择。还有这个技术的一个问题是它只反射静态对象,地形,以及你决定在你的射线检测算法中包含的任何其他游戏元素。

小程序[渲染层网络层错误] failed to load image_游戏中水的渲染技术相关推荐

  1. 微信小程序渲染图片报错:[渲染层网络层错误] Failed to load local image resource

    微信小程序渲染图片报错解决:[渲染层网络层错误] Failed to load local image resource 背景 通过用户点击上传图片,通过res.tempFilePaths拿到用户上传 ...

  2. 有效解决微信小程序加载视频[渲染层网络层错误] Failed to load media

    问题1,小程序的视频一般都是放在网络上的,没谁能把视频放本地把,所以在小程序视频插件在加载视频的时候,就会出现如下错误:[渲染层网络层错误] Failed to load media wxml加载视频 ...

  3. 微信小程序 [渲染层网络层错误] failed to load font

    微信小程序报错: [渲染层网络层错误] Failed to load font http://at.alicdn.com/t/c/font...... 原因:我使用了阿里的iconfont字体图标,该 ...

  4. 解决图片渲染报错[渲染层网络层错误] Failed to load local image resourcethe server responded with a status of 500 (HTT

    错误:[渲染层网络层错误] Failed to load local image resource /profile/upload/2022/10/25/d36ed28d-5f31-4c2d-9905 ...

  5. [渲染层网络层错误] Failed to load local image resource /pages/mine/photo the server responded with a statu

    在做uniapp小程序时添加头像显示渲染层网络层错误,头像无法显示 ,代码如下 <view class="border-inner"><image src=&qu ...

  6. 小程序运行报错:[渲染层网络层错误] Failed to load local image /presource 的解决方案

    一般而言,出现这种问题是因为使用vue进行小程序端数据渲染的时候出现了问题. 会出现以下报错: 问题代码: 出现的形式: 我当时是在点击上传的时候每次都报这个错误,所以就一直在思考哪里出了问题.找过另 ...

  7. 小程序报错:[渲染层网络层错误] Failed to load local image resource /static/logo.png......

    问题来源 我在刚开发微信小程序时发现了一个问题,当我用hbuilder x运行小程序到微信开发者工具中时,出现了报错. 报错后并且也出不来图片,当时也去百度了许多用法,发现大多数都无法解决.我也很奇怪 ...

  8. 微信小程序报错图片加载失败渲染层网络层错误Failed to load image

    这个错误找了很久,原来是这样的: <u-image v-if="baseListItem.img.length>0" :src="baseListItem.i ...

  9. WeChat报错微信小程序图片加载失败渲染层网络层错误Failed to load image /pages/index/image/index.jpg:用绝对路径不用相对路径

最新文章

  1. 火狐浏览器允许ajax,解决火狐浏览器发送jquery的ajax请求无效的问题
  2. struts2配置详解
  3. C#的加密解密算法,包括Silverlight的MD5算法
  4. OpenGL_Qt学习笔记之_05(纹理映射)
  5. GraphPad Prism 9 如何一次处理多张图表?
  6. WSAAccept()函数使用解析
  7. 干,认识Audio框架还因此发现一个雷
  8. Ribbon中的负载均衡算法实现
  9. SpringBoot使用ELK日志收集
  10. [LeetCode]题解(python):068-Text Justification
  11. 卷积的感受野计算及特征图尺寸计算
  12. 基于Matlab的自适应低通滤波器设计,课程设计-低通滤波器设计(含matlab程序)
  13. MIMO 瑞利衰落信道 代码 包括天线相关矩阵
  14. AD15将PCB变为自己想要的形状
  15. 从有赞UI组件库看CSS BEM命名规范的好处
  16. pip list outdated pacakge and update
  17. 济南江苏商会成立 全国工商联·万祥军:商协社团厚德聚苏商
  18. SpringBoot整合lombok日志
  19. win8.1服务器系统安装教程,win8.1安装iis图文教程
  20. Win7 添加grub引导Linux最简单方法

热门文章

  1. ❤️六W字《计算机基础知识》(七)(建议收藏)❤️
  2. html中form标签的作用style,HTML5中meta常用标签属性说明
  3. win7系统服务器环境配置,win7系统服务器环境配置
  4. php打png图片水印颜色失真,ThinkPHP水印功能实现修复PNG透明水印并增加JPEG图片质量可调整...
  5. 仪表盘怎么调 铃木uy125摩托车_平时市区骑行,摩托车链条多久保养一次?
  6. C语言形参和实参的区别
  7. Android leak内存,GitHub - jin870132/memoryleakdemo: 安卓内存泄露几种常见形式及解决方案...
  8. 在布局空间标注的尺寸量不对_卫生间最佳布局尺寸,合理布局做到1毫米都不浪费!...
  9. centos6 yum快速安装mysql_centos6.10 yum安装mysql 5.6-Go语言中文社区
  10. 心电信号越界怎么回事_心电监护仪常见故障分析与排除