Search Unity

Submerged vessels... displacing water?

Discussion in 'Editor & General Support' started by antenna-tree, May 25, 2006.

  1. antenna-tree

    antenna-tree

    Joined:
    Oct 30, 2005
    Posts:
    5,324
    I'm cooking up a scene where a character uses an umbrella as a floatation device. The probolem is the water plane shows through the umbrella and of course completely ruins the illusion of the umbrella properly submerged in the water. I can't think of anyhting to solve this problem and I'd love to hear any creative solutions. Attached pic shows what I mean.

    Thanks
     
  2. jeremyace

    jeremyace

    Joined:
    Oct 12, 2005
    Posts:
    1,661
    Depending what angles the umbrella is viewed from, could you just use layers? Put the umbrella in a higher layer?

    -Jeremy
     
  3. antenna-tree

    antenna-tree

    Joined:
    Oct 30, 2005
    Posts:
    5,324
    No, I want it to look submerged. With two layers it would always be in front and look like it was on top of the water plane. I was thinking maybe a texture/plane that becomes enabled once the umbrella hits the water plane. The texture/plane would be a flat representation of the part of the umbrella that is "underwater". But there's also the character riding this umbrella that needs to look like he's sitting in it. Aargh, this is just like Bill's radar system of doing realtime booleans cutting off pieces of ships entering the radar sphere... I don't know if it's possible.
     
  4. jeremyace

    jeremyace

    Joined:
    Oct 12, 2005
    Posts:
    1,661
    Damn...tricky one. I doubt that it is possible as you want it without mesh access of some sort or something similar like the booleans. Good luck man.

    -Jeremy
     
  5. antenna-tree

    antenna-tree

    Joined:
    Oct 30, 2005
    Posts:
    5,324
    Darn, my umbrella wielding super hero might not have floatation abilities after all :wink:

    I'll keep experimenting with it, thanks Jeremy.
     
  6. jeremyace

    jeremyace

    Joined:
    Oct 12, 2005
    Posts:
    1,661
    One more hack idea, if you just need to view your character in 3rd person, you might be able to get away with having a bone linked to the point of the umbrella or an animation so when it is "submerged" you squash the top of the umbrella to flatten it out. Depending how your character sits in it you might be able to get away with it to a small extent.

    I really like the idea of an umbrella ad a flotation device btw. Pretty cool.

    -Jeremy
     
  7. antenna-tree

    antenna-tree

    Joined:
    Oct 30, 2005
    Posts:
    5,324
    Hmmm, how about flattening out the inside top of the umbrella and parallax/normal mapping it so it still has the illusion of shadow depth below that point? That could work tweaking the textures just right! The character could sit on that and look pretty good if in the right pose. Cool, thanks again man.
     
  8. jeremyace

    jeremyace

    Joined:
    Oct 12, 2005
    Posts:
    1,661
    You could also normal map the inside "ribs" of the umbrella to help with the illusion.

    I hope it works out for you man.

    -Jeremy
     
  9. BadMonkey

    BadMonkey

    Joined:
    Oct 15, 2005
    Posts:
    55
    If I understand what you want correctly, would it be practical in your situation to cut out a shape in the water mesh for the umbrella to sit in and move that mesh with umbrella ?
     
  10. marty

    marty

    Joined:
    Apr 27, 2005
    Posts:
    1,170
    Here's an idea, stated prosaically:

    Use render-to-texture to draw a solid circle the size of the umbrella's circumference at the section where it intersects the water plane at the appropriate location on the water plane.

    Then, use this solid circle as an opacity map to create a see-through section in the water plane.
     
  11. greenland

    greenland

    Joined:
    Oct 22, 2005
    Posts:
    205
    If you did that the textures would need to stay in the same place while the mesh moved. Shaders do that, right? :D
     
  12. Sync1B

    Sync1B

    Joined:
    Sep 13, 2005
    Posts:
    561
    You _can_ do it with a vertex shader. I had a similar thing with my 3D map, while not solved (don't have a good enough gfx card) it is possible to cull geometry in a shader. Irregular shapes are hard obviously, but a sphere is doable. Look at my last post in my sphere map thread. That code came from one of Neil's friends, all it does it cull any thing in the radius of the sphere. It will require Cg, but it's possible since a umbrella is basically a piece of a sphere. Hope that sort of helps.

    Bill
     
  13. marty

    marty

    Joined:
    Apr 27, 2005
    Posts:
    1,170
    Heya, Bill. So, what exactly does this cool-looking shader do? Do you havce an example movie? I'm always keen to enjoy some of your awesome shader-work!
     
  14. Sync1B

    Sync1B

    Joined:
    Sep 13, 2005
    Posts:
    561
    Well it would need to be written in Cg which I really haven't got into since by gfx card is not up to par. Give me a few months when I get my macBook pro and I will have a demo. :D I was just saying it could be done.
     
  15. Lallander

    Lallander

    Joined:
    Apr 23, 2006
    Posts:
    429
    Step right up one and all, pitch in your spare change to the "Buy Sync1B a Macbook for the betterment of the Unity Shader Library. Thats right for a small donation you will be doing your part to improve the developer community.
     
  16. Sync1B

    Sync1B

    Joined:
    Sep 13, 2005
    Posts:
    561
    I just thought of a crazy idea, maybe you could modify a projector to project alpha. It would take some fine tuning of the projector placement, but it might work? I will look into that, Aras, what do you think?

    lol, love it lallander.

    Bill
     
  17. marty

    marty

    Joined:
    Apr 27, 2005
    Posts:
    1,170
    He is truly a god amongst shadersmiths.
     
  18. Sync1B

    Sync1B

    Joined:
    Sep 13, 2005
    Posts:
    561
    Ok you have gone to far. lol
     
  19. Bampf

    Bampf

    Joined:
    Oct 21, 2005
    Posts:
    369
    Another cheat that occurs to me is that you could put a flat polygon at the water level inside the umbrella and texture map it with a picture of the inside of the umbrella (already suggested.) But that picture could be a visually correct picture generated on-the-fly with a second camera, using render-to-texture. So the lighting, hero's feet etc would look correct, theoretically.
     
  20. NCarter

    NCarter

    Joined:
    Sep 3, 2005
    Posts:
    686
    This is possible. I know someone who managed to get a boat to float in water without water appearing inside the boat, but he did it using OpenGL directly in a program he wrote himself. I believe the trick is to use the depth (Z) buffer to prevent the water from being drawn on the inside of the boat, presumably by drawing an invisible, depth-writing plane across the top of the boat's hull.

    Unfortunately, this is drawing-order dependent... you'd need to draw the boat first, then the invisible plane, then the water. I don't know if it's possible to get Unity to do this. You might at least be able to put the water into the transparent objects queue (using a shader) so that it gets drawn later.

    Anyway, just some ideas to get you thinking....
     
  21. freyr

    freyr

    Joined:
    Apr 7, 2005
    Posts:
    1,148
    How about just using two cameras with the topmost camera clearing z-buffer only.

    The bottombost camera should render the water and the topmost the boat.

    Edit: On second thought, this would also make the outer side of the boat be drawn on top of the water... dang...
     
  22. NCarter

    NCarter

    Joined:
    Sep 3, 2005
    Posts:
    686
    I forgot about using multiple cameras to force the rendering order! In that case, it's definitely possible to do this. Maybe I'll put together a test piece tonight to see if I can make it work.

    If anyone else wants to give it a go, try using three synchronised cameras like this:

    • The first draws the boat (or umbrella) and all other normal objects.
    • The second draws an invisible polygon across the top of the hull (use a totally transparent alpha blended material or make a custom depth-writing but not colour-writing shader).
    • The third draws the water (which must respect the depth buffer).
    I have a feeling that it might also be necessary to artificially push the invisible shape up the depth buffer using DepthOffset in a custom shader.
     
  23. antenna-tree

    antenna-tree

    Joined:
    Oct 30, 2005
    Posts:
    5,324
    Thanks all for doing a little head scratching on this problem. I've been trying a lot of different combinations (camera order, depth only, don't clear, ZWrite, ZTest, etc...) of Neil's suggestion and am getting closer. The problem is even though you write a depthbuffered plane into the proper place, and layer, it still gets drawn over unless it's opaque. I think this will require a custom shader.

    This would be possible with a stencil buffer right? I know they're commonly used for realtime shadows, but couldn't they also be used to block out the drawing of certain geometry?
     
  24. NCarter

    NCarter

    Joined:
    Sep 3, 2005
    Posts:
    686
    Here's my attempt. The attached file is a Unity project which uses the technique I described above to render a hollow, half-immersed object using three cameras.

    I knocked together a stupid shader to handle the transparent hull cover. There might be more optimal ways of doing it, but this seems to do the trick.

    Incidentally, one side effect of this technique is that it looks wrong in the editor (because only one camera is in effect there), but it looks right in the game view. You need to run the game to see it working.
     
  25. Sync1B

    Sync1B

    Joined:
    Sep 13, 2005
    Posts:
    561
    Very clever Neil. Works great, and it was done with no extra special shaders. The bobbing script was a nice touch. :)

    Bill
     
  26. antenna-tree

    antenna-tree

    Joined:
    Oct 30, 2005
    Posts:
    5,324
    Well I'll be damnned, thanks a bunch Neil! That's perfect! Is it the "ColorMask A" line in the shader that does the magic here? This is really cool, now to cook up other uses for this technique.

    Thanks Again!
     
  27. NCarter

    NCarter

    Joined:
    Sep 3, 2005
    Posts:
    686
    Yeah. It means 'only draw the alpha channel, not the RGB colour channels', which results in nothing visible being drawn. Ideally, I would have told it to ignore the alpha channel as well, but it doesn't seem to be possible to say anything like 'ColorMask None'.

    Here's an even more minimal version of the shader:

    Code (csharp):
    1. Shader "HullCover"
    2. {
    3.     SubShader
    4.     {
    5.         Lighting Off
    6.         ZTest LEqual
    7.         ZWrite On
    8.         ColorMask A
    9.         Pass {}
    10.     }
    11. }
    You actually don't need anything in the Pass block! :D
     
  28. NCarter

    NCarter

    Joined:
    Sep 3, 2005
    Posts:
    686
    The shader and example project are now on the wiki. I renamed the shader from HullCover to DepthMask to make it clearer what it does. Thanks to Sora for helping me to make a version of the project which works properly for everyone!