Low poly water shader

Edit: I’ve added a link to a downloadable version of the shader! Copying the code from this post does crazy stuff to the symbols..

The side tracking specialist strikes again.

I’ve been working on another project lately and ended up in need of low poly flat shaded animated water.

I tried editing the mesh at runtime by script. Using the method mentioned by joni.giuro here: http://forum.unity3d.com/threads/low-poly-water-help.276685/

But when using the standard plane with this script, basically 200 triangles and when you’ve separeted all vertices (600), FPS drops down from 1500 without script to 190 with script applied. If you add more planes or models with more triangles you quickly get to a point where you get 1 FPS. So I needed something else.

That’s when I figured I’d try my luck with shaders.

Tried googling for solutions, but nothing was to be found so I needed to build my own. With no experience in shader programming this proved to be harder than I expected. But fast forward through some horrible looking results to today. Now I’ve gotten to a point where I can take any plane (not having to worry about splitting verts) applying my shader and getting this:

Almost no hit on FPS with fully animated low poly flat shaded water with specular color. And with this solution:

I can add looots of planes with this shader with almost no hit on FPS. Here I’ve added got 30 standard Unity planes with 200 tris each, all animating off into the distance.

Here’s a video of it in motion:

So how is this done, you say?

Code below.

It’s not perfect but it works! F.ex. I’ve left the UV coords in there but don’t need them for this. And I’m not entirely happy with the waves just yet.. But here you go.

Link to downloadable version

30 thoughts on “Low poly water shader”

  1. Awesome work, i’ve tried myself to get my hands on shader, but it relatively dark when you don’t know about it in the first place.

    Really impressed, keep up the good work.

    Any chance that you do a kind of tutorial or a step by step guide on how to program such a shader ? (for newbs like me :D)


    1. This is my first shader, so I am relatively new to this stuff myself! I do agree that shader-information on the web is a dark place. Really hard to find good tutorials or clear answers to anything. But I finally managed to make this. But it’s a bit early for me to make a tutorial, and I don’t really have the time either.. Already found errors and weird behavior on this shader, but will continue working on it and might come back with more!

      1. I can totally understand that it’s very time consuming to do such a thing as a tutorial. Thank you for the reply though. 🙂

        By the way, i tried to download this shader to play a bit with it on Unity, and it won’t compile because of this error:

        “shader is not supported on this gpu (none of subshaders/fallbacks are suitable)”

        Ever came across this error ? I’m still searching for an answer on the web, and i can’t quite understand the problem there.

        If i manage to fix it, i’ll share it here 🙂

        1. If you are on Mac or some other platform than Windows without DX11 capabilities it probably won’t work.. It’s quite limited as is.. Unity will support geometry shaders on other platforms down the road I believe!

  2. Nice work! I tried a lot of times now to develope a low poly water shader by my own but I always give it up with the normal calculation. Can’t get it to work.

    Your shader is working but I get an offset from the pivotpoint of the object. It doesn’t render at the place I put my object.

  3. Nice work! I tried a lot of times now to develope a low poly water shader by my own but I always give it up with the normal calculation. Can’t get it to work.

    Your shader is working but I get an offset from the pivotpoint of the object.

    1. I believe the offset is due to scaling, not sure. Haven’t had time to look more into this shader. It could be improved in many ways!

  4. This is great!
    That low poly water look is exactly what i would like to have in my current project.
    I tried to use your example but i soon realized it isn’t affected by fog.

    I found this answer regarding fog in vertex shaders:

    However, with my limited knowledge about shaders i can’t figure out how to pass the fog data through the geometry function in your shader, so i can use it in the fragment function like in the example.

    Is there an easy way to achieve this?

    1. Hi, Brian! I really like your idea! And I hope you’ll get it working! The reason for what you are experiencing is a bug in the vertex function of the old shader. I’ve fixed it in my current shader, but not in the one I’ve shared.. I would have to spend some time on it to fix it, and I haven’t had free time to look at it. It’s a rather simple fix. Just have to change the way I added the offset of the vertexes. I believe I set v.vertex = mul((float3x3)_World2Object, v0) or something like that in the shader you have, but what you want is v.vertex.y += mul((float3x3)_World2Object, v0).y .. kind of.. But if you don’t know your way around shaders you could simply make a bigger plane in Blender and use that to get a bigger wave.

  5. This is a really cool shader. Can I use it for a commercial product? (working on a game that may or may not be published at some point). And another thing – by any chance did you think of adding reflection and transparency to it?

    1. Thank you! Yes! You can use what I’ve shared any way you want! I’m okay with that! I’ve already made a new shader with reflection and transparency, but I’m not sharing at the moment!

          1. I’m not sure I know what you mean, but if you are trying to get an object to “follow” the motion of the waves, you would either need to make another shader that displace the boat with the same wave code, or duplicate the wave code in script..

    1. Yes.. This is because the collider does not change! You need to duplicate the wave formula in code to make the boat follow.

  6. Hello Ronnie, this shader is awesome and just what I need!
    Though I would like to make the water semi transparrent, anyway to add alpha to this?

      1. Hmmm, it looks pretty nice and supports alpha, but it says it only works on DirectX 11 capable hardware, I’m planning on exporting to WebGL, so I don’t know if everyone would be able to play it, and after a little messing with the low poly water scene that comes with the package, I got a display driver stopped responding error and unity crashed 🙁

        1. Yes, my old shader is quite limited.. I’m not sharing my newest version yet, and don’t have time to support the old one.. I’m sorry..

          1. It’s ok 🙂 I can live with the non transparent one, thanks for making this free 😀

          2. No problem! Hope it works out fine! But fyi the non transparent one is also DX11 only i think!

  7. for people using more recent version of Unity :
    you must replace
    void geom(triangle v2g IN[3], inout TriangleStream triStream)
    void geom(triangle v2g IN[3], inout TriangleStream triStream)

Leave a Reply

Your email address will not be published. Required fields are marked *