Search Unity

Question Water shader with Flat edges

Discussion in 'Shader Graph' started by Ibrahimsadoq, Nov 7, 2020.

  1. Ibrahimsadoq

    Ibrahimsadoq

    Joined:
    Feb 5, 2018
    Posts:
    6
    Hello I'm working on a mobile game where water is a must can you help me achieve a water foam with flat edges instead of the depth based one?
    I want the foam to surround the intersected object in all directions on the water surface!
    any help is important!
     

    Attached Files:

  2. Olmi

    Olmi

    Joined:
    Nov 29, 2012
    Posts:
    1,553
    You probably can't produce this effect with pure Shader Graph, unless you execute some code in a custom function node.

    Here's a concept idea. You need to measure the distance from your object to the current texel being rendered (world position.) In case of a sphere this is trivial, but for complex shapes you would most likely need some sort of distance field, which you have generated. Or use some compromise proxy shapes which would be easier to test. And you would need to somehow pass in the data to your graph for every object in the water.

    Then you would use the distance gradient from the surface of the object to where the foam ends to generate your foam look etc.

    Here's a quick test, I made it in Shader Graph. The foam follows the object when it's moving in the water.

    20201108_water_foam.PNG
     
    Ibrahimsadoq and florianBrn like this.
  3. Ibrahimsadoq

    Ibrahimsadoq

    Joined:
    Feb 5, 2018
    Posts:
    6
    thank you men for your help, I really appreciate your feedback.
    I am just starting out with shader graphs and I really struggle a lot to understand the basic stuff, but what you said is far from my understanding, can you if you don't mind upload the shader you made or a picture of it so I can get a starting point to build for rounded and complex shapes.
    and can you tell me where should i look to lean and build a solide foundation for making shaders!
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,336
    The short version is this isn't something you can do with Shader Graph alone. You're doing a depth comparison between the pixel of water being rendered and the closest opaque object visible in that same pixel. It's not checking for anything outside of that single pixel, so a pixel where the opaque object behind it is far away won't show the foam.
    Technically you can check some number of pixels nearby, like screen space ambient occlusion does. But that's extremely expensive and/or requires some kind of blurring pass to actually be useful. And even then the effect falls on the edges of the screen or with objects that aren't totally in view. Just like the problems SSAO has.
    Ideally you'd want some kind of distance field representation of the world you could test against, but that's not a feature Unity has built in, as it's expensive to generate in real time.
    The usually solution is to hand paint the foam where you want it for anything static, and for dynamic objects make due with the cheap screen space technique you're using. Alternatively have a foam render texture you render stuff into dynamically and read from. Or use some limited number of analytical or prebaked 3D texture based SDFs of the shapes you want to compare against.
    Again, 99% of that work is entirely outside of Shader Graph.
    @Olmi 's suggestion is basically to pass a position and radius to the shader as a property and compare the distance from that point to the water surface to see if it's within some range and draw foam there, which is equivalent to a sphere SDF.
     
    Olmi likes this.