Closed doors are no problem. Here are some smugly closed doors in their natural environment. They're rough prototypes I knocked up on the train to play with, but they're good enough to experiment with.
Open them up however and they really ruin the whole cutaway-wall look on the doorframes - particularly in the foreground. In fact, because the wall tiles I'm using here are recessed, you can even see them poking through the rear walls too. This really ruins the "believable, solid world" feeling I'm going for.
Unfortunately, I don't think this is going to be something I'm going to solve today. The options seem to be:
1) Animate the door vertices, collapsing them as they enter the doorframe. In order to avoid any texture warping as you deform the geometry, this would need a truck-load of vertices across the face of the doors - and would be really frustrating to model given the curved doorway I'm using. Worse, this time consuming animation job would need to be re-done once for every new door/doorway shape combination. This feels like a hack. Another similar alternative is to animate the vertex colour to transparent as it slides through the doorway - but this has all the same drawbacks - so I've pretty much given up on any vertex animation based solution.
2) Make one side of the door texture transparent, and "slide" the door image across a static quad to make it look like the door is opening. I think this is what the moonpod guys did for Mr Robot, so it can obviously look very good (and can I just say those guys are AWESOME - I'm more excited by Mr Robot than anything commercial that's coming out - plus they have a kick-ass development diary). But it does have a few downsides, namely that the door is as flat as a pancake (which could look odd in a game that lets you rotate the camera), the door can't cast shadows (as it's flat) and the door needs a totally planar UV mapping (meaning it can't re-use texture space). This also stops me doing any cool detail on the door itself (like interlocking sections that slide out from each other, animated textures for display panels, etc)
3) Use the stencil buffer to mask out the region around the door. This obviously turns door rendering into a multi-pass activity, plus (because it's done in screen space with no depth component) it only works well when the door is mostly square to the screen. As soon as you look across an oblique angle, it's going to be hard to exclude the right region. I've pretty much given up on this one.
4) Use clip planes to define a rough model of the doorframe. My initial hesitation with these is getting them into both the DirectX and OpenGL code paths I have, plus planning ahead for programmable shaders. I did a little research on this today, and it looks like it is available everywhere - even if there's some debate on how expensive it can be in a pixel heavy shader. Still, this is my current favourite, as it allows me to make any kind of cool doors/locks that can be real-3D, without interfering with any other rendering trick (e.g. skinning, vertex, or texture animation) I might want to use on the door somewhere. The downside of this approach is that, because clip planes are global render state - this will need me to flush my render queues on both sides (breaking material/depth sorting goodness) to ensure that the clip planes only effect the door itself. As a final bonus - once I have these setup, I can re-use them for line-of-sight portal rendering if I ever want to go down that path.
5) (this last one was suggested by a guy at work today) Implement real-time Booleans operators to clip the door in software. This is an impressive idea, but interpolating all the various types of per-vertex data (and possibly re-indexing the geometry to remove primitives that are entirely culled) seems a little bit like overkill - not to mention the fact that it will require every door to make a unique copy of the door geometry to modify.
As hinted above - I'm leaning towards the 4th option - as it seems to be the cleanest solution. I just need to work out how to manage the interactions between the scene graph traversal and the renderer. In the mean time though, I throw down the gauntlet to any reader to suggest other clever solutions!
Cheers,
G