Sign in to follow this  
jameswren

Imposter Specifics

Recommended Posts

jameswren    190
I'm currently adding trees to my game, using meshes when closeby and falling back to billboards when far away. I've followed and understood the render-to-texture example in Tom's Millers MDX Kickstart book, but am having trouble adapting to render my tree to a billboard. 1) Setting up the view matrix. At the moment I'm using the camera position as Position and the tree position as LookAt...is this correct? 2) The size of texture, surface and viewport to use. Should these all be the same, and are they the resolution of the final texture? Or should the size of my window (eg 800 by 600) be taken into account for the viewport? 3) Creating the billboard quad. When creating the vertex buffer for the quad, how do I get it the right size on screen..perhaps using the mesh's bounding box? If you could help by answering any of my questions then that'd be great to get me going again. Thanks in advance.

Share this post


Link to post
Share on other sites
_winterdyne_    530
1) Should work, assuming your tree is centred around its origin. Otherwise you may need to offset your tree.

2) For long distance, don't bother with a high-res texture - takes longer to render, and might not be visible. 256 square should do fine. Yes, all should be the same size. Don't forget that your projection matrix must take into account the viewport size. Your eventual window doesn't matter. Don't forget to light it neutrally - coloured lights used for the imposter may cause problems when the imposter itself is lit - or you need to ensure that your imposters is lit when its texture is rendered, and NOT lit when it's rendered in your scene.

3)The billboards for imposters should be technically be TTF (turn-to-face). Don't confuse these with a manually drawn quad that you might use for sprites or HUD overlays. Basically their size is transformed according to the standard projection matrix based on their position (where your tree should be). Their original size (assuming the tree occupies the entire texture) should be the height of the tree object itself. This is covered in various tutorials about the place.

Share this post


Link to post
Share on other sites
paic    645
I don't really know the "Tom Miller's" method, but wouldn't it be simpler to pre-calc your billboards (in a rendering software such as Mays, 3DS, etc.) ?


For the 3), don't use billboards. Create a quad in world space, at the same place as the original tree, with the tree height, and aligned to the camera.

For example, this code will create the quad :


D3DXVECTOR3 quad[4];
quad[0] = D3DXVECTOR3(treePosition.x, treePosition.y, treePosition.z);
quad[1] = D3DXVECTOR3(treePosition.x, treePosition.y, treePosition.z);
quad[2] = D3DXVECTOR3(treePosition.x, treePosition.y + treeHeight, treePosition.z);
quad[3] = D3DXVECTOR3(treePosition.x, treePosition.y + treeHeight, treePosition.z);

D3DXVECTOR3 sideVector(viewMatrix._11, viewMatrix._12, viewMatrix._13);
quad[0].x -= (treeWidth / 2.0f) * sideVector.x;
quad[0].z -= (treeWidth / 2.0f) * sideVector.z;

quad[1].x += (treeWidth / 2.0f) * sideVector.x;
quad[1].z += (treeWidth / 2.0f) * sideVector.z;

quad[2].x -= (treeWidth / 2.0f) * sideVector.x;
quad[2].z -= (treeWidth / 2.0f) * sideVector.z;

quad[3].x += (treeWidth / 2.0f) * sideVector.x;
quad[3].z += (treeWidth / 2.0f) * sideVector.z;



This will create a quad in the world space (so when the camera moves away or toward the tree, the size of the tree on screen changes) which has a height of "treeHeight" and a width of "treeWidth". And this quad is aligned with the camera (because we use the sideVector extracted from the view matrix)

Hope this helps ^^

Share this post


Link to post
Share on other sites
_winterdyne_    530
Actually a more elegant way of doing that is to use a billboard set, rather than thrashing the allocator with creating a new quad every frame.

Rule of thumb: ctor's cost time- that includes D3DXVector. I really wouldn't create the quad for each tree, each frame, depending on view position. Honestly, the transformation math is much, much cheaper.(Edit: Especially if you're using any form of memory management, and aren't just creating things on the stack)

I'd suggest keeping a billboard set allocated (of quads, size as mentioned) that you assign to known tree locations as your LOD culler specifies, up to a certain number of imposter trees.

This also gives you the advantage that the billboard set can be placed into your scene and sorted according to shader (surface / texture / material) like any other renderable, saving shader changes, which again are costly in terms of time. Do bear in mind that alpha mapped objects have to be drawn from FAR to NEAR, unless you're using stencil buffering, which has many better uses. Since imposters are generally distant objects, you can basically sort the active billboard list for the set by depth, render solids, then your imposters, then your transparent objects.

Share this post


Link to post
Share on other sites
jameswren    190
Thanks for your replies.

I'm not going to use pre-rendered textures as I'm wanting to incorporate a dynamic day/night system, so am going to Render-To-Texture for each billboard only as often as the lighting and camera view changes significantly.

What I do is for each tree at load time, compute its bounding sphere. This allows me to then create a quad the correct size of the tree (width == height == 2 * radius).

When I RTT, this is the code I use to setup my view matrix:



Vector3 cameraTarget = position; //position of tree
cameraTarget.Y += centerTree.Y; //adjust to look at center of tree
Vector3 ray = cameraPosition - cameraTarget; //get ray from center of tree to camera
ray.Normalize();
ray.Scale(radiusTree / (float)Math.Tan(Math.PI / 8)); //scale to the correct distance away from center of tree using trig (PI/4 is the FOV)
cameraPosition = cameraTarget + ray; //add ray to center of tree to give new camera position

Matrix matView = Matrix.LookAtLH(cameraPosition, cameraTarget, new Vector3(0, 1, 0));




However, when the LOD changes between the mesh and the billboard, I notice a flicker, and the billboard texture is slightly smaller/raised than the mesh itself appears. Am I doing anything obviously wrong that could cause this...I'm thinking it would be in my view matrix code.

Also, in order to make the billboard render with transparent parts around the tree, I'm using an A8R8G8B8 render surface and texture to keep alpha, and clear the render target surface to Color.Transparent...this works, but is it the correct way?

Any help/advice would be much appreciated.

Share this post


Link to post
Share on other sites
paic    645
Hi again.

For the alpha part, yes, I think it's the right method.

For the "flicker", it can come from 2 things :

- The size of the billboard. Using a bounding sphere is not really accurate to compute the size of the billboard. You could use a bouding box, it would be a lot more accurate.

- The rendering to texture. To have a good size, you should make sure that the tree occupies all the screen (in height at least), so when setting your view / projection matrices for the render-to-texture, you have to use a FOV and to place the camera at a distance such as your tree will fill the wholde texture.
For example, if you place your camera too far from the tree, then the tree will occupy only 50% of the texture, and even if the billboard's size is right, it will look smaller than the tree.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this