Search Unity

Water with procedural "shoreline"-function. Hard?

Discussion in 'Shaders' started by Foxxis, Aug 14, 2007.

  1. Foxxis

    Foxxis

    Joined:
    Jun 27, 2006
    Posts:
    1,108
    Hi,

    I've practically zero experience with shader programming, but I suspect I could speed up my game a bit by developing a special shader. At least I guess older cards would benefit.

    The case is this: I have some water in the game, and I use the standard (non-Pro) watershader with the transparency modification. I wanted the transparent water since I have an island, and I want a shoreline effect. Not just a straight intersection between land/water, but the effect of the island fading out under water. I've accomplished this, and it looks good.

    However, I suspect I'm wasting a lot of performance by rendering the water as transparent when all I want is the color shift in the water that you see around tropical islands. I guess I could do that far more efficiently with a procedural shader that takes the distance to land into account?

    So, a few questions:

    1) Is it possible to do the equivalent to a proximity-shader in Unity? One that looks at land polygons and sets the water color based on the combined distance? It would only have to do this very infrequently - possibly only at game start.

    2) Is it hard?

    3) Do you agree that it would be more efficient than using transparent water?

    I would very much appreciate your thoughts on the subject, and if you have a link - or even sample code - I'll be ecstatic! :)

    Thanks,
    Dan
     
  2. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    Doing that as a shader - no, not really. Doing that as a script that computes all the data that some shader can then eventually use - sure. Read on.

    Shaders are pretty isolated and simple things. It's best to imagine them as this:

    * Vertex shaders operate on a single vertex at a time. They don't even know which triangle they are operating now; and certainly don't know the distances to some other scene elements. Data for a single vertex comes in (and nothing more), and some data for the same vertex comes out.

    * Same with pixel shaders - they operate on a single pixel on the screen. They get some data in (most often texture coordinates and some colors), and they compute the final color. They know nothing about the neighboring pixels, or surfaces, or anything like that.

    Now, back to your water question: I'd imagine the easiest way to change the colors based on water depth is to actually store them in the vertices of the mesh. So at game startup you'd go through all vertices of the water mesh, raycast down (or whatever other method you choose) to determine water depth, and store the wanted color (or depth, or whatever you want) in the colors of the mesh. Then the shader could use that vertex color to do something.

    A different approach could be: just use same old water with no alterations. Then manually (or automatically) place "shoreline" polygons near water edges; possibly with a different texture that scrolls towards the land.
     
  3. Foxxis

    Foxxis

    Joined:
    Jun 27, 2006
    Posts:
    1,108
    Many thanks for the info! Makes absolute sense. :)

    Now for the inevitable follow-up: is there any examples floating around out there that showcase interaction between a shader and an object (as in grabbing the vertex colors for example)?

    Again, thanks for the help!
     
  4. drJones

    drJones

    Joined:
    Oct 19, 2005
    Posts:
    1,351
  5. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    Most Shaders in Unity don't actually use vertex colors; what they grab from the vertices are positions, normals, UVs and tangents.

    Grabbing vertex colors is simply adding something like "float4 color;" to the vertex shader input structure. If you take a look at built-in shaders, you see that they most often use appdata_base or appdata_tan input structures (defined in UnityCG.cginc). You're free to write your own input structure that also includes vertex color, and then just use that in the vertex shader.
     
  6. Foxxis

    Foxxis

    Joined:
    Jun 27, 2006
    Posts:
    1,108
    I know - but I couldn't find one simple enough to get my head around in the limited time I have to focus on the problem. My current method isn't that bad, but I guess a new approach could make it look a bit better while at the same time performing better on low-end hardware.

    Please point me in the right direction if you know of a specific shader that's simple enough for a shader-newbie like myself. :)
     
  7. Foxxis

    Foxxis

    Joined:
    Jun 27, 2006
    Posts:
    1,108
    Sounds simple enough. I'll have to experiment with this and see if I manage to break Unity in my pathetic attempts at shader-programming. ;)

    Thanks for the help so far everyone!