Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Wanted: Ocean shader

Discussion in 'Works In Progress - Archive' started by bigkahuna, Jan 8, 2009.

  1. ToreTank

    ToreTank

    Joined:
    Jun 23, 2008
    Posts:
    165
    mike: Back at the office I finally got the chance to download and watch your videos in their entirety! I'm amazed, looks awesome :) Can't wait for a real-time demo!

    twinfox: The reflection is standard planar reflection/refraction like they use in the built-in water with a small hack offsetting the sampling based on wave height (in hindsight, I see that this could have been done more elegant by pretending all waves were at y height 0 when computing the UVs used for projection).
     
  2. Baalspawn

    Baalspawn

    Joined:
    Jan 9, 2009
    Posts:
    5
    Has nybody tried to expand the ocean beyond the limit of 9x9 tiles. (witch is about 1575mx1575m)
    need a realy good looking ocean that covers about 20000x20000 meters of terrain.
     
  3. angel_m

    angel_m

    Joined:
    Nov 4, 2005
    Posts:
    1,160
    Same problem here, about the ocean size...
     
  4. jeffcraighead

    jeffcraighead

    Joined:
    Nov 15, 2006
    Posts:
    740
    Is all that water going to be visible at once? Is more than the 1.5km x 1.5km going to be visible at once? If not, you could just shift the tiles around as needed so that it appears to be larger than it is.
     
  5. Baalspawn

    Baalspawn

    Joined:
    Jan 9, 2009
    Posts:
    5
    most will be visible at once (camera can see about 10000 meters and the water have to stay in one place since several players will travel around on the same map.
     
  6. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    There is a problem with this OCEAN, it mess up all full screen image FX, like Glow etc... any idea why?
     
  7. ToreTank

    ToreTank

    Joined:
    Jun 23, 2008
    Posts:
    165
    nikko: Which download screws it up, and what does it look like? Are you on windows? It'd be nice with a screenshot showing the problems (I can imagine there are some problems with the reflective/refractive version, such as overbright screen using the glow or flipped reflection using post-effects on windows, I'll post a fix for this in the near future).
     
  8. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    I have to go to work, but will post a video tonight.
    In fact, all the full screen shaders are doing the same thing.
    The full screen shaders are working correctly but it looks like if the remote camera that does the reflection+refraction+transparency is not at the right place, so when you move the camera from top to bottom for example, the shadow of the objects that are into the water are moving up down right left!

    Also it seems that the camera captures the full screen shader's effect when it calculates the textures...

    You don't have a pro version? because it is easy to check. I'll post a video tonight.
     
  9. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
  10. ToreTank

    ToreTank

    Joined:
    Jun 23, 2008
    Posts:
    165
    In OceanReflectionRefraction.shader, try replacing

    Code (csharp):
    1.  
    2. float3 projDelta = o.pos.xyz - mul( glstate.matrix.mvp, float4(v.vertex.x, 0.0, v.vertex.z, 1.0)).xyz;
    3.  
    4.     //Sample offset to try to minimize glitches when the waves are high
    5.     o.sampleOffset.xy = projDelta.xy/o.pos.z;
    6.  
    7.    
    8.     //TODO: This could probably be handled better. Texture coordinates must be
    9.     //mapped from -1,1 clip space to 0,1 texture space. Set up a bias matrix
    10.     //and use elements from _ProjectionParams like they do in the Pro water shader.
    11.     o.projTexCoord.xy = o.pos.xy/o.pos.z;
    12.     o.projTexCoord.xy += 1.0;
    13.     o.projTexCoord.xy /= 2.0;
    14.  
    with

    Code (csharp):
    1.  
    2. float4 tmpProj = mul( glstate.matrix.mvp, float4(v.vertex.x, 0.0, v.vertex.z, 1.0));
    3.  
    4.    
    5.     //Bias matrix for converting clip-space vertex positions
    6.     //to texture coordinates.
    7.     float3x4 mat = float3x4(
    8.     0.5, 0.0, 0.0, 0.5,
    9.     0.0, 0.5 * _ProjectionParams.x, 0.0, 0.5,
    10.     0.0, 0.0, 0.0, 1.0
    11.     );
    12.    
    13.     o.projTexCoord.xy = mul(mat, tmpProj).xy;
    14.     o.projTexCoord.xy /= tmpProj.w;
    15.  
    This "should work", as on DirectX the texture coordinates will be flipped (hence the _ProjectionParams.x in there) if post effects are used (temporary rendertextures).

    Also, if you want to tone down the overbright effect you probably get from the glow filter, try changing "half4 result = half4(0, 0, 0, 1);" to have the last component lower than 1 (you can of course base this on pixel intensity or something too, by setting result.a = someintensityfunctionbasedon(result.rgb) somewhere in the shader).

    To verify that it works on windows, I put up a quickly edited version at http://www.terravision.no/~trondabu/unity/water.html
     
  11. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    It works.

    I ve added added caustics and a bunch of other stuff. I will post the project as soon as possible.
     
  12. norby

    norby

    Joined:
    Jul 10, 2006
    Posts:
    277
    Can't wait to see it :p

    norby
     
  13. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    Here is a video of the most recent version:
    http://www.youtube.com/watch?v=9hYEXKvNvqs

    Before I publish the new shader and its script, I want to have underwater and some other features too. For now, here is a list of the additional features I've so far:
    - caustics animation
    - caustics color
    - caustics transparency
    - sun reflections on the water
    - color of the sun reflections
    - power of the sun
    - position of the sun (so it match any light)
    - refraction power (can create some nice metallic water like mercury
    - Main texture : the water can have a nice texture
    - Main texture color
    - Specular (sort of color enhancer/contrast in my case)
    - Specular color

    Of course it still have the refraction/fresnel, reflection, control over the refraction and reflection color and intensity...

    Lot of possibilities in fact...
    If anyone has a clue on how to detect and set a quick and dirty underwater (flip the mesh normals?) but then, how do I detect if I'm underwater, partially underwater? It seems a bit complicated.
     

    Attached Files:

  14. norby

    norby

    Joined:
    Jul 10, 2006
    Posts:
    277
    Hi Nikko

    maybe you can use the UnderwaterEffects script
    from the Island demo.

    Norby
     
  15. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    Brilliant! :)

    For underwater I would flip normals and turn off all reflections. You can sense the viewers eye by just checking for the transform of the camera. It might be better to use a simple water shader for when the camera is half in and half out of the water. Reflections probably wouldn't work at that angle anyways.

    Other underwater effects to consider: "God rays" and depth blur.

    Other above water effects to consider: boat wakes / trails and shadows.

    This is awesome work Nikko!
     
  16. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    Tahnks for the answers, I'll use that for now...

    I know how to check if I'm underwater, but the case where I'm partially underwated is tricky.

    I think I need 3 shaders and switch between them :
    - one above water (the complex one)
    - one partially underwater (very simple with no reflection/refraction to avoid weird distortion...BUT a way to display part of the underwater volume as well.
    - one totally underwater with whatever godrays, blur etc...
     
  17. ToreTank

    ToreTank

    Joined:
    Jun 23, 2008
    Posts:
    165
    Great work nikko! This is starting to look seriously good!

    I just thought I'd share some thoughts on the underwater/partially underwater stuff. I've been briefly working on something similar, and while it is nowhere near perfect, I think it has some potential. It is a bit cumbersome to set up though, and I'm mainly talking about the partial underwater scenario.

    Here's what I currently do (if the camera is _potentially_ seeing both over and under water, this is a simple height check taking max/min waveheight into account):

    1: Using an ortho cam, I render the water with a custom, simple shader from the camera position (carefully matching the ortho settings with the near plane of the perspective, normal camera), and in a vertex shader pull down vertices the farther from the camera they get (using clip-space z as a factor). This results in a mask, as seen on the red/yellow-ish frame on the screenshots (I haven't really thought of a good way to get a mask built from a thin polygon, so this hackish method is what I did in that case, I'll get back to a different and possibly better method later).

    2: Render the scene as seen underwater (using the regular camera settings). This involves rendering the water with flipped normals (using revert cullface from the GL-class) and a very simple shader (currently no refraction, though it would be quite possible) as a pass of its own, then rendering the rest of the underwater scene (not the water itself) using some suitable fog-settings and this pass should obviously not clear anything from the water surface pass. This results in the grey-ish frame just below the over/underwater mask from step 1.

    3: Render the scene using regular camera. In the callback-function OnRenderImage, I used the BlitWithMaterial from the Pro Standard Effects ImageEffects-class using a custom, fairly simple composition shader - all this shader takes as input is the source rendertexture passed into the OnRenderImage-effect, the over/underwater mask texture and the underwater render texture and blends them based on color (in my case, red channel is an on/off mask telling if we should render over or underwater, and if my memory serves me well, the green channel is some sort of wave speed used for simple underwater distortion).



    The main problem with this method is that the underwater mask might be slightly off in some cases, I think this is because vertices very seldom will hit the near plane and thus pulling them down as we go back in the frustum will also have an effect on the near plane position of any clipped polygons. I've recently thought of a possibly better way to do the over/underwater mask, but haven't had the time to test it out yet. Here's the idea from the top off my head:

    Render a heightmap of the water as seen directly above the near plane of the camera (it should be sufficient to have a camera covering only the near plane). Now, both regular and underwater passes are done as before, except this heightmap is now used as input in the OnRenderImage-function instead of the watermask. This heightmap must be projected onto the full-screen quad that is drawn to combine the textures (from above - the heightmap is perpedicular to the near plane). For each pixel, you can now read the height from the heightmap, and compare it to the current height of the pixel (in heightmap-camera-space), and based on the height comparison, choose which texture to sample from (this way you can even create a foam-ish effect near the water surface as well) - kind of like shadowmapping.

    I am now expecting someone to drop in and ask "why aren't you just doing..." and present me with a much simpler and robust method :) I can't think of a way to create a mask based on a clipped waterplane alone, but there might very well be and it would be greatly appreciated to get some tips on this!

    Oh, and quick question nikko - when rendering the reflection pass, do you have the face culling inverted? At some points in the youtube movie, it seems like it is rendering backfaces for the sphere (best seen around 4:00), but it may very well be my eyes playing tricks on me. Keep up the good work!
     

    Attached Files:

  18. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    @ToreTank - The stills look like you've nailed the effect for half in / out of the water. Can you post a video clip?

    It's amazing how many great ideas have evolved since I first started this thread (and my pretty lame attempt back then).
     
  19. Yann

    Yann

    Joined:
    Oct 20, 2007
    Posts:
    432
    Incredibly exciting :D :D :D

    Congrats to all, can't wait to build scenes with this fantastic tool
     
  20. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    Wow, very interesting ToreTank, I think we are going to have underwater very soon! Will have time to work on that tonight (east time), I may just post the project so you can add your work to it... we should post it under GNU License for example so if anyone improve it he will have to post the result to the community, what do you thing about that?
     
  21. ToreTank

    ToreTank

    Joined:
    Jun 23, 2008
    Posts:
    165
    I'll post a movie as soon as I get the chance to record it, I didn't have any recording software at hand yesterday.

    Sharing the project is a great thing, but I'm not too eager about it being under GPL, as this will seriously limit its use for anyone wanting to use it for closed-source projects, but, of course, this is entirely up to you or anyone else making changes to it. LGPL, on the other hand, is better for that purpose, in my opinion at least :) I'm not a license expert, but as far as I have understood, at least LGPL will let people use the licensed code/assets in closed-source project as long as it is not modified.

    Edit: I realize now that you by GNU License not necessarily meant GPL, sorry about that.
     
  22. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
  23. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    The ocean looks great but there's something really weird going on with the skybox. It looks like bits of it are flipping to all white (or all black in full screen mode).
     

    Attached Files:

  24. Irix

    Irix

    Joined:
    Aug 6, 2008
    Posts:
    28
    First I want to congratulate you guys on a job well done! I ported the Nvidia ocean shader to Unity a few months ago and was less then satisfied with the results. First because there were some bugs in my porting that I couldn´t manage to nail in time and second: it´s a pain getting height at a certain point from a vertex shader, or so it seemed, unless I missed something obvious.

    I´m using the latest package you guys provided and all is peachy, except for two things:

    1 - There are seams at the tiles, looking from certain angles you can see the skybox below. Is anyone else seeing this?

    2 - I can´t manage to replicate this beautiful sun specular on water, with flares, self-illuminated objects or whatever.


    Any help is appreciated, and congrats again!


    Sebastiao
     
  25. Yann

    Yann

    Joined:
    Oct 20, 2007
    Posts:
    432
    This is magnificent ! Strangely enough, I don't get the skybox problem. I'm on a MB Pro 2.4 with GeForce 8600M GT.

    Just wondering : would a complementary effect for wet objects be doable ? some animated texture that would only affect the parts of an object that have been covered by water, and would disappear porgressively until the object gets "dry' again. Dreaming is free... :)
     
  26. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    I don't have the Skybox thing too... but I think I know what it is. I'll fix that tonight and repost the players.

    Answers :
    - wet objects. I don't see exactly, as being wet can be very different from one object to another. I think it should be possible to do it as an animation made on the object shader itself, a little bit like the foam is done on the water.

    - the shader package. Yes the tiles are not perfectly aligned from a certain angle, when you go from one LOD to another because the 2 adjacent tiles does not have the same number of polys... The solution is to 'move the Ocean to follow the player so the player is seeing only the highest poly, in the middle of the Ocean. But to do that, you must also change the Gaussian random generator, because if you move the ocean like this you will have to jump the player from one tile to another and the tiles must all be identical or the jump will be noticable.

    - the reflection of the sun is very simple :
    add this in the properties :
    Code (csharp):
    1.         _SunPosition ("Sun Position", Vector) = (1, 1, 1,1)
    2.         _SunPower ("Sun Intensity", Range (0,2)) = 0.25
    3.  
    This in the vertex part :
    Code (csharp):
    1.     o.lightDir = mul(rotation, -_SunPosition);
    This in the fag part

    Code (csharp):
    1.     float3 halfVec = normalize(normViewDir - normalize(i.lightDir));
    2.     float sun = pow(max(dot(halfVec, tangentNormal ), 0.2), 200.0)*_SunPower;
    3.  
    ...and this at the end of the shader to add the sun.

    Code (csharp):
    1.     result.rgb = result.rgb + sun;
     
  27. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    It happens on both my Macs, one is a Intel Core Duo iMac and the other is an Intel Core Duo 2 MBP. Both are running OS X 10.4.11. Happens with both FireFox and Safari.
     
  28. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    I just tried it on my Windows machine (Dell Vostro notebook) and it works fine. I'm guessing it might be an issue related to my OS?
     
  29. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    The camera far clip plane settings are at 800000 (because I move along the ocean and I don't want the sun to move in the sky)

    I think it is the problem... but because MAC and PC uses the same video cards generally, I will make some test and if confirmed I'll open a ticket and submit that as a bug.
     
  30. MrBodean

    MrBodean

    Joined:
    Jan 25, 2008
    Posts:
    103
    I see the same skybox issue as bigkahuna but instead of white or black, I see triangles of the skybox offset. When I look up, its like I am seeing through fly eyes, when its broken up in pieces but still see skybox.

    Very strange, never seen something like this before. This is on Mac, have not tried on PC
     
  31. ToreTank

    ToreTank

    Joined:
    Jun 23, 2008
    Posts:
    165
    I had similar problems like that (the skybox got clipped), and if I remember correctly, it was caused by me not explicitly resetting the camera transform.position and transform.rotation, I only "reset" the worldToCamMatrix before the renderpass in question (used one camera for several passes with different positions). After (re)setting position and rotation as well, the problem disappeared. Don't think I ever tried it on Windows before I got it fixed on Mac, so not sure if it was a problem there as well.
     
  32. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    Sorry, I've been too busy lately to package the Ocean. I just need to zip and check...

    Here is a little picture of what it will be.
    Check back sometime this week-end...
     

    Attached Files:

  33. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    :eek: :eek: :eek: WOW! AWESOME! :eek: :eek: :eek: (Even your sun in the sunset shot is beautiful!!)
     
  34. norby

    norby

    Joined:
    Jul 10, 2006
    Posts:
    277
    Can't wait to play with it :p

    Norby
     
  35. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    Here is the project file, make sure to read the readme if you have any problems.
    Note to the Unity Web team I can't attach the 4.5 MB zip I get : "Tried to upload empty file"

    So I've uploaded it to my blog here http://www.nikko3d.com, section Downloads.

    Feel free to download it.
     
  36. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    Hi Nikko,

    The ocean shader looks amazing. I did, however, run into some issues:

    1. This project must be used with Unity version 2.5+, it won't work with 2.1 because you used Material.renderQueue in Ocean.js and it isn't supported in 2.1 (at least I got an error when trying to run it in 2.1 so I ran it in 2.5 and the error went away).

    2. I got a few warnings when I loaded the package file into a new project, a screenshot of the list is attached.

    3. The ocean shader didn't appear when I ran the "Ocean" scene, but it did work with the "Ocean V3" scene.

    4. I got some very weird smearing of the skybox when using the mouse look. A few screenshots of the problem are attached. I'm using an iMac Intel Core Duo with 128 MB ATI graphics board.
     

    Attached Files:

  37. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    hum... try to change the camera far clip plane (I forgot to check that on MAC) as it seems to create some trouble here. Let me know which value works for you and if it is the solution of the problem (should be less than 800000 but more like 50000 or so.

    About 2.5, yes, you must have 2.5 to run the project.

    About the warnings well, yes I know, but it is just unused variable, not a big deal, will fix that later. I'm more concern by the skybox. It is working fine on PC though. I'll check on my Macbook tonight.
     
  38. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    1. Yes, changing the far clipping distance does fix the skybox problem, but it needs to be greater than 150,000 or the sun won't appear.

    2. When running "Ocean Scene V3" I'm also getting this error:
    Can't add component 'MeshRenderer' to Ocean because such a component is already added to the game object!
    UnityEngine.GameObject:AddComponent(String)
    UnityEngine.GameObject:AddComponent(String)
    UnityEngine.GameObject:AddComponent(Type)
    Ocean:SetupOffscreenRendering() (at Assets/Ocean_v3/Ocean.js:412)
    Ocean:Start() (at Assets/Ocean_v3/Ocean.js:147)

    [/Users/build/builds/unity-branches-2.5.x/unity-2.5.x/Projects/../Runtime/Mono/MonoExportUtility.cpp line 601]

    3. I also changed the initial camera Y value to 40 otherwise the scene starts below the surface of the water and only displays the water after you click on the mouse.

    4. I haven't investigated why "Ocean Scene" doesn't work yet, is it supposed to?
     
  39. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    1- thanks, will change that and update the package to v3.1
    2- you should not have this error. Double check that all the textures and scripts have been assigned in your project.
    3- yes you are right, will change the camera in the distrib for the next update.
    4- Ocean Scene is not supposed to work, it should not be included in this project, it is another version, and things are missing in the distrib so it can't work.
     
  40. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    Ok, I looked for missing values:

    1. The "Plane" object was missing a material so I gave it the "Ocean Plane" material.

    2. The "Ocean" object script was missing an "underwater_material" value.

    I tried throwing something in both of these and it didn't change things. Is it possible your script is adding a second mesh renderer?
     
  41. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    I've updated with v3.1.
     
  42. Yann

    Yann

    Joined:
    Oct 20, 2007
    Posts:
    432
    OMG ! :D :D :D

    Nikko, thanks so much. Should be added in your readme that the "CameraHelper" script must be present, and not only the FFT plugins. But as soon as it works... WOW !

    One question : how does the "boyancy" script function now ? I can't get it to recognize any "Ocean" object.
     
  43. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    I tried the new version and got these errors (below):

    Edit: I fixed it by importing your original package and then your new package on top of it. I also fixed the "mesh renderer" error by commenting out line 412 in Ocean.js:

    Code (csharp):
    1. //  gameObject.AddComponent(MeshRenderer);
     

    Attached Files:

  44. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    I don't know if you mentioned this already, but this project requires a number of Unity Pro only assets. Now that I've got it working properly, it is absolutely breath taking. Easily the best ocean water example I've ever seen! :D

    Edit: It seems that the ocean mesh is generated based on the rotation of the main camera. I tried resetting the main camera to the same rotation as the start of the mouse look script and I noticed that the ocean swells became very sinusoidal in shape versus the more random shape it was initially. I tried changing the initial rotation of the camera to different positions and it seemed to have a direct effect on the shape of the ocean waves. Is that intentional?
     
  45. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    I also tried using the buoyancy script without success. How is it supposed to be set up?
     
  46. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    It is because the 'plugins' directory is missing with the FFT scripts.
    I can remember adding these in the proejcts...
    Just in case I've made a v3.2 that has these scripts for sure.
    Please try from a clean install:
    - install Unity 2.5 in a new directory
    - run the island demo
    - import the Ocean 3.2 package. It should work
     
  47. Matroblend

    Matroblend

    Joined:
    Jan 30, 2009
    Posts:
    134
    Very very good....

    Makes me want to go surfing...

    Anyway Thank you, it the best ocean ever can't want to use it with my Island.
     
  48. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    The file your website links to is "Ocean_V31.zip" is that correct or does the link need to be updated?
     
  49. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    hum try again; I had to upload it but was interrupted by a long phone call sorry...

    Boyancy
    1- add mesh collider to your object
    2- add the boyancy script to this object
    3- select the ocean as collision mesh in the boyancy script parameters
    4- add rigid body to your object
    5- check the gravity button in your mesh rigidbody settings
    6- set its mass
    run
     
  50. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    Ok I'll add this to the read me...