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
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.
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.
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
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.
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...
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.
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!
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.
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.
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!