Profile picture
vulcanoid @dondragmer_
, 13 tweets, 8 min read Read on Twitter
doing another vfx thread about my student project, @wildbrewgame
this time i'm breaking down my water shader!
#gamedev #indiedev #shaders #madewithunity
the starting point for this one is just a scrolling foam texture over a solid color alpha blended over the background.
there are lots of good stylized water tutorials out there, like this one by @minionsart : so i'm just going focus on what's different
next step is to add foam around the edges. i use a slightly different method here than others i've seen because instead of using the raw depth, i calculate the world-space position of the ground and then compare the water's height to that. if they are within a threshold it's foam
the code for reconstructing world-space coords from the depth buffer is just copied from what unity uses internally for deferred lighting, but i'll show it for posterity. the idea is to get a ray to the far plane which goes through the fragment and then scale it by the depth.
i also use the depth below to control the water's color. i take two colors as material parameters and smoothstep between them until it reaches some max depth
next up is to add normal maps and cubemap reflections.
the shader takes two scrolling normal maps and blends them together in a way that better preserves detail than just learping or adding them.
the reflection is code is just copied from unity's standard shader
now that we have normal maps, lets add some refraction to the background.
we can get a texture with everything that has already been drawn to the screen using a grab pass: docs.unity3d.com/Manual/SL-Grab…
now we can sample from this texture using distorded uvs based on our normals
the refraction is a cheap and dirty effect that doesn't factor in the depth of the water. to get the uv offset, transform the normals into view-space to get them relative to the camera, and then transform them into projection-space to correct for the aspect ratio distortion
we also need to match the distortion when sampling the depth texture or the water color won't match up with what's behind it. the huge gotcha here is that the depth and grab textures can both be upside-down for different reasons so you need to account for both as shown:
now for the fun part, waves! i'm using a lot of tessellation and then moving the verts around with Gerstner waves. developer.nvidia.com/gpugems/GPUGem…
more detail in there, but basically these are sine waves that are pinched towards the peaks so you get some nice undulation on the surface
the last piece of the effect (and my favorite to work on) are some procedural ripples made using a render-texture bump map
i use the same top-down camera technique as in my grass shader so you can just read about it in that thread:
here i just have particles write the ripple height into the blue channel and then use that heightmap to deform the verts and normals of the water
and that's just about it for this water shader. i'm planning on revisiting this at some point and toying ray-marched refraction/volumetric lighting/more realistic fluid simulation, but for now, here's another video showing off the procedural ripples:
Missing some Tweet in this thread?
You can try to force a refresh.

Like this thread? Get email updates or save it to PDF!

Subscribe to vulcanoid
Profile picture

Get real-time email alerts when new unrolls are available from this author!

This content may be removed anytime!

Twitter may remove this content at anytime, convert it as a PDF, save and print for later use!

Try unrolling a thread yourself!

how to unroll video

1) Follow Thread Reader App on Twitter so you can easily mention us!

2) Go to a Twitter thread (series of Tweets by the same owner) and mention us with a keyword "unroll" @threadreaderapp unroll

You can practice here first or read more on our help page!

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just three indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member and get exclusive features!

Premium member ($3.00/month or $30.00/year)

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!