Search Unity

Reflecting surface

Discussion in 'Editor & General Support' started by Bampf, Jun 8, 2006.

  1. Bampf

    Bampf

    Joined:
    Oct 21, 2005
    Posts:
    369
    This evening I decided to play with making a reflecting surface. Conveniently enough, the surface is a a flat square at Y=0.

    I'd like to get a little help rather than muddle through. At the risk of looking foolish I will detail my two attempts and hopefully someone will have a tip about one or both of my approaches.

    1. My first attempt was to add a second camera underneath my scene pointing upwards, opposite my main camera. I render it to a texture, then put that texture onto a new plane object. I set the opacity to 50% (say) and put the plane at Y=0.01.

    So far so good but the image never aligns. The reflected objects aren't directly under the originals, and seem to be slightly warped. Camera placement issue? Aspect ratio issue? I got tired of fiddling and tried another approach.

    2. This is the "lazy programmer" approach. I created a water layer from the standard pro assets. It's got a nice reflection, ad the 2nd camera seems to be built in to the prefab. Now I remove bits I don't need until I have just the simple reflection, and hopefully by then I understand things better!

    I suppose I could keep go with a black box approach: keep the given shader and just set the bumpmaps to a uniform height, and otherwise fool the system into painting a flat reflection. But I'd rather go with a simpler shader if I can, particularly if there's a performance benefit.

    I've only just started this 2nd approach. It may work but I figured I'd post this message in the forum in the meantime.

    What are other people doing to pick up this topic? A hint or recommendation might save me a lot of time at this early stage!

    Thanks in advance,
    Matt
     
  2. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    First approach is almost correct, except that you need to project the resulting texture on the surface in screen-space; not just use surface's UVs.

    That is what water essentially does (and some more to do the waves, fresnel etc.). I'd say the second approach is the way to go. You might want to wait a tiny bit till Unity 1.5, which will contain cleaned up water shaders.
     
  3. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    Here's a quick mockup how a minimal reflection shader/setup could look like.

    • Import the unity package
    • Create your reflection plane geometry, set it's material to Reflective
    • Add a new Camera as a child of your reflection plane, set it's Target Texture to Reflections and attach ReflectionCameraSetup script.
    • Should work!

    This shader uses alpha channel of main texture to control "how reflective" the surface is. For better effect you might also want to include Fresnel effect similar to how Water shader does.

    Hope that helps.
     

    Attached Files:

  4. Bampf

    Bampf

    Joined:
    Oct 21, 2005
    Posts:
    369
    Thanks! I've been playing with it, not quite getting it to work yet.

    The rendering to texture appears to be working: if I inspect the Reflections texture in the package I can see the output of the camera there. And when I execute, the viewpoint of camera2 changes and becomes distorted, so it seems that the ReflectionCameraSetup script is finding the camera and adjusting it.

    The two problems now are:
    1) The image rendered onto the Reflections texture still seems to be wrong.
    The viewing angle looks like it might be right but the positioning is in the far corner of the plane instead of under the objects being reflected.

    (Hmm... I'm wondering if maybe the UV coords of the standard Unity-generated plane are somehow involved?)

    2) Nothing is drawn on the plane- the render texture isn't shown, though the environmental reflection is. If I change the shader on the plane from FX/Reflective Surface (which is what your custom shader names itself) to some other generic shader, say Alpha/Glossy, I can then see the render texture on the plane. (Though like I said, the shadow positioning isn't right.)

    (Mac OS X 10.4.6, ATi x800 256 M VRAM)

    Hopefully I'm just doing something wrong. Ideas?

    Thanks,
    Matt
     
  5. Bampf

    Bampf

    Joined:
    Oct 21, 2005
    Posts:
    369
    Poked at it a little more. Below is a picture illustrating the first problem. As you can see, in the inspector the Reflections rendered image looks correct- if it was centered on the plane the reflections would be right under their respective pawns.

    But instead it ends up being way off to one corner, at least with the standard alpha shaders. This is demonstrated in the Game View. (I tried using my own planar surface instead of Unity's plane object, and it was the same.

    I'm a bit mystified.
     

    Attached Files:

  6. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    Can you do a shot how the plane's material is set up? That looks strange...
     
  7. Bampf

    Bampf

    Joined:
    Oct 21, 2005
    Posts:
    369
    Sure thing. Here are two pics, one showing the plane's material setup as originally suggested, and the render texture isn't visible for some reason. The 2nd mage shows when I replace the shader with Alpha/Vertexlit, which makes the texture visible but then there's the offset problem.

    Thanks again for helping with this...
     

    Attached Files:

  8. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    Ahh... in the Reflective shader, the Main Color should be just a regular texture (e.g. your checkerboard). The alpha channel defines how much "reflective" surface would be at that point.

    The Environment Reflection would be the reflection render texture itself.
     
  9. Bampf

    Bampf

    Joined:
    Oct 21, 2005
    Posts:
    369
    Ohhhh, so that's it. I thought that was for the usual environment map for the background.

    It's working now. I don't want to make the main color my checkerboard, because each square of the board is a separate piece with it's own texture. But I'll just make a blank texture with an alpha channel for it.

    Thanks so much for the help!
     
  10. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    Then don't use any texture at all. The default will be pure white color.
     
  11. Bampf

    Bampf

    Joined:
    Oct 21, 2005
    Posts:
    369
    Good tip, but I do need the marble texture to show through. I was going to put the reflection plane on top and make it translucent instead. I'll play with it a little before deciding.
     
  12. Bampf

    Bampf

    Joined:
    Oct 21, 2005
    Posts:
    369
    As I'm sure you realized, I guess I can't make the plane translucent after all with this shader as-is. I'll either have to do as you suggested with the marble texture, or add an opacity setting (via a slider or another alpha channel) to the shader, or use the Pro water asset after all. But at least it's starting to make sense to me.
     
  13. Bampf

    Bampf

    Joined:
    Oct 21, 2005
    Posts:
    369
    Addendum: I changed my geometry so that I could use this shader. It's working well. I plan to alter the shader to turn off reflections if the player selects a low-quality graphics quality, but otherwise it's good to go I think.

    If anyone else tries this, make sure you position the child camera at 0,0,0 relative to the parent object (i.e. the reflecting surface.) It took me a while to realize that this is why the method was returning odd results. (Possibly something that could be fixed in the script, but I haven't looked into it.)

    Thanks again, Aras!