Stylised shoreline effect

I’m working on a project with a stylised art style. We’ve managed to establish most of the content areas.

I’m tasked with coming up with a water effect which automatically handles the shoreline in a similar way to what can be seen in Rime:

I’ve tried DepthFade, and as anyone who has played around with it knows, this doesn’t create the desired effect, as it does not render correctly on the surface of the water plane mesh.
I’ve tried DistanceFields, and for the most part (static meshes) it works perfectly, however Landscapes don’t seem to generate fields, so It’ll only work around meshes.

To illustrate what I’m trying to achieve:

http://ss.myth.ro/t/Z542q.png

  • A white band along the point at which the water plane and landscape/mesh collide (Shoreline)
  • A white band which starts at a distance from the coastline, but closes in on the Shoreline (and fades in as it does so)
  • Change the color of the water based on the distance between the water plane and the landscape/mesh beneath it.

As I say, I’ve managed to create this effect using Distance fields on meshes, but landscapes don’t generate these, so I’ve been unable to create something similar. Distance fields would also not work in really shallow waters, as the distance from the water plane and the terrain underneath would create the effect, rather than just the collision point (the shoreline).

I’ve exhausted my understanding of the engine, but know it’s possible (at least visually) through Rime (which is running on UE4). Does anyone know if their effect is manually placed, or whether it can be automated in the way I have described?

Thanks

I’d like to know too how to achieve this (or any shoreline for that matter) effect.

If you water is tesselated you can use vertex colors. You could also use texture. Hand drawn or some kind of topdown projection of depth that is then masked to contain only interesting parts.

depth fade is actually the way to go. when you say ‘it doesn’t lie on the surface of the mesh’ you are probably talking about the lack of perspective correction. You can adjust this yourself by dividing by cameravector dot vertex normal with some alpha control.

Depth fade can’t produce shoreline if there isn’t something close to that pixel. It almost work but for Rime or Zelda kind of waves you definitely need something more thicker and reliable. For last game I worked I actually used previous frame SSAO as info that something is close to that surface pixel.(fully opaque water). This somewhat worked but it was really unreliable too.

So you don’t have any terrain or geometry under the water? as long as you have a gradual slope under the water it should be enough.

RyanB: I figured that if it was possible to render the DepthFade as though the camera was directly above at all times, it would look perfect. I’ll play around with your suggestion!

Thanks

If you capture basically a heightmap or draw out a simple depth gradient you can look it up mapped to world coordinates and do it that way. It will certainly make the effect more stable.

The problem is you cant just find the floor below in Z without some kind of ray tracing method.

What would be the cheapest solution for mobile ?

The one that works and uses the fewest texture samples and instructions and meets your quality goals.

I don’t suppose there is any way to get a landscapes heightmap within a material? I’ve actually been toying with the idea of simply exporting the heightmap and importing, finding ocean level and going from there. I’m just reluctant to do it as it has a manual process attached.

Trying the DepthFade approach, it seems to still suffer from the camera angle effecting the output:

http://ss.myth.ro/t/IW90i.png

http://ss.myth.ro/t/XE72h.png

http://ss.myth.ro/t/eS15Z.png

Not sure if I’m missing something really obvious here. It’s getting late and I’ve been banging my head against this for most of today!

Thanks again.

hmm actually I think I gave you bad instructions there.

instead, try setting a value for your ‘Fade Distance’ using scalar param, and divide that by your dot product.

And you may need to adjust the dot product by lerping it down or clamping it since it most likely wont’ need the full correction for most depths. If you know the depth at which the bottom of the ocean flattens out you can limit the error to that depth.

Ahh, thats more like it. It’s not displaying the edge no matter what angle you’re looking at it, however I’m still fighting with the fact that it appears to display under the surface, rather than flat on the surface (creating the effect seen here):

http://ss.myth.ro/t/TI191.png

I believe this is a limitation of DepthFade? It’s passable, but as soon as you look at it from a particular angle the illusion is lost.

Could you explain a bit how that worked?

Does that mean that I must have slopes, and could not use it as in the example below on a cylinder in water? I’d like it to be a bit more like the white lines in the right example.

in the example on the right, the depth fade approach would only give you a gradient along the depth intersection, which means it would outline the shape of the cylinder under the water. It would not extend nicely out from the silhouette like you probably want. But if the slope under the water is gradual, so will be the depth fade. In the past I have used extremely low poly ‘bulge’ shaped meshes and placed them under the shore for make this look better.

f1ec0f5dab1ce40ac149f1bba57b8ea0fe761ee9.jpeg

And I have also gone with the second imported heightmap approach. it is a pain since you have to keep it syncronized with your landscape changes and you also have to manually set up the world extents. But its not too hard, in fact there was a material function released with the Kite demo for exactly that purpose.

Thank you, very helpful tips. I guess heightmap makes most sense if the players are allowed to go into the water, bulging geometry might look weird.

Sloped low poly corners can also cause this since it just, as you said, outlines the underlying geometry. I guess making them smoother solves that somewhat (or using the heightmap method)

Okay, So I’m going to opt for a combined approach for this. I’ll be using DistanceFields for all static mesh interaction with the water plane, and the landscape heightmap will handle interaction with the landscape.

I’m not sure of the limitations of the engine here (on materials and landscapes), but something I would absolutely love to see in future is Landscapes adding to distance fields (and/or) the ability to grab the landscape heightmap from within a material. I feel this would open up some really interesting interactions going forward.

Thanks again for the help! Once I get the DistanceField approach set up I should be able to post my workings here for you @Gmi

I am glad you found something to try. Let us know if you need any help setting it up.

I agree it would be great to be able to read that information in a material without having a second texture. It comes up frequently among internal artists as well. I think the only thing stopping it, is that it would be hard to check in a partial solution for this, such as one that works with only one heightmap. So the person who writes this feature probably has to handle it working with multiple landscapes and streaming etc so it probably ends up being a lot harder than it sounds at first glance.

Converting landscapes to distance fields also gets requested. I do not believe that feature would be quite as complicated (I have done similar code) but it may be quite slow to generate DF for large landscapes.

For kite demo we briefly had talked about doing it so the landscape could composite into the distance fields and use the ray traced distance field shadows. Instead we ended up with a different feature that fit the performance needs more, a further cascaded shadow region called the FAR shadow that meshes had to set “affect far shadow” to true to affect, and we just had landscape also affect that pass.

How far shadow exactly differ from normal cascades? Is the only thing that differ the boolean toggle? Is those updated every frame?

Thanks @Skulburn, I’m really interested in how it works.

I’m still wondering about height-map usage. In my case I’m not using landscape, but imported geometry and I have multiple islands, each being a seperate mesh and some are even floating (not connected to the underwater-ground).

Would the best method be to combine the islands in an external editor, create a heightmap of the whole scene and use that as some kind of a mask on my ocean plane?