Sign in to follow this  
ArnoldV

2D Sprite Scaling with D3DXVec3Project

Recommended Posts

ArnoldV    100
Hello, I have a quick question regarding scaling a 2D sprite by distance from a mesh in a 3d world space via D3DXVec3Project. Currently, I am using D3DXVec3Project(...) to successfully determine where to place a 2D image on the screen based off of an object's location in the world (like a tag). However, no matter what my distance is from the object, the image remains the same size, greatly overpowering the object at vast distances. Just like an object getting smaller as I distance myself from an object in real life via my perspective, I'd like the image to get smaller when moving away such that it's proportional to the size of the object. Thus, my question to the community is "Is there a way that I can calculate manually or through DirectX a scaling factor that would make the image above the object proportional in size to the object, regardless of what distance I would be from it?". Any help would be appreciated. Best regards, ArnoldV [Edited by - ArnoldV on February 15, 2010 2:29:42 PM]

Share this post


Link to post
Share on other sites
drChengele    100
I had almost the exact same problem because I had to use pretransformed sprites for particles in an otherwise 3d world and ended up implementing a kinda-sorta ugly hack for this, but it works.

D3DXVec3Project conveniently returns, in the z coordinate, the z-value of the point you projected. This z value determines where the point lies between near plane and far plane (0.f for near, 1.f for far) and is also the very same z used in depth buffers.

The problem is, this z value is for the most part in the range of 0.999 to 1.000 unless the projected point is very near the screen. It further complicates the matters that this z value is completely dependent on znear and zfar values used used when the projection matrix is specified. After some experimentation I managed to extract a hopefully working formula for getting the distance of a projected point out from camera plane based on the z-value. After that, getting a sprite scale that is dependent on the camera distance is a matter of simple division.

This function returns a scale value that will reduce your sprite proportionally based on the distance from the screen:

*UPDATE* - I have done extensive testing and have updated the formula to be much more accurate, I think it is 100% accurate (or near enough that it makes no matter as long as FAR_PLANE is at least 10-100 times larger than NEAR_PLANE). Also I have fixed it to take FoV into account when scaling the sprite. I will replace the original formula because it was inaccurate.


// NEAR_PLANE, FAR_PLANE, FIELD_OF_VIEW are all values you set when creating the perspective matrix
// projected_z is the z value returned by the D3DXVec3Project function

float get_sprite_scale(float projected_z)
{
float distance = NEAR_PLANE / (1.f - projected_z + NEAR_PLANE/FAR_PLANE );
// you might wish to do some optimization and store NEAR_PLANE/FAR_PLANE in a precomputed variable.
return 100.f / (distance * FIELD_OF_VIEW); //
}



This formula provides a realistic scale for sprites placed in the 3d world. Regardless how far they are from the camera or how the FOV changes, sprites will have the correct scale in relation to 3d geometry.

[Edited by - drChengele on March 9, 2010 9:08:25 PM]

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