海水效果

Category Archives: Water

Ceto: Ocean System for Unity

Well its been a long time since I made a blog post. 13 months to be exact. So what have I been doing all that time?

To make a long story sort I decided that I would start making some products for the asset store. Its been fun making projects for the blog but its not really something I could keep doing forever. The more projects I put up the more questions and comments I got and it just started to be a lot of work for something that essentially costs me money. So from here on there wont be anymore projects posted here but there maybe the occasional post about a project I’m working on.

On that note I would like to present Ceto which is a ocean system for Unity. Its seemed like the natural choice given that the previous ocean projects have gotten the most attention. Work on Ceto began around March this year and it’s finally got to the stage where I was happy enough to put it on the asset store. Ceto is already a robust asset that provides enough flexibility and features for most applications and there are still many more features and improvements to come.

Although Ceto is new to the asset store it is already being used in a few titles. It is currently being used inThe Forest, in Homebrew, its to replace the previous ocean for Strandard Deep and is going to used for a ship simulation being created for Rolls-Royce Marine by Morild Interaktiv.

Ceto is not just a rehash of the old ocean project on this blog. Its has been extensively redesigned. There are some common features like the wave spectrum previously used but plenty of new features like reflections, underwater effects and a new concept called wave overlays.

The wave overlays are a quite a powerful new feature. They allow the ocean to be easily modified in local areas and the number of overlays is independent to the shader. This means that you could have hundreds of overlays modifying the ocean and the ocean shader still has the same performance. The overlays do of course have a small cost (a 1 quad draw call per overlay) but are still cheap and could be further optimized by batching to reduce the draw calls. The overlays allow you to modify the wave height, foam or normals in a local areas as well as allowing you to clip away parts of the ocean mesh. Very useful for inland caves and low areas of the terrain.

So if you would like to have a look at Ceto here’s the asset store link as well as some demo projects.

Ceto Asset Store Page.

Ceto Windows DX9 Demo.

Ceto Windows DX11 Demo.

 

Ocean44

Waves

CetoSunset

Ocean50

These are some screen shots provided by Morild Interaktiv.

Screenshot_04

Screenshot_01

This image was provide for Homebrew.

CetoHomeBrew

 

Tiled directional flow in Unity

This is just a simple project but I find sometime the simpler ones are the most popular. This project is a Unity version of the tiled directional flow project found here.

The idea behind this project is provide a method to control the direction water flows based on a flow map. The flow map (also know as a velocity map) is simply a texture with the red and green components representing the flow direction normalized to a range of 0 – 1. The shader then divides space into a series of squares where the waters normal direction is determined by the flow map. This is done four times, each with a different offset and the results blended together to remove any seams.

I was planning to apply the shader to a terrain but the height map provided in the demo is not of a very good quality and I don’t really have time at the moment to make a nice height map and then create the flow map for that terrain. Creating the flow map could be a bit of a hassle. It would be best done using a fluid simulation and some 3D modelling programs can do this for you. You could also paint it by hand in photoshop but this could be quite hard.

At the moment the shader is just applied to a flat plane and viewed from above so the effect can be seen best. Moving this to a terrain shader would be relatively trivial if that is what you need. I may do this as some point in the future when I have time to make a really nice terrain with rivers. Rivers are one topic I am quite interested in and is something I want to do some projects on in the future.

If you are after a much more professional version of this I know there are some on the Unity asset store.

This project will work in Unity Indie and uses SM3.

Project files.

Web player.

TiledDirectionalFlow0

Reference

Frans van Hoesel, “Tiled Directional Flow”,
University of Groningen, The Netherlands,
SIGGRAPH 2011,  August 7 – 11, 2011.

Ocean white caps in Unity

Yes, another port to Unity of one of Eric Bruntons projects. I thought the last one I did would be the last but when doing a bit of research into ocean white caps and foam I came across his “Real-time Animation and rendering of whitecaps” article. I had seen this article before but I didn’t think there was any source code available. Reading the article again I noticed there was a link at the bottom to the source code.

This project is basically a extension of the ocean BRDF project and uses the same lighting model and fourier transform method of wave generation. The difference is that the wave generation and lighting model has been extended to take wave white caps into consideration. The white caps are generated using the choppy wave model out lined by Tessendorf. This method works by sampling the vertical and horizontal perturbations produced by the ocean spectrum in the frequency domain. A fourier transform is then applied and the results are converted to the spatial domain. The benefit to this is that the fourier transform can easily create a tileable texture with little repeating patterns. The down side is that the extra fourier transforms start to add up and performance starts to suffer. This project is a lot more demanding than the previous ocean BRDF project.

Since the white caps look best in a choppy ocean Ive had to add the code to displace the waves on the X and Z axis not just the Y axis. This creates a more ‘watery’ ocean with waves that peak sharply. Its at these sharp peaks that the white caps can best be seen. While this choppy wave model was in Eric’s original BRDF project I had left it out in the previous ocean projects I have done. The reason is that it requires two more fourier transforms, one for the X axis displacement and one for the Z axis displacement. Since I didn’t think the extra performance cost justified the results I left it out. As the white caps needs to have this choppy wave model to look their best I have included it in this project. In the previous ocean projects I have done there are 3 textures that need to have the fourier transform applied to. 1 for the heights and 2 for the slopes. In this project there is a extra 2 for the displacement and 3 for the white caps taking the total textures to 8 that have fourier transform applied to. In Eric’s code he uses 8 render targets to write all the data in a single fourier pass. Since Unity restricts the number of render targets to a maximum of 4 I have had to split the fourier passes into 3 passes. One pass will do the heights and slopes the next the displacements and the next the white caps.

Project files (Unity4)

Project files (Unity5)

OceanWhiteCaps0

By default the amount of foam is quite high. This starts to look a bit fake when viewed from high above. This image has the white cap strength set to 0.2.

OceanWhiteCaps1

You can turn this down on the ocean game object. This image has the white cap strength set to 0.05. OceanWhiteCaps2

class="youtube-player" type="text/html" width="633" height="387" src="https://www.youtube.com/embed/sQ11hadNgUk?version=3&rel=1&fs=1&autohide=2&showsearch=0&showinfo=1&iv_load_policy=1&wmode=transparent" allowfullscreen="true" style="border-width: 0px; border-style: initial; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; max-width: 100%;">

References

Eric Bruneton, Fabrice Neyret, and Nicolas Holzschuch, (2010) Real-time Realistic Ocean Lighting using Seamless Transitions from Geometry to BRDF, In EUROGRAPHICS 2010 Volume 29 (2010), Number 2

Eric Bruneton, Jonathan Dupuy, Real-time Animation and Rendering of Ocean Whitecaps, INRIA Grenoble Rhone-Alpes, Universite de Grenoble et CNRS, Laboratoire Jean Kuntzmann Universite de Lyon, CNRS Universite Lyon 1, LIRIS, UMR5205, F-69622, France

Ocean waves using phillips Spectrum in Unity

This is another ocean project but one that takes quite a different approach to the other two. The other ocean projects use a spectrum for generating the waves base on a article call ‘A unified directional spectrum for long and short wind-driven waves’. This spectrum is designed to replicate ocean waves on both small and large scales and is good for replicating large wind driven waves in a open ocean.

This is not the only wave spectrum around. In fact this spectrum was based on a much earlier model called Phillips spectrum. I wanted to get a working copy of Phillips spectrum running in Unity because it has quite a different effect than the previous model and in some ways looks much more ‘watery’. Some time around 2001 Jerry Tessendorf released a paper called ‘Simulating Ocean Water’ and in it he out lined all the methods and math need for simulating oceans. If you have not read it I recommend having a look as its probably the best paper on simulating oceans around. In this paper the math for using Phillips spectrum was outlined and I had planned to convert this to code but lucky I came across a blog by Kieth Lantz where he has already done this (Thanks Kieth).

His project was written in C++ so it was just a matter of converting that to a C# script for Unity. I have left all the math the same but have made some changes and restructured the code a bit. The issue is that he has used a class for complex numbers with operator overloading. This is fine in C++ but in a C# script operator overloading does not perform as well as in C++. Its OK for a small number of calculations but in something like this where there are a massive number of math calculations to perform it starts to add up. When I first ported the code over I replicated it exactly with a complex number class in C# and I got a frame rate of 10fps. Not very practical. By performing the complex number math by just using floats and storing the results in Unity’s Vector2 class I was able to get the frame rate from 10fps to 60fps. From there I restructured some things a bit as there was some calculations that could be precomputed and stored in a look up table. I also used the fourier transform class I had used in the previous ocean projects because it operated on complex numbers stored in a Vector2 or Vector4. The slope and displacement both consist of two complex numbers which could be stored in a array of Vector4’s and have the fourier transformed applied at the same time instead of separately.

With all those changes I was able to get the frame rate from 60fps to 100 fps. Much better. The fourier transform is calculated on the CPU and in some of the previous ocean projects I have done the fourier transform is calculated on the GPU. You could do the same with this project but I don’t plan to do so. The reason is that performing the operation on the GPU makes getting the wave heights on the CPU for physics calculations not practical. This method uses the wave heights to directly modify a meshes vertices position. This means you can interact directly with the mesh for physics effects. The mesh created is tileable  and I have added the ability to tile as many meshes as you like.

There are some problems with this approach however. For a start since the results are stored in a mesh instead of a texture there is no way to remove the repeating patten produce from tiling multiple meshes. Secondly since larger scenes are made from tiling the same mesh there is no natural way to create a LOD scheme which would be essential for large scenes. And lastly since the normals are only per vertex they do not contain enough detail for good lighting calculations . You could of course use a normal map to add extra detail.

On the ocean game object there are a few parameters you can change. There’s ‘N’ which is the fourier grid size and length which is the world size of the grid. So you can make a mesh that spans a larger area but keeps the same fourier grid size, you will get a lower resolution mesh though. There’s the wave amp that controls how high the waves will be. Something to watch out for with this is that the waves can ‘curl’ back on themselves if it is set to high. Its just something that happens because of the math used. If you increase the length you may need to decrease the wave amp to prevent this happening. There’s is also a wind speed that controls the size of the waves created and there direction. One last thing. I am getting some bad aliasing in some places. Not sure what is causing that at the moment.

This project will run in Unity Indie.

Note – The fourier transform now runs on its own thread resulting in a big performance increase.

Project Files (Unity 4).

Project Files (Unity 5).

Web Player.

PhillipsOcean0

References

www.keithLantz.net

Jerry Tessendorf, Simulating Ocean Water, 2001

Ocean with BRDF lighting in Unity

A while ago I did a project that was basically a port of Eric Brunetons ocean project. The focus of Eric’s project was a BRDF lighting model. I choose to leave out the BRDF lighting model and just used his method of generating the waves using fourier transform. The BRDF lighting model added a large amount of complexity to the project and I though it would be best to leave it out. The project also used his atmospheric scatting project for the sky and there are some limitations in doing this in Unity. When I completed my ocean project I was a little unhappy about the quality of the shader so I’ve decided to do a separate project that is a complete port of Eric’s project with the BRDF lighting and atmospheric scattering. The idea was to see how practical this was in Unity and how it performed. Unsurprisingly the quality of the shader is much better and it performs quite well with frame rates of around 100 on my laptop.

Since I already had a lot of the code in other projects it did not take to long to complete this project. I’ve managed to knock it together in a afternoon. I did run into a few problems however. For the BRDF lighting the variance of the wave slopes needs to be precomputed and stored in a 3d texture. This only needs to be done once on start up. To render into a 3d texture in Unity I needed to use a compute shader. Doing this caused my graphics card to crash however. The problem is the calculations require a rather large loop in the compute shader and I think this was the cause of the crash. I found that if I reduce the number of threads that the compute shader uses it stopped the crashes. Not sure why that is and other people may experience crashes as well even on the settings that work on my card. I had considered moving the calculations to the CPU but it could be rather slow to compute. If enough people report crashes I may do this but for the time being its working fine, on my card at least.

The second issue was some artifacts on the back of the waves. This showed up due to the sky reflections being a dark color on the back of the waves. In Eric’s project you can see this sometimes as well but it seemed to be much worst in my shader. I’m not to sure whats causing that but to fix it I used a slightly modified normal for the part of the code that was causing the artifacts. Since Eric used a projected grid for the ocean mesh the detail is much greater than my radial grid and I suspect this is amplifying the issue. In any case I managed to reduce it to a acceptable level. Edit – Fixed the issue with the black marks. Turns out I had just forgotten to enable ansiotrophic filtering and mip mapping on the sky map render texture.

So here’s the project files. Just watch out as the shaders are rather complex and there is a good chance they may not be supported on all cards. This project requires Unity Pro (render textures) and will work in dx9/SM3.

If you are looking for the updated project with the get heights function its at the bottom of the page.

EDIT – This project has been moved into dx9/SM3, see updates below. The’ Get Heights’ version (see updates) is still dx11/SM5.

Project files (dx9 Unity 4).

oceanBRDF0

oceanBRDF1

oceanBRDF2

class="youtube-player" type="text/html" width="633" height="387" src="https://www.youtube.com/embed/cRWCLF9Mi68?version=3&rel=1&fs=1&autohide=2&showsearch=0&showinfo=1&iv_load_policy=1&wmode=transparent" allowfullscreen="true" style="border-width: 0px; border-style: initial; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; max-width: 100%;">

Update

Recently I have been working on a project that required fetching large amounts of data from the GPU. Since a method for getting the ocean heights from a script is a much requested feature for this project I though I would use the scripts I had just written and update this project. The script uses a compute shader to write the data in a render texture into a compute buffer where the data can then be fetched. Once a copy of the heights have been fetched the wave height at any world position can be reconstructed. This does come at a cost how ever. On my laptop it costs about 20-30 fps (NVIDA GT 555M).  Obviously on a new computer it maybe much less. The contents of the whole render texture is retrieved each frame, about 128 by 128 pixels. If only a few heights are need it maybe best to only retrieve what is needed but since retrieving data from the GPU forces it to stall and send the request I thought it would be best to get everything in one go.

I have made a new project for this update as I have made a few other changes and thought it maybe best to keep them separate. The same scripts I have added can also be used to send data into a render texture and as such I have remove the encode/decode method previously used to write data into a render texture as it was a bit redundant in a dx11 build. I know a few people have modified this project so it doesn’t need to use dx11 so the encode/decode method would be needed for this hence the reason I have made this a new project file. EDIT – I have since moved the original to dx9/SM3.

I have only added this get heights function to this project and not the other ocean projects. I don’t want the ocean surface effects project to be dx11 only and there are some technical issues that makes this method a bit hard in the ocean white cap project.

There is only one issue with this method. For some reason the heights don’t quite match up when the ocean waves are very large. I’m not quite sure what the reason is at the moment. I think it maybe OK for larger objects like ships but is very obvious for small items like crates. The waves can be quite large before this becomes a issue however.

Project files (Get heights dx11 Unity 4).

Project files (Get heights dx11 Unity 5).

oceanBRDF4

Update

This project has been moved from dx11 to dx9. The ‘Get Heights’ version is still dx11 however. The reason it was originally in dx11 was because I needed to render into a 3D texture in two places which can only be done in dx11 in Unity. The variance texture for the BRDF and the inscatter texture for the atmospheric scattering. The calculation for the variance texture was moved to a script and the data for each channel is normalized and loaded into a 8 bit texture. The data is then unnormalized in the shader. I was expecting some lost of quality but the results look the same to me. The calculation is quite slow however and I had to cut the texture size from 16 to 4 pixels cubed.

The inscatter texture is now loaded into a 2D texture and some modifications have been made to the atmospheric code to correct for this. It still represents a 4D data set like before.

References

Eric Bruneton, Fabrice Neyret, and Nicolas Holzschuch, (2010) Real-time Realistic Ocean Lighting using Seamless Transitions from Geometry to BRDF, In EUROGRAPHICS 2010 Volume 29 (2010), Number 2

Eric Bruneton and Fabrice Neyret, (2008) Precomputed Atmospheric Scattering, Eurographics Symposium on Rendering 2008, Volume 27 (2008), Number 4

T. Elfouhaily, B. Chapron, K. Katsaros, D. Vandemark, A unified directional spectrum for long and short wind-driven waves, Journal of Geophysical Research vol 102, p781-796, 1997

Ocean surface effects in Unity

This is a ocean renderer Ive ported to Unity and is based on these two projects written in openGL for the first and DirectX for the second.

Eric’s ocean renderer and Clae’s water renderer.

I especially recommend having a look at Eric’s project. It would have to be the best ocean renderer I have seen. The focus of his project is the BRDF lighting model. I have taken this part out for my project. While it looks great the problem with the BRDF model is that its far to complicated and I wanted something more simple for people (and myself) to better understand whats going on. The math involved in generating the waves is hard enough to understand and the BRDF lighting model just gets in the way. The waves in this project are the most realistic Ive seen and I have used his approach in my project. The waves are created by using a function that recreates the spectrum of ocean waves in the frequency domain and converts it to the spatial domain using fourier transform. I believe the function is based on real world measurements of the statistical properties of waves.

In Clae’s project he used a technique called the projected grid to create a mesh for the water plane. Eric also used this technique. I originally went with this approach as well but the projected grid has issues with rendering the plane when the camera is at certain angles. There are solutions to this but I was concerned that there may always be some camera angles that may cause problems so I switched to a more conventional radial grid. The resolution of the grid is not as good but the results still look good.

I have two separate versions of this project. A Indie and a Pro version. The indie version performs all the calculations from scripts and suffers from performance issues as a result. This project probably wont be practical for a professional program but is a good demonstration for people who would like to get a better understanding of the code but don’t have Unity Pro. Getting the math to work on the CPU was a important step for moving everything to the GPU. In the Pro version all the calculations are performed on the GPU and performance is quite good with frame rates between 80 – 100 on my laptop. Since the data for the Pro version is completely calculated on the GPU there is no practical way to get the wave heights for physics calculations. This is a bit of a issue and if you must have the wave heights it maybe best to go with another technique.

The size of the grid for the fourier transform can be changed and its set at 128 for the pro version and 64 for the indie version. The pro version has a limit of 256 for the grid as some data has to be packed into a 8 bit texture. It handles well with a grid of 256 and the results are nicer but the extra performance cost wasn’t worth it so the default size was set to 128. For the indie version the calculations are done on the CPU so there is no limit to the grid size but it struggles with anything larger than 128.

You can find some settings in the ocean game object in the scene. You can change the wind speed, wave decay factor, wave amplitude, and the fourier transform size. These settings are only used on start up however and will have no effect during run time.

Note – The Indie version has been updated to run on its own thread resulting in a big performance increase.

Here’s the project files and web player.

Web player (Indie).

Project Files (Indie Unity 4).

Project Files (Indie Unity 5).

Web player (Pro).

Project Files (Pro Unity 4).

Project Files (Pro Unity 5).

Since this project I have completed a few more ocean projects that maybe of interest.

Ceto: Ocean System for Unity.

Ocean with BRDF Lighting.

Ocean white caps.

Ocean using Phillips spectrum.

ocean9 ocean6 ocean7 ocean8

References

Eric Bruneton, Fabrice Neyret, and Nicolas Holzschuch, (2010) Real-time Realistic Ocean Lighting using Seamless Transitions from Geometry to BRDF, In EUROGRAPHICS 2010 Volume 29 (2010), Number 2

Claes Johanson, Real-time water rendering Introducing the projected grid concept, March 2004 Lund University

T. Elfouhaily, B. Chapron, K. Katsaros, D. Vandemark, A unified directional spectrum for long and short wind-driven waves, Journal of Geophysical Research vol 102, p781-796, 1997

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值