How to determine the distance an object has to be from camera size in order to display a pucture perfect texture in perspective mode?

Hi,

I’m curious if there is a formula for determining the distance an object has to be from camera in order to display a picture perfect texture in perspective mode based on the following variables:

  1. object’s size in unity units
  2. Field of View in degrees of the camera
  3. Object’s distance from the camera
  4. Texture size
  5. Screen Resolution

I want to know this because I’m trying to get the most out of my textures. I tried one method, which included me scaling a cube along the x and y axis, so that it filled the frame. These were the results and settings:

  1. The camera side of the cube’s mesh was 20 units upstage from the camera
  2. Resolution was 960 x 640
  3. Cube was 23 units in height and 34.7 units in width ( making in-between 27.5 to 28 pixels per unit )
  4. Field of View was 60

I would like to know if there is a formula for finding the distance that an object has to be from camera in order to show its texture in perfect dimensions. For instance, I would like to know how to find out what distance the camera would need to be from a 3x3 unit mesh with 128x128 pixel texture in order to have the texture close to perfect in size pixel perfect.

Thanks in advance for helping.

Camera.WorldToScreenPoint() will help you here. http://docs.unity3d.com/Documentation/ScriptReference/Camera.WorldToScreenPoint.html do you want the objects actual size on the screen in pixels, or the amount the pixels in the texture is using based on the screen?

1 Answer

1

Maybe Unity has something but otherwise the way is simple, you need to multiply your vertex positions by the matrices.

You have the world matrix that you multiply by the view matrix (camera view) Then you multiply by projection matrix. And finally viewport matrix (may be same as previous if you are not dividing your screen)

This will consequently turn your point from world position to camera position (changing origin of the world), then you convert the point to projection space which turns it all into 2D. Now you have your points and you can get the distance.

This is highly simplified but that could get you started.

EDIT: One thing you can use is Unity - Scripting API: Camera.ScreenToWorldPoint

Problem is that it cannot define how far the object should be since the two points can be right here or represent a large distance from far away. Now you can probably work that out but there will be some restriction.

Considering you have a distance of 2 between A and B. On the screen the distance is 50px.
ScreenToWorldPoint will give two points in 3D that are distanced by the equivalent of 50px. But those could be anywhere in the world, they may represent 10km distance real far away you cannot figure out.

I would think, but it needs to be tried, that using the field of view of the camera and a little trig you can figure out where the object should be.

See your points will form some kind of pyramide with flat top where the two points are. Your purpose is to find the base of the pyramid. You know the field of view of the camera. So you can use some trig to figure out the sin of the angle. (I cannot upload a pic since it does not work for undefined reasons).

So all in all

Points in on top with camera
    ---
   /| |\
  / | | \
 /  | |  \     We need to find the length of this side line
/   | |   \
Needed points here at the bottom

So with this above, the top is your two points in 3D world after conversion but they are not positioned properly, just converted without considering scale. The bottom is where they should be. The middle lines and the side lines have 1/2 of field of view angle. You need the bottom to be distance by let’s say 2. You subtract the distance you already have from the points at the top (between the two straight lines), then you divide by 2 (== sin of angle).

Now come the trig part. You have the angle (half field of view)and the sin of the angle. You can find the cos with sqrt(1-sin(angle)^2). Then you get hypotenuse with sin/cos.

This hypotenuse is the length of the side of your pyramid. now I leave up to you to position them in the world.

Problem is, your object can only face the camera. If it rotated then I would guess you enter a world of chaos.

Note this is just done on top of my head and I cannot promise any results. Maybe it will be right…

Correct me if I'm wrong, but doesn't this means that I need to know the position of the object before I find the pixel dimensions that the mesh is displaying, if so, the calculation is backwards. I wanted to figure it out with the distance the mesh has to be from camera as the result of the calculation. The texture size is known, the mesh size is known, the camera field of view is known, the resolution is known, but I want to know how to find the distance that the mesh has to be from camera in order to display the texture at it's perfect size.

Well do it invert effect. You know the position on screen and use the invert of each matrix.

Right, sorry, took me a while to wrap my head around it

Understandable, matrices are quite confusing when starting. Then suddenly comes the moment when one realizes that they are just basic arithmetic a 10 year-old could tackle as long as you know what should be used. No worries, most of us went through this.

Hey fafase, do you mind giving me an example of how you do that?. I'm reading about matrix transformations and multiplications, but I'm stumped! I now know how to multiply a matrix if the matrices are right in front of me, but I have no idea how to write a matrix out. I would be stoked if you could show me a quick example. Thanks in advance