What projection and camera should I use to view 3D / 2D from top to bottom?

I'm probably going to hit myself in the face when the answer becomes clear, but I'm afraid I can't figure out what to do with my camera to effectively mix the scrolling of 2D and 3D objects.

I am currently using an offset camera, which I implemented when it was just a 2D project. The camera shifts the drawing position of all 2D objects depending on where its position in the world is. In case it is unclear, here is the code:

public void DrawSprite(Sprite sprite) { Vector2 drawtopLeftPosition = ApplyTransformation(sprite.Position); //TODO: add culling logic here sprite.Draw(spriteBatch, drawtopLeftPosition); } private Vector2 ApplyTransformation(Vector2 spritetopLeftPosition) { return (spritetopLeftPosition - topLeftPosition); } 

Simple enough. This worked efficiently until I tried to push 3D to the equation. I have several areas that I want to display next to 2D game objects. I already figured out how to arrange the Z-order correctly, but I can’t draw the spheres correctly. They appear and disappear depending on where the camera is, and often fly randomly even with the slightest movement of the camera. Here are my cameras:

 viewMatrix = Matrix.CreateLookAt(new Vector3(Position, 1f), new Vector3(Position , 0), Vector3.Up); projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, graphics.Viewport.AspectRatio, 1f, 1000f); 

Note that Vector2's position is the absolute center of the camera's viewing window, not the top left or something like that. I also tried using OrthographicOffCenter and orthographic forecasts. ViewMatrix updates each frame using the same CreateLookAt function, which is based on the current camera position. Here is the Camera method that draws a 3D object:

 public void DrawModel(Sprite3D sprite, GraphicsDevice device) { device.BlendState = BlendState.Opaque; device.DepthStencilState = DepthStencilState.Default; device.SamplerStates[0] = SamplerState.LinearWrap; sprite.DrawBasic(this, device); } 

My main perplexity is whether I should move 3D objects as well as 2D. I tried to do this, but had more success, actually flashing 3D objects on the screen, if I do not.

Here is the Sprite3D drawing section:

 public Matrix GenerateWorld() { return Matrix.CreateScale(Scale) * Matrix.CreateTranslation(new Vector3(Position, -ZPosition)) * Matrix.CreateFromYawPitchRoll(Rotation3D.X, Rotation3D.Y, Rotation3D.Z); } private Matrix GenerateDEBUGWorld() { return Matrix.CreateScale(Scale) * Matrix.CreateTranslation(Vector3.Zero); } public void DrawBasic(Camera camera, GraphicsDevice device) { Matrix[] transforms = new Matrix[Model.Bones.Count]; Model.CopyAbsoluteBoneTransformsTo(transforms); foreach (ModelMesh mesh in Model.Meshes) { foreach (BasicEffect effect in mesh.Effects) { effect.World = (transforms[mesh.ParentBone.Index] * GenerateDEBUGWorld()); effect.View = camera.ViewMatrix; effect.Projection = camera.ProjectionMatrix; } mesh.Draw(); } } 

GenerateDEBUGWorld just puts the sphere at 0.0 so I always know where it should be.

A few things I noticed:

  • If I set the camera’s Z position to a larger number (for example, 10), the spheres move less randomly, but still erroneously
  • Using the OrthographicOffCenter projection displays tiny small spheres in the center of the screen that do not change in position or scale, even if I multiply the Scite Sprint3D variable by 1000.

So, the main question: should I use a displacement camera, or is there a better way to mix 2D and 3D efficiently (maybe billing, but I don't want to add unnecessary complexity to this project)? And, if I use offset, should 3D objects be moved as well as 2D? Finally, what type of projection should I use?

Update. If I move the camera back to z at 100 and make the spheres enlarged by 100%, they will behave normally - when the camera moves to the left, they move to the right, up, down, etc., since you expect a perspective projection. However, they move too much in relation to other 2D objects. Is it a matter of scale? It is very difficult for me to agree on a way to display sprites and a way to display three-dimensional objects on the screen ...

+4
source share
2 answers

It looks like you are looking for Unproject - it will take a 2D point and “turn it” into 3D space. If all your objects are in three-dimensional space, your regular Ortho / LookAt camera should work as you expect ... I also completely lose my memory, because I cannot be able to search for it .;)

0
source

Just a thought, but your Z in your view matrix is ​​limited between 1 and 0. Update the Z component of these Vector3 to be the actual Z camera, and see what it does for you.

<2 cents / ">

0
source