PDA

View Full Version : Mirrors



NecroDOME
30-08-2006, 10:05 PM
Hi there,

Well, to put it simply: I whant to create a mirror in D3D.

My idea:
Make a plane, put a camera in the oposite direction of the plane (and move it when the player moves) so it looks like a mirror. The plane has a a render target texture of the camera bihind the plane.

But what if I stand far away from the plane? the camera will render more than only what I need to see in the mirror...

So i don't think thats the way to do it :P

Anyone have any idea how to do it correct?

Relfos
31-08-2006, 04:00 PM
Hi, I'm my LEAF2 engine I've implemented mirrors. I use OpenGL, but you probably could do it in D3D.
This solution uses the stencil buffer, its the basic algoritm, I optimized it later with scissor clipping and other stuff.

1¬? Disable any render state not needed to speedup (smooth shading, lighting, etc) and disable depthbuffer writing with glDepthMask(GL_FALSE).

2¬? Setup stencil.
This will fill a mirror shape in the stencilbuffer with 1's
glStencilFunc(GL_ALWAYS,1,1);
glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);

3¬? Draw mirror quad, visible ou with color write disabled if you want.
It all depends of the type of mirror you need, transparent and such.

4¬? Reenable depthbuffer writing and setup stencil.
Only draw where stencil=1
glStencilFunc(GL_EQUAL,1,1);
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);

5¬? Now this is the part to remove any ghost object that may appear from behind.
This basically is used to clear the zbuffer, but only where stencil=1
glDepthFunc(GL_ALWAYS);
glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
//DrawFullScreenQuad here
glDepthFunc(GL_LESS);
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);

6¬? The last part is to render the reflected scene with faceculling reversed.
Here I used glClipPlane to removed other ghosts that may appear.
To reflect the scene I use a mirror matrix transformation, constructed from the mirror position and normal.

NecroDOME
01-09-2006, 10:13 AM
Well, I will give it a try...

Can it be done with a RenderTarget or is a stencil buffer better?
And what is the differece between a stencil buffer and render target?

I never done enything with stencilbuffers, but I think I can manage to make some :P

Relfos
01-09-2006, 06:40 PM
With a render target you're rendering to a texture, that you use later to draw the mirror surface.
With the stencil buffer, you're rendering directly to the scene, using the stencil buffer to mark the mirror shape.
The main difference is that with a render target you're limited to the texture resolution, and have to upload it, so it may be a little slower. However, you can skip some frames to cheat and gain some performance.
In the stencil buffer case, since you're rendering to the framebuffer there's no resolution problems and the result is more accurate. However, you're forced to render the mirror every frame, so the frame skip trick doesnt apply here.

NecroDOME
01-09-2006, 08:55 PM
Cool. Thanks for the explanation.

(I still haven't tried to create a mirror with the stencilbuffer, but I will soon!)

What I want is also to create portals. The only thing i'm worried about is the collision within portals as I use newton. For example, when I create a portal onto a wall I need to change the collision map to make a "hole" in the wall. (but thats for later use)

First I want to create a mirror/portal view...

Relfos
02-09-2006, 09:17 AM
This stencil buffer technique can be used not only for mirrors, but also for water reflection and portals.
The basic use for stencil buffer is, first you draw some geometry in it, with stencil activated. That will mark the geometry pixels into the stencil buffer. Then later you can change the stencil op, and for example you can use it to only draw on the marked region.

With other techniques, with the stencil buffer is possible to do shadows, fades, CSG and other cool stuff. Once you understand how it works, the only limit is your imagination 8)

NecroDOME
02-09-2006, 11:26 AM
Yeah :)

Another question; shaders!

How shoud I implement shaders with FX files?
I know shaders need some information from the program, but I want that the user can fully customize the shaders and maybe have a few shaders like water as a standard. I do not want to user to go "deep" in the code to program shaders.

What is the best way to implement those shaders?

EDIT: I should make a new post for this :P ...

Relfos
02-09-2006, 01:59 PM
About shaders...Sorry, but I'm a OpenGL guy, so I only know about GLSL shaders, and that is a little diferente from D3D. Last time I worked with DirectX, it was still D3D8, and in that time all the shaders were programmed in asm.

NecroDOME
03-09-2006, 11:51 AM
ok...

Thanks for the explanation on the mirrors :)