Search Unity

Shader that detects other mesh

Discussion in 'Shaders' started by vegenarie, Aug 21, 2015.

  1. vegenarie

    vegenarie

    Joined:
    Jan 5, 2011
    Posts:
    287
    I want that a mesh like a water plane detects the distance to every vertex of another mesh, like could be a shoreline for instance, that can be done?
     
  2. jistyles

    jistyles

    Joined:
    Nov 6, 2013
    Posts:
    34
    tl;dr version: unfortunately can't be done like that.

    Long version: That can't be done with a shader - in general, think of a shader as only capable of operating on 1 vertex or pixel at a time (depending on if you're in a pixel or a vertex shader!) It has no knowledge of any other vertex/pixel in its own mesh, let alone another mesh. There's a few small rule breakers (eg, ddx/ddy in a way looks at a neighboring pixel), but in general this is pretty absolute.

    What is usually done for your example of a shoreline for instance, is to take a copy of the depth buffer to be read back as a texture, and that's used to figure out how far the current pixel is to the pixel drawn behind it. So if the water is visible and the pixel distance is getting really close we fade in a shoreline effect like some surface foam or the like. Alternatively, pre-baked or manually crafted data is used like vertex colours on the mesh to define where the shore is, or a heightmap is baked that represents the depth of the water at that position.
     
  3. vegenarie

    vegenarie

    Joined:
    Jan 5, 2011
    Posts:
    287
    Nice reply, thanks. I would like to make a monster with many tentacles and those tentacles had around a foam on water, no matter how deep is the water, as it could be in middle of the ocean, and one tentacle could be with S shape, part above the water, part at water level making foam and part under the water. The only way i see to do it is using particles
     
  4. vegenarie

    vegenarie

    Joined:
    Jan 5, 2011
    Posts:
    287
    I am reading about depth buffer and i see it is the distance from camera to an object but have no idea up to what object, what happens if an object is partially or fully transparent, the distance would be from camera to that object or until finds an object with full opacity? and this is just used to render something in the whole screen using graphics.blitz?

    And how could i get the distance from an partially transparent object A, like could be water, to another object B behind it like could be something under the water, as with depth buffer i just get the distance from camera to the most distant object
     
  5. jistyles

    jistyles

    Joined:
    Nov 6, 2013
    Posts:
    34
    So the depth buffer only records 1 depth value per pixel at a time; it's written to when a shader zwrites (Zwrite On), and things can trivially be rejected (hidden) when compared against it (ZTest function in a shader). This improves performance since those rejected pixels are generally not being computed.
    Big obvious limitation is transparents generally never write to the depth buffer because otherwise they would start hiding things which get rendered after them, but are physically behind them.

    Fast forward to the late 90's, when we get access to it as a texture. Boom! We can now read from it and compare depths, generate world positions, etc. Super handy for lots of effects.

    Quickly copy+pasting from a random shader of mine... so a transparent surface like water grabs its physical depth:

    vertex shader:
    o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    o.screenPos = ComputeScreenPos(o.pos);

    pixel shader:
    float fragDepth = i.screenPos.w;

    And also samples the depth buffer to see what's solid behind it:

    pixel shader:
    float sceneDepth = CalcSceneDepth(i.screenPos);

    From there you can tell how far away the thing that you're currently drawing is to the thing behind it. Have fun :)
     
    forestrf likes this.