I first thought about the technique I'm going to present you here the first time I have heard about the Mega-Texture technology of John carmack from Id Software. I wondered what effect real/full texture virtualization would allow us to achieve ? That's why I have started to develop this little demo. The goal was to have every surface in the virtual environment having it's own texture and texels.
I started by developing a little level. To simplify, The virtual environment is composed of just planar surfaces (quads). Then, for each of these quads, I allocate a texture with a resolution which will make all texel have one given size in the world. I define each surface texture as containing the diffuse color and the heightmap to render relief-mapping. To display the scene, I render each polygon using its corresponding texture and using relief mapping to render surface hole and irregularities based on its heightmap. The normals are generated in the shader based on the heightmap. Because normals are generated "on the fly" using the heightmap, a deffered rendering engine would be the best thing to use. (but this is not the case in my simple demo).
Now that I have unique texture/texel on each surfaces, I first started by implementing a perspective projection based algorithm which can bake decals in the surface texture. Let's call this surface texture a megamap! Sounds like mega texture isn't it? :-) This is possible using a simple shader and the framebuffer extension. Now, it's possible to bake every decals in each megamap and to see it following the surfaces curvature.
Download source and executable (currently, the source is not commented)
YouTube video or HighQuality video
Top-left : relief mapping
Top-right : a projected decals
Bottom : from another view point.
Notice how the decal follow the surface curvature!
I have explained that I store the heightmap of the surface in the alpha channel of the megamap. So, as the color, it is possible to modify the heightmap of the surface and thus to change it's appearance. This is simply achieve by rendering to the alpha channel as to the color channels of the megamap also by using blending. Moreover, you can change the surface heightmap and then reproject a new decal on it : it will follow the new curvature of the surface! Furthermore, I have added a simple "shadow mapping"-like algorithm which avoid the projection of decals behind blocking surfaces. I have also added an attenuation equation with smooth transition in order to not project decals on too far surface.
Left : a projected blood decal.
Right : a projected "Alien" blood decal! Notice how the surface get gnawed by this acid blood!
Notice how the projected blood do not spill on the floor behind the column.
It seems that a doom3 hell demon have appeared here! In this case, the surface has been burnt!
As explained previously, projecting blood in the megamap require a perspective projection but projecting a bullet hole does not! The bullet hole size does not grow with the distance! That's why I propose here to use an orthographic projection in this case. What's cool is that if you fire a bullet in parallel to a surface, you will see the creation of a strench!
Left : some bullet holes.
Right : when a bullet is fired in parallel to a surface, a trench is created!
The advantages of using megamap is that it allows you to have high dynamic surfaces which can really bring a virtual environment to life using these dynamic surfaces color and heightmap! It is possible to bake any number of decals you want in the megamap without any loss of framerate! You can virtually have an infinite number of decals applied to your environment! The disavantages is that the memory used by the entire megamap on each surfaces is really high : in the simple demo I present here, a constant amount of 53Mb of video memory is used for the megamap only. I can also say that due to the fact that megamap texels can not be as small as you want, each decal projected on the surface can lose some of its details once it is baked in the megamap.
In addition to the high memory consuption, the bottleneck of megamap is the high computation involved during megamap update. To improve this, good occlusion culling methods are required (PVS seem highly recommended in this case).
I hope that you like this effect! If you are interested, you can improve my demo :
- (easy) Add drawing capabilities (just a simple continuous tag projection)
- (normal) Repair the surfaces by elevating the heightmap of the megamap surface.
- (heard) Add a new channel to the megamap to allow the spill of liquid and to see it flow on the surface based on its orientation and heightmap compared to the gravity vector. (for that, you should refer to one of the nVidia demos)
In contrary to polygonal decals, this technique do not reduce the frame rate, even with an "infinite" number of decals applied to the scene.
Because all decals are stored in the surface texture, we are limited by its resolution. (Precisely, the size of one texel in the world space)