8000 GitHub - ivdstudios/crest-oceanrender: Novel ocean rendering techniques (Unity3D)
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

ivdstudios/crest-oceanrender

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

crest

Teaser

Contacts: Huw Bowles (@hdb1 , huw dot bowles at gmail dot com), Daniel Zimmermann (@DanyGZimmermann, infkdude at gmail dot com), Chino Noris (@chino_noris , chino dot noris at epost dot ch), Beibei Wang (bebei dot wang at gmail dot com)

Introduction

Crest is a Unity3D implementation of a number of novel ocean rendering techniques published at SIGGRAPH 2017 in the Advances in Real-Time Rendering course (course page link).

It demonstrates a number of techniques described in this course:

  • CDClipmaps - a new meshing approach that combines the simplicity of Clipmaps with the Continuous Detail of CDLOD.
  • GPU-based shape system - each LOD has an associated displacement texture which is rendered by the WaveDataCam game object.
  • Normal map scaling - a technique to improve the range of view distances for which a set of normal maps will work.
  • Foam - two foam layers that are computed on the fly from the displacement textures.

The branch dynamic_simulation contains a fully dynamic multi-scale water simulation (isntead of a kinematic animation). This gives interesting effects such as depth-dependent wave speeds, refraction, shadowing, reflections, etc. However it currently does not support displacement shapes and does not give the same quality animation as the kinematic version in the master branch.

Summary of contributions

We introduce an elegant, unified data structure for an anti-aliased, level of detail water simulation and rendering system.

Level of detail is a central consideration in our system. We use the infinity norm with square isolines to drive the detail - this fits well to the square textures we use to render/simulate the water shape. We do not require spatial data structures such as quad trees to select detail which simplifies our implementation enormously.

The water shape is stored in multiple overlapping nested textures that are centered around the viewer. Each texture represents a different scale. The smallest scale gives high detail close to the viewer. TODO update these notes with latest implementation.

The ocean surface is rendered by submitting geometry tiles which are placed around the viewer on startup. The tiles are generated on the CPU on startup. The shape textures are sampled in the vertex shader to compute the final shape. The layout and resolution of the tiles match 1:1 with the shape texture resolution, so that data resolution and sampling rate are well matched. Building the mesh out of tiles afford standard frustum culling.

When the viewer moves, shape rendering snaps to texel positions and geometry is smoothly transitioned out towards the boundaries. The LODs also slide up and down scales when the viewer changes altitude. A height interpolation parameter deals with fading shape in/out at the lowest/highest levels of detail. This eliminates visible pops/discontinuities.

Although normal maps are not stored in shape textures or simulated, they are treated as first class shape, and are scaled with the LODs so that they always give the appearance of waves that are higher detailed than the most detailed shape LOD. The required scaling and blending calculations hang off the ocean geometry scales and use the same interpolation parameters.

The above gives a complete ocean rendering system. There are just a few core parameters which are intuitive to tweak, such as a single overall resolution slider and the number of LOD levels to generate.

How it Works

On startup, the OceanBuilder script creates the ocean geometry as a LODs, each composed of geometry tiles and a shape camera to render the displacement texture for that LOD. It has the following parameters that are passed to it on startup from the OceanRenderer script:

  • Base Vert density - the base vert/shape texel density of an ocean patch. If you set the scale of a LOD to 1, this density would be the world space verts/m. More means more verts/shape, at the cost of more processing.
  • Lod Count - the number of levels of detail / scales of ocean geometry to generate. More means more dynamic range of usable shape/mesh at the cost of more processing.
  • Max Wave Height - this is just so that the ocean tiles bounding box height can be set, to ensure culling eliminates tiles correctly.
  • Max Scale - the ocean is scaled horizontally with viewer height, to keep the meshing suitable for elevated viewpoints. This sets the maximum the ocean will be scaled if set to a positive value.
  • Min Scale - this clamps the scale from below, to prevent the ocean scaling down to 0 when the camera approaches the sea level. This should be set to a low value gives lots of detail, but will limmit the horizontal extents of the ocean as the detail scales have a limited dynamic range (set by the previous Lod Count parameter).

At run-time, the viewpoint is moved first, and then the Ocean object is placed at sea level under the viewer. A horizontal scale is compute for the ocean based on the viewer height, as well as a _viewerAltitudeLevelAlpha that captures where the camera is between the current scale and the next scale (x2), and allows a smooth transition between scales to be achieved using the two mechanisms described in the course.

Once the ocean has been placed, the ocean surface shape is generated by rendering Gerstner wave components into the shape LODs.

The ocean geometry itself as the Ocean shader attached. The vertex shader snaps the verts to grid positions to make them stable. It then computes a lodAlpha which starts at 0 for the inside of the LOD and becomes 1 at the outer edge. It is computed from taxicab distance as noted in the course. This value is used to drive the vertex layout transition, to enable a seemless match between the two. The vertex shader then samples the current LOD shape texture and the next shape texture and uses lodAlpha to interpolate them for a smooth transition across displacement textures. A foam value is also computed using the determinant of the Jacobian of the displacement texture. Finally, it passes the LOD geometry scale and lodAlpha to the pixel shader.

The ocean pixel shader samples normal maps at 2 different scales, both proportional to the current and next LOD scales, and then interpolates the result using lodAlpha for a smooth transition. Two layers of foam are added based on different thresholds of the foam value, with black point fading used to blend them.

Bugs and Improvement Directions

  • Each Gerstner wave is computed and blended into the displacement texture individually. This makes them very easy to work and convenient, but baking them down to a single pass would be an interesting optimisation direction. Using prebaked textures (i.e. from an offline ocean simulation) would also be an option.
  • Ocean tiles are updated and drawn as separate draw calls. This is convenient for research and supports frustum culling easily, but it might make sense to instance these in a production scenario.

Links

Core work

Wave Theory

Boundary conditions

Water depth

Breaking waves

Experiments

Particle sim

Generating ocean waves into simulation

  • Sum of gerstner waves - each frame compute gerstner waves that are appropriate for each sim, apply a force to the ocean surface to pull towards gerstner wave
  • Write dynamic state into sim - write dynamic state of an FFT or the sum of gerstner waves into the sim. This could be stamped onto the sim periodically, if the surface repeats with a given period. This is possible - each sim has a particular wave speed. If a strict scheme of only writing a particular wave length into each sim was employed, this would mean the waves would repeat with a particular period. However it's non-obvious how this could be strictly enforced in a practical game-like situation.
  • The generation of waves by wind is well understood: https://www.wikiwaves.org/Ocean-Wave_Spectra . This could be modelled. There is a transfer of energy across wavelengths that allows waves that travel faster than wind to be generated, perhaps this can be modelled by transferring energy across sims. This feels like the approach that fits most accurately into the sim paradigm. It would require wind to be defined everywhere. Another problem is that this process occurs over large fetch areas (thousands of wavelengths in size), whereas the sim domains are very bounded, so the process would need to be accelerated (?).

About

Novel ocean rendering techniques (Unity3D)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C# 45.4%
  • C 28.5%
  • ShaderLab 13.2%
  • C++ 6.4%
  • HLSL 3.7%
  • GLSL 2.8%
0