0
\$\begingroup\$

I can easily make a basic water shader, and create a script that detects when something touches the water, but does anyone know how I would actually trigger a ripple in shader graph? I'm not asking for full in-depth guide, I just need a basic idea. I have struggled to find videos that actually talk about collision based ripples. Also my game is 2.5d so you can see both the top and side of the water-I don't know if a normal map would work with that.

When I say 2.5d, its basically just 2D but using a perspective camera, so the water would look something like this just with a shader and different colors:

enter image description here

As you can see its like a cube but its more 2D than 3D, you only ever see the top and side.

Here is an idea of what I want:

enter image description here

It's basically 2D but you can see it's got some depth and it's quite realistic looking. It's also cut as if you're seeing it behind some glass. This is something I'm struggling to find online, as the water is viewed as if its inside a container. Making normal map methods fail.

The ripples should make the top of the water 'bob' when someone/something touches it, and there aren't likely to be more then 10 making splashes at a time, but really the system should be able to handle as many as possible.

\$\endgroup\$
0

2 Answers 2

1
\$\begingroup\$

If you need to scale up to a large number of interacting objects, then handling them one-by-one in the shader won't be efficient.

Instead, you can dynamically render ripples into a heightfield texture, then pass that texture to your water shader to apply conventional displacement.

Set up a layer in your project for this heightfield rendering. Make an orthographic camera that sees only this layer, and place it to look down at your water, framing its extents in the camera bounds. Set its clear colour to solid black, and have it render to a RenderTexture of your desired resolution. Higher resolutions are naturally more expensive, so start small and scale up only if the result looks too jagged. Use a floating point colour format so we can go negative (to get both valleys and hills)

When an object contacts the water (e.g. using OnTriggerEnter or Stay on a box collider aligned with the water's surface), spawn a ripple particle in that heightfield rendering layer. Animate the particle to expand and fade over time, and use an additive blending mode. This way, multiple ripples can overlap and constructively/destructively interfere, just like real water waves. This can handle scaling up to large numbers of particles.

For the particle content itself, you can either use a pre-made ripple texture, or use sinusoid math in the shader as agone suggests to shape each wave.

Now replace your water mesh with a densely subdivided plane. In its shader, sample the corresponding height from the heightfield and use that value to displace each vertex vertically. You can also get a partial difference from the heightfield and use that to tilt the surface normals to get correct shading even for small ripples.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks man, I really appreciate it. \$\endgroup\$
    – Pow
    Feb 19 at 0:06
1
\$\begingroup\$

Use the sin x, or cos x, function create simple waves.

For crests, use tan or 1/cos x or 1/sin x added to the waves.

The number of "splashes" is an array passed to the shader.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .