游戏中水的渲染技术系列一( 二 )


我把我的系数作为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 = http://www.kingceram.com/post/coefs1.r; // a0value += coefs1.g * coses.r; // a1value += coefs1.b * sins.r; // b1value += coefs1.a * coses.g; // a2value += coefs2.r * sins.g; // b2value += coefs2.g * coses.b; // a3value += coefs2.b * sins.b; // b3value += coefs2.a * coses.a; // a4return value;}
方程给了我一个角度 , 这也是算法与编程结合的函数实现 , 然后我可以比较水面上的反射光线的角度 , 以确认我们是否应该绘制天空或反射的地形 , 
目前我只是使用黑色的反射地形 , 效果似乎满足需求 。如果我们想要更好的效果 , 还可以存储地形的颜色 , 除了高度 。当然这将使所需的数据量增加
四倍 。

游戏中水的渲染技术系列一

文章插图
那它是如何工作的呢?
您可以查看本文顶部的照片作为示例 。这里有一个版本的顶点网格绘制 。每个顶点存储16字节的数据在我当前的实现 。
游戏中水的渲染技术系列一

文章插图
上图显示了我使用的顶点分辨率效果 。
在水面上使用的法线贴图有助于实现这种假反射效果 , 实现的效果如下所示:
游戏中水的渲染技术系列一

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