我的github

作者:Huw Bowles 单位:Studio Gobo

Introduction(简介):Studio Gobo is a small team of talented developers based in Brighton / UK

The Crew(成员):Ben Andrews, Paul Ayliffe, Anastasios Brakis, Jim Callin, Clement Dagneau Kevin Hayes, Will Myles, Olliver Reid-Smith, Phil Williams, Tom Williams.[Some of the amazing people from Studio Gobo that contributed to this work, across code, art and design. There are additional people that made contributions to this work but can’t be named for legal reasons.]

Project(项目):1)Mystery Project X(神秘项目代号X)   2)Built a self contained part of the game(构建了游戏的独立部分)   3)Includes a virtual ocean(包含一个虚拟海洋)[由于法律原因,我们不被允许透露我们参与的项目的名称,尽管该项目(以及我们参与其中的情况)已经宣布。]

Screenshots(效果图):

这就是它看起来的样子。此视频应以每秒30帧的速度流畅运行。

任务和挑战:Project timeline was tight so we aimed to develop one solution that worked on all shipping platforms. The GPU on the Wii is fixed function so we aimed to do a CPU solution(项目时间表很紧,所以我们的目标是开发一个适用于所有运输平台的解决方案。Wii上的GPU是固定功能的,所以我们的目标是做一个CPU解决方案)

目标&要求:

  • Seamless experience across land and sea(跨越陆地和海洋的无缝体验)
  • Ocean is both a play space and a back drop(海洋既是一个游戏空间,也是一个背景板)
  • Various art and design goals(各种各样的艺术设计表达方式)
  • 8 month development(8个月的开发周期)
  • Shipping platforms: Xbox 360, PS3, Wii(游戏平台:Xbox360,PS3,Wii)

概况:To render an ocean you need three things. One is some kind of description of the shape. Secondly you need to sample the shape as a 3D mesh and submit it to the GPU. Finally, shaders tell the GPU how to create the appearance of the ocean surface.(要渲染海洋,你需要三样东西。一种是对形状的某种描述。其次,您需要将形状采样为3D网格,并将其提交给GPU。最后,着色器告诉GPU如何创建海洋表面的外观。)

 生成形状(点)->生成网格(面)->着色(图片)

难点:Ocean surface is complex and detailed and at the same time vast. This makes it challenging to describe (compactly).(海面既复杂又细致,同时又广阔。这使得描述(紧凑)变得很有挑战性。)

第一章:Shape(形状)

Doing a full fluid sim is still out of reach for games. Compress the shape by dividing it into two levels. Global shape is the base ocean shape that is repeated over the entire ocean surface. Local shape adds some localised deviation to the shape to meet art and design requirements. Also normal maps are used to hallucinate high freq waves on the surface. We’ll look at these later.

由于计算机性能的限制,做一个完全流体模拟的游戏仍然遥不可及。通过将形状分为两个级别来压缩形状。全局形状是在整个海洋表面上重复的基本海洋形状。局部形状为形状添加了一些局部偏差,以满足艺术和设计要求。法线贴图也被用来在表面产生高频波的幻觉。我们稍后再看这些。

-Global shape(全局形状)
    -Fourier Synthesis傅立叶合成
    -Procedural representations程序化表达
-Local shape(局部形状)
    -Wave height modifiers波浪高度修改器
    -Wave particles波浪粒子

1.1 Shape / Fourier Synthesis(形状-傅里叶合成器)

Fourier synthesis generates something like this – a patch of our ocean surface.

 Can limit the frequencies so we get a tileable, loopable patch.(可以限制频率,这样我们就可以得到一个可平铺、可循环的面片。)

  • Several models for the frequency content of ocean waves known(已知海浪频率含量的几种模型)
  • Can use Fourier Transform to synthesise surface with desired spectrum(可以使用傅立叶变换合成具有所需光谱的表面)
  • See the work from [Tessendorf2001](参见[Tessendorf2001]中的工作)

Some implementation details:Fixed point values – 8bit seemed to be enough precision to store the displacement map. We did the interpolation of data also using fixed point math and then converted to floats afterwards.

一些实现细节。定点值–8位似乎足够精确,可以存储置换贴图。我们还使用定点数学对数据进行插值,然后转换为浮点。

We did all this on the CPU.I guess, if this is done by sampling textures in the vertex shader, mipmapping will automatically filter out high frequencies (if mip maps are enabled?)?

我们都是在CPU上完成的。我想,如果这是通过在顶点着色器中采样纹理完成的,mipmapping将自动过滤掉高频(如果mip贴图已启用?)?

  • We used this for Xbox 360 and PS3(我们在Xbox 360和PS3上使用了这个)
  • Precompute FFT offline into set of displacement maps [Torres2012](将FFT离线预计算为一组位移图[Torres2012])
  • 64 frames looping animation, 64x64 spatial resolution, 8bit fixed point values(64帧循环动画,64x64空间分辨率,8位定点值)
  • 1.5mb for positions and normals(位置和法线为1.5mb)

Memory is precious on Wii. We decided to look at procedural representations that do not rely on prebaked data.内存在Wii上是珍贵的。我们决定研究过程表示方法,它不依赖预烘焙数据。

  -Too much memory for Wii (64mb RAM)(对Wii来说需要太多内存了 64MB的RAM)
  -Look at procedural representations(查找过程表示法)
   -Sum a set of waves(总结了一系列的波)

1.2 Shape/Trochoids(全局形状-Trochoids波)

Standard shape for deep ocean waves (waves not influenced by ocean floor).

深海波浪(不受海底影响的波浪)的标准形状。

Trochoids are nice – peaks/crests are important for visual interest.

Trochoids很漂亮–峰值/波峰对于视觉兴趣很重要。

More info: http://whatonearth.olehnielsen.dk/oceanwaves.asp

 更多信息:http://whatonearth.olehnielsen.dk/oceanwaves.asp

Trochoid is a parametric equation. The parameter can’t be solved for a particular point in space algebraically. While it can be solved iteratively using fixed point iteration, we decided to approximate the trochoid shape with a piecewise polynomial.

 Trochoid是一个参数方程。对于空间中的某一点,该参数不能用代数方法求解。虽然它可以用不动点迭代法迭代求解,但我们决定用一个分段多项式来逼近三弦形状。

  • Cannot sample wave height directly (see appendix)不能直接取样波高(见附录)
  • Approximate trochoids instead with polynomial equation用多项式方程代替近似三次曲线

1.3 Shape / Parabolic waves(全局形状-Parabolic波)

This is the shape we settled on.

这是我们确定的形状。

Its constructed by adding three parabolas

它由三条抛物线构成

1.4 Shape / Wave Height Mods(局部形状-波高的修改)

Simple solution to control wave heights.控制波高的简单解决方案。

A wave height mod has 2 radii. Influence blended from 0 to 1 between outer and inner edge.波高模型有2个半径。影响在外边缘和内边缘之间从0混合到1。

Could be done with wave particles but its useful to have two radii, and the operation is an alpha blend as opposed to additive blend.

可以使用波粒子完成,但使用两个半径很有用,并且操作是alpha混合,而不是添加混合。

  -Spheres placed in world to influence waves(放置在世界上影响波浪的球体)
  -Ramp waves down in bays/around islands(海湾/岛屿周围的斜坡波浪下降)
  -Ramp waves up in storms(风暴中波浪上升)

1.5 Shape / Wave Particles(局部形状-波粒子)

The second way we add local detail is using wave particles.

添加局部细节的第二种方法是使用波粒子。

-Wave Particles introduced by [Yuksel2007]【Yuksel2007】引入的波粒子
  -“Blobs” of water that move over the surface 水面上运动的“物体”

In our implementation the wave particles contributed both water volume and foam values

在我们的实现中,波粒子贡献了水量和泡沫值。

We tethered foam wave particles to floating objects to help them connect with the surface. Moving objects also generated a wake simply by spawning wave particles moving outwards from the object and scaling the wave particle height by the velocity. In the paper from Yuksel they preserve water volume which is nice.

我们将泡沫波粒子系在漂浮的物体上,帮助它们与表面连接。移动的对象也会生成尾迹,只需生成从对象向外移动的波粒子,并按速度缩放波粒子高度即可。在来自Yuksel的论文中,它们保留了水量,这很好。

  • Contribute both surface height and foam values for shading(为着色提供“曲面高度”和“泡沫”值)
  • Can be either free-moving or tethered to floating objects(波粒子可以自由移动,也可以系在浮动对象上)

Here is a cross section profile of a single wave particle. Yuksel et al. use a cosine curve to give the wave shape. We use the smoothstep function. This allowed us to factor out some terms and use in both the height and derivative computation.

 这是单个波粒的横截面剖面图。Yuksel等人使用余弦曲线给出波形。我们使用smoothstep函数。这使我们能够在高度和导数计算中计算出一些术语和用法。

  • We use smoothstep as the particle kernel
  • Cross section shown below

 

We can do a symmetrical parameter offset to get a donut shape i.e. a ripple.我们可以做一个对称的参数偏移,得到一个圆环形状,即纹波。

This is novel as far as we know.据我们所知,这是目前最先进的方式。

Could probably get a train of ripples by transforming the wave particle parameter.可以通过变换波粒参数得到一系列的波纹。

See the appendix for equations.方程式见附录。

  • Can offset parameter to get ripples. 可以偏移参数以获取波纹

 

Using positive ripple only – would be best to follow it with a negative ripple.

仅使用正波纹–最好使用同时跟上一个负波纹。

Could probably get a train of ripples by transforming the wave particle parameter.

可以通过变换波粒参数得到一系列的波纹。

Insert sea monster here

在此插入海怪

To efficiently evaluate the shape contributed by wave particles, we need a fast way to query them.

为了有效地得到波浪粒子所贡献的形状,需要一种快速的查询方法。

Use uniform grid.

使用统一网格。

Rasterize all possible cells, so that lookup is a single query. This however means that the bucket sizes in the uniform grid have to be larger as every WP is written to 9 cells.

栅格化所有可能的单元格,使查找成为单个查询。但是,这意味着统一网格中的桶大小必须更大,因为每个WP都要写入9个单元格。

Would have been best to have multiple grids to allow for different wave particle kernel widths (a uniform grid with cell width c imposes a maximum wave particle kernel radius of c). We ran out of time here 

最好有多个网格以允许不同的波粒核宽度(单元宽度为c的均匀网格施加最大波粒核半径为c)。我们在这里没时间了

-World axis-aligned uniform grid for queries用于查询的世界轴对齐统一网格
  -Write active particles into grid after update更新后将活动粒子写入栅格
  -Simple loop to rasterize ripples onto grid通过简单循环将涟漪光栅化写入到网格中

图:眼睛看向水面,将水面网格化

1.6 Shape / LOD(形状-LOD)

We want to use shape judiciously. We’ll have a very limited number of samples later.

我们要明智地使用形状。稍后我们会有非常有限的采样。

Insufficient sampling leads to large interpolation error and possibly aliasing.

采样不足会导致较大的插值误差和可能的混叠(锯齿?)。

-Limited number of samples有限数量的采样
  -Especially when meshing on the CPU尤其是在CPU上进行网格化时

We really need to be economical on shape.

我们真的需要节省的形状。

-Avoid shape where it is not apparent当不可见时要避免形状
  -View dependent根据可视而定

We only introduce shape close to the viewer. Shape is removed in these ways. For the procedural approach we could also make waves smoother (crests less sharp).

我们只介绍接近观众形状。形状以这些方式删除。对于程序方法,我们还可以使波更平滑(波峰不那么尖锐)。

Ramping down/scaling does not solve undersampling/aliasing, but reduces the magnitude of the error

递减/缩放不会解决欠采样/锯齿问题,但会降低误差的大小

Proper filtering of fourier synthesised surface patches could be performed if we did meshing on the GPU and we were willing to pay for mipmaps.

如果我们在GPU上进行网格划分,并且愿意支付mipmaps的费用,则可以对傅里叶合成的曲面片执行适当的滤波。

  • Procedural – omit smaller wavelengths程序–忽略较小波长
  • Fourier synthesis – ramp down傅立叶合成-缓降
  • Wave particles – ramp down波浪粒子–缓降

1.7 Shape / Summary(形状-总结)

  • Many ways to describe shape有很多描述形状的方法
  • We found the discussed methods to be我们发现所讨论的方法是:

    -Expressive富于表现力

    -Relatively quick and easy to implement相对快速且易于实施

第二章:Meshing(网格化)

There are many other ways that shape could be described. Could for example have repeated the input coordinate to get a chain or ripples from one wave particle. We found the previous were quick and easy to implement, efficient to compute and gave us a reasonable amount of expressive power.

Now that we have the shape, we want to sample it to generate the mesh.

还有很多其他的方法可以描述形状。例如,可以重复输入坐标以从一个波粒子获取链或涟漪。我们发现前面的方法快速且易于实现,计算效率高,并为我们提供了合理的表达能力。
现在我们有了这个形状,我们想对它进行采样以生成网格。

  • Need a set of sample positions需要一系列的采样点
  • Triangulate to get surface三角化以获取曲面

Also ideally we would get alignment of mesh edges with edges/corners of the shape. It seems like there are ways to adjust the topology based on wave direction to get a better alignment of edges to the shape but we didn’t do anything here.

此外,理想情况下,我们可以将网格边与形状的边/角对齐。似乎有一些方法可以根据波的方向调整拓扑结构,以使边与形状更好地对齐,但我们在这里没有做任何事情。

-We want to adapt meshing to shape我们希望调整网格以适应形状
-Globally全球范围内
  -View dependent sampling根据可视情况采样
-Locally局部范围内
  -Pinch verts at wave crests and wave particles波峰和波粒子处的收缩顶点
  -See appendix见附件

2.1 Meshing / Clipmapping(全球大范围尺度的网格化-Clipmapping)

Mesh verts almost completely stationary (bar some blending between detail levels)

(远处的?)网格顶点几乎完全静止固定不变(除了细节级别之间的一些混合)

  • Sew different resolution grids together将不同分辨率的格网缝合在一起

Source: [Losasso2004]

We ruled this out during preproduction based on some guesses about implementation difficulty and runtime efficiency. I don’t have evidence to confirm this though. And it has shipped in AAA titles [Ochoa2012], I believe CryEngine uses it too – TODO dig up presentation (http://www.crytek.com/cryengine/presentations )

基于对实现难度和运行时效率的一些猜测,我们在预生产阶段排除了这一点。但我没有证据证实这一点。而且它已经发布了AAA的瓦片[Ochoa2012],我相信CryEngine也使用了它——要挖掘演示文稿(http://www.crytek.com/cryengine/presentations)

An interesting contribution would be to compare the two using some kind of suitable performance and quality metrics.

一个有趣的贡献或许是使用某种合适的性能和质量度量来比较两者。

  • Sew different resolution grids together将不同分辨率的栅格缝合在一起
  • Ruled out during preproduction在试生产期间排除(这个方法?)
  • Future work: proper comparison今后的工作:适当的比较

2.2 Meshing / Projected grid(全球大范围尺度的网格化-投影网格)

Instead we started with the projected grid method.

取而代之,我们从投影网格方法开始。

The idea with this method is to generate a mesh in screen space and then project it onto the ocean plane. Then the projected verts are then the sample points of the shape.

这种方法的思想是在屏幕空间生成网格,然后将其投影到海洋平面上。然后,投影的顶点就是形状的采样点。

Introduced by [Hinsinger2002]

由【Hinsinger2002】引入的。

Mesh moves with viewpoint so this method is prone to interpolation error.

网格随视点移动,容易产生插值误差。

I refer to this as interpolation error whereas it’s typically referred to as aliasing. I guess it is aliasing (from the triangle hat reconstruction filter?) but I’ll keep referring to it as interpolation error here.

我称之为插值误差,而它通常称为锯齿。我猜这是锯齿(从三角帽重建过滤器?),但我在这里会继续称它为插值误差。

-Simple and cheap简单而廉价
-View adaptive视图自适应
-Verts move with camera顶点随摄影机移动
  -Interpolation error becomes animated and noticeable插值误差变为动画且明显

Here is what it looks like in motion. Note the rippling effect on the surface. And the height of the wave changes considerably depending on the samples.

下面是它运动时的样子。请注意表面上的涟漪效果。波的高度随采样的不同而变化很大。

Here is a 3d prototyping scene. It has 3 parabolic waves summed together (introduced earlier).

这是一个3d原型场景。它有三个抛物线波加在一起(前面介绍)。

When the camera is stationary, nothing out of the ordinary.

当相机静止不动时,没有什么异常。

Now freeze the ocean surface and move the camera.

现在冻结海面并移动相机。

The rippling artifacts are obvious.

波纹伪影是明显的。

Note that this error is still there when the camera is stationary! Its just not noticeable because the error is frozen.

 请注意,当相机静止时,此错误仍然存在!它只是不明显,因为错误已冻结。

Similar issues occur when rotating the camera. Most noticeable at sides of screen.

旋转相机时也会出现类似问题。在屏幕两侧最明显。

This is happening in the first video.如第一个视频中所示:

  • If we can keep verts stationary, we can freeze interpolation error.如果我们能保持顶点不变,我们就可以冻结插值误差

2.3 Meshing / Polar Meshing(全球大范围尺度的网格化-极坐标网格)

  • We introduce Polar Meshing我们引入极坐标网格
  • Aims to keep vertices stationary in world space目的是使顶点在世界空间中保持静止

第一种情况:Rotation(旋转)

This is the trace of an individual vert when the view is rotated. We want the verts to be as stationary as possible to avoid the animated interpolation error shown before.

这是旋转视图时单个顶点的轨迹。我们希望顶点尽可能保持静止,以避免前面显示的动画插值错误。

Solution part 1: Change vert placement to match vert flow.

解决方案第1部分:更改顶点位置以匹配顶点流。

Instead of doing a strict screen space projection of a regular grid, we are moving into world space and constructing the mesh around the viewer.

我们不是对规则网格进行严格的屏幕空间投影,而是移动到世界空间并围绕查看器构建网格。

  • Change shape to match vert flow更改形状以匹配垂直流

Solution part 2: Snap mesh rotation to angular increments that match the mesh.

解决方案第2部分:捕捉网格旋转到与网格匹配的角度增量。

  • Snap rotation捕捉旋转

 

Result – completely stationary verts.

结果—完全静止的顶点。

第二种情况:Forwards motion(向前移动)

One idea would be to simply pull the vert ring radii inwards to compensate for some of the motion of the verts.

一种方法是简单地向内拉动顶点环半径,以补偿顶点的某些运动。

However we quickly lose the detail close to the viewer and end up with a very sparse mesh.

但是,我们很快会丢失靠近查看器的细节,最终得到非常稀疏的网格。

Move vert rings inwards(向内移动顶点环)

So we would like to introduce detail as the mesh approaches the viewer by smoothly dividing vert rings.

因此,我们希望当网格靠近观察者时,通过平滑分割顶点环,从而引入细节。

Question – when and where do the splits occur?

问题–何时何地发生拆分?

  • Adaptive tessellation自适应细分

  • How to organise split/merge events?如何组织拆分/合并事件?

Idea: get ring radii by intersecting a line with a binary tree

想法:通过一条线与二叉树相交得到环半径

 

>>Structured Volume Sampling - Huw Bowles:https://www.jianshu.com/p/9c8f4575b9b2

>>作者github网址:https://github.com/huwb

posted on 2023-05-25 10:15  XiaoNiuFeiTian  阅读(53)  评论(0编辑  收藏  举报