Search Unity

Simulated projection in shader, UV coordinates issue?

Discussion in 'Shaders' started by Captaingerbear, Mar 5, 2019.

  1. Captaingerbear

    Captaingerbear

    Joined:
    Mar 6, 2013
    Posts:
    57
    So, I've written a pretty nice water shader that translates a white to black gradient into animated water foam. What I need to do next is to add a soft white halo around any actors or floating objects in the water.

    My first thought was to use some particles, capture them with an overhead camera, and then project the captured particles back down onto the surface of the water. I can do this using a projector easily enough, but in that case the projected halo does not translate into ripples the same way my shoreline does, and it makes the lighting inconsistent besides.

    What I would like to do is be able to get that projected texture back into the shader so I can add the results before the shoreline translation is performed, but I can't for the life of me figure out a way to do this to get the placements consistent.

    The camera that captures the particles is attached positionally to the water plane. I assign UV coordinates to each vertex of the water plane whenever it shifts in order to keep the texture's placement consistent, but I haven't done anything with other UV channels yet. I'm thinking I should be able to use uv2 to work this out, and it's entirely possible I'm missing something obvious, but it's just escaping me at the moment.

    Any suggestions welcome.



    Simple gradient mask in the water marks where foam/ripples should appear. This is where I need to work.
    upload_2019-3-5_13-28-15.png

    Shoreline gradient converted into foam/ripples.
    upload_2019-3-5_13-29-16.png

    Showing the macro structure of the scene setup.
    upload_2019-3-5_13-37-11.png

    Snapshot with particles and resulting effect visible; the effect just isn't lined up in the right place.
    upload_2019-3-5_13-37-53.png
     
  2. Captaingerbear

    Captaingerbear

    Joined:
    Mar 6, 2013
    Posts:
    57


    And naturally, I was over complicating it. I simply assigned a full-spread UV map in blender to the second channel, and then made sure my particle capture camera covered precisely the same area the UV map did. There's a lot of wasted space, but that can eventually be filled with tons of ripples from monsters, flotsam, etc.

    Particles rendering correctly on the shader gradient layer.
    upload_2019-3-5_15-22-52.png

    The final effect.
    upload_2019-3-5_15-28-46.png

    Now if anybody can suggest why the gradient from the depth fade is so gritty in comparison to everything else, I'm all ears. It appears to happen only at this distance, if I zoom in, it smooths out. If I view it in editor mode, it smooths out as well.
     
    bgolus likes this.
  3. sylon

    sylon

    Joined:
    Mar 5, 2017
    Posts:
    246
    Good idea.Might borrow some of that in the future :)
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    You may be at the precision limits of the depth texture. Try pushing your camera's near plane further away and see if that helps, or if your camera is orthographic pull in your far plane.
     
    Captaingerbear likes this.
  5. Captaingerbear

    Captaingerbear

    Joined:
    Mar 6, 2013
    Posts:
    57
    What do you know, that was precisely the issue, thanks!

    Everything looks nice and uniform now.
    upload_2019-3-6_14-14-48.png
     
    bgolus likes this.
  6. ErikSutton

    ErikSutton

    Joined:
    Apr 25, 2019
    Posts:
    6
    @Captaingerbear Would you mind sharing how you did the shoreline uvs? I'm assuming you're using the gradient in the depth texture for the U coordinate, but how did you calculate the V to be able to map a texture along the shore?
     
  7. Captaingerbear

    Captaingerbear

    Joined:
    Mar 6, 2013
    Posts:
    57
    Oh, terribly sorry, I somehow missed this question. It's been quite a while since I've done this effect and I was really flailing around blindly for much of it, but I'll try to explain what I did, even if I don't know why it works.

    ShaderGraph.png

    This is the relevant section of my shader graph. There are two variables that are calculated elsewhere, COMBINEDDEPTH and CLAMPEDGE, but they are not complicated.

    COMBINEDDEPTH is the gradient depth I showed above, with some soft moving noise added, so that the gradient texture wobbles gently instead of holding static. That's all.

    CLAMPEDGE is the gradient depth again, but inverted and remapped very tightly toward the shallowest depth, and I only use it to fade out the edge where the water meets the shore, so the textures don't clip too hard into each other.

    The magic part here is the LERP between the two Vectors. For some reason, using the Combined depth as a LERP value between (12,0) and (12,3) and plugging it into the offset of the UV channel gave me the result I wanted, but I'll be damned if I can mathematically explain why it works.

    I will say that this effect is axially mirrored; at two specific angles, the water foam mirrors itself and reverses. This might be obvious in something like a square pool, but around an irregular shoreline, it's nearly impossible to detect.

    Maybe someone more mathematically minded than I am can explain why this solution works.

    [Edited for a redundant sentence]
     
    ErikSutton likes this.