dimanche 20 avril 2014

DirectX - caméra (LootkAt + projection orthogonale) ne veut pas fonctionner [SlimDX / D3D9]-Stack Overflow


I don't really understand how "cameras" work with D3D9


First, how i set my camera up:


     public Camera()
{
this.eye = new Vector3(0.0f, 0.0f, 0.0f);
this.lookAt = new Vector3(0.0f, 0.0f, 1.0f);
this.up = new Vector3(0.0f, 1.0f, 0.0f);
viewMatrix = Matrix.LookAtLH(eye, lookAt, up);
projectionMatrix = Matrix.OrthoLH(1 * zoomLevel, 1 * zoomLevel, 0.0f, 1.0f);
}

And my vertices :


        vertices = new VertexTexture[]
{
new VertexTexture()
{
Position = new Vector4(0.0f, 0.0f, 0.0f, 1.0f),
TextureCoord = new Vector2(0.0f, 1.0f)
},
new VertexTexture()
{
Position = new Vector4(0.0f, model.Height, 0.0f, 1.0f),
TextureCoord = new Vector2(0.0f, 0.0f)
},
new VertexTexture()
{
Position = new Vector4(model.Width, model.Height, 0.0f, 1.0f),
TextureCoord = new Vector2(1.0f, 0.0f)
},
new VertexTexture()
{
Position = new Vector4(model.Width, 0.0f, 0.0f, 1.0f),
TextureCoord = new Vector2(1.0f, 1.0f)
}
};

It works. I can move the camera, zoom, etc.


But the cameras properties seems weird to me ! I thought it would be something like:


    public Camera()
{
this.eye = new Vector3(0.0f, 0.0f, 1.0f);
this.lookAt = new Vector3(0.0f, 0.0f, 0.0f);
this.up = new Vector3(0.0f, 1.0f, 0.0f);
viewMatrix = Matrix.LookAtLH(eye, lookAt, up);
projectionMatrix = Matrix.OrthoLH(1 * zoomLevel, 1 * zoomLevel, 0.1f, 100.0f);
}

but with that parameters it doesn't work. Same if i change the Z coordinate for my plan (Which need to be set at 0 to work).


Now, i try to render other objects. I generate vertices for a sphere (it works fine on D3D 10, a 1 radius sphere generated around (0;0;0) ) but nothing appear on the screen


I played with the eye and lookat parameters but i can figure how to make it work, so, what i m doing wrong ?




First, some background. In orthogonal projection we technically don't need Z coordinate transforming but in fact D3D system doesn't care what kind of projection you use - for device it's just a transformation matrix and nothing more. So, Z coordinate is always transformed regardless to the projection type. On the other hand, camera coordinates are not transformed by a projection matrix (otherwise positioning would be a nightmare). Now let's get back to your situation and see what's happening.


Specifying zn=0.1f in OrthoLH you declare that this is your minimum depth. Hence, every vertex will be shifted in depth by -0.1f. With your vertex layout transformed Z will be 0.9f but you remember camera is not affected? So, it's still at depth 1.0f and this why you see nothing: there are no vertexes behind the camera.


Add here float computation error and you'll understand why setting camera at 0.9f sometimes helps and sometimes not. Though, setting position to 0.8f will work for any case.




First, thank's for the answer. I managed to avoid the problem by setting my camera with that properties:


        this.eye = new Vector3(0.0f, 0.0f, 0.0f);
this.lookAt = new Vector3(0.0f, 0.0f, 1.0f);
this.up = new Vector3(0.0f, 1.0f, 0.0f);

viewMatrix = Matrix.LookAtLH(eye, lookAt, up);
projectionMatrix = Matrix.OrthoLH(1 * zoomLevel, 1 * zoomLevel, 0.0f, 10000000.0f); :D

I'll read again what you said, and will think about a nicest fix :)


I think my problem is relative to my vertices ... for exemple, I generate a sphere with a radius of 20, then I transform that vertices to correspond to a 20px wide sphere, by scaling according to my screen coordinates


        worldMatrix = SlimDX.Matrix.Identity;
worldMatrix = SlimDX.Matrix.Scaling(new Vector3(2.0f / ControlWidth, 2.0f / ControlHeight, 1.0f));
worldMatrix = SlimDX.Matrix.Multiply(worldMatrix, SlimDX.Matrix.Translation(new Vector3(-1.0f, -1.0f, 0.0f)));

My X / Y scaling is ok. But how to scale the Z coordinate ? 2.0 / ((ControlHeight + ControlWidth ) / 2 ) ?


I'll read your anszer again, to understand everything :)



I don't really understand how "cameras" work with D3D9


First, how i set my camera up:


     public Camera()
{
this.eye = new Vector3(0.0f, 0.0f, 0.0f);
this.lookAt = new Vector3(0.0f, 0.0f, 1.0f);
this.up = new Vector3(0.0f, 1.0f, 0.0f);
viewMatrix = Matrix.LookAtLH(eye, lookAt, up);
projectionMatrix = Matrix.OrthoLH(1 * zoomLevel, 1 * zoomLevel, 0.0f, 1.0f);
}

And my vertices :


        vertices = new VertexTexture[]
{
new VertexTexture()
{
Position = new Vector4(0.0f, 0.0f, 0.0f, 1.0f),
TextureCoord = new Vector2(0.0f, 1.0f)
},
new VertexTexture()
{
Position = new Vector4(0.0f, model.Height, 0.0f, 1.0f),
TextureCoord = new Vector2(0.0f, 0.0f)
},
new VertexTexture()
{
Position = new Vector4(model.Width, model.Height, 0.0f, 1.0f),
TextureCoord = new Vector2(1.0f, 0.0f)
},
new VertexTexture()
{
Position = new Vector4(model.Width, 0.0f, 0.0f, 1.0f),
TextureCoord = new Vector2(1.0f, 1.0f)
}
};

It works. I can move the camera, zoom, etc.


But the cameras properties seems weird to me ! I thought it would be something like:


    public Camera()
{
this.eye = new Vector3(0.0f, 0.0f, 1.0f);
this.lookAt = new Vector3(0.0f, 0.0f, 0.0f);
this.up = new Vector3(0.0f, 1.0f, 0.0f);
viewMatrix = Matrix.LookAtLH(eye, lookAt, up);
projectionMatrix = Matrix.OrthoLH(1 * zoomLevel, 1 * zoomLevel, 0.1f, 100.0f);
}

but with that parameters it doesn't work. Same if i change the Z coordinate for my plan (Which need to be set at 0 to work).


Now, i try to render other objects. I generate vertices for a sphere (it works fine on D3D 10, a 1 radius sphere generated around (0;0;0) ) but nothing appear on the screen


I played with the eye and lookat parameters but i can figure how to make it work, so, what i m doing wrong ?



First, some background. In orthogonal projection we technically don't need Z coordinate transforming but in fact D3D system doesn't care what kind of projection you use - for device it's just a transformation matrix and nothing more. So, Z coordinate is always transformed regardless to the projection type. On the other hand, camera coordinates are not transformed by a projection matrix (otherwise positioning would be a nightmare). Now let's get back to your situation and see what's happening.


Specifying zn=0.1f in OrthoLH you declare that this is your minimum depth. Hence, every vertex will be shifted in depth by -0.1f. With your vertex layout transformed Z will be 0.9f but you remember camera is not affected? So, it's still at depth 1.0f and this why you see nothing: there are no vertexes behind the camera.


Add here float computation error and you'll understand why setting camera at 0.9f sometimes helps and sometimes not. Though, setting position to 0.8f will work for any case.



First, thank's for the answer. I managed to avoid the problem by setting my camera with that properties:


        this.eye = new Vector3(0.0f, 0.0f, 0.0f);
this.lookAt = new Vector3(0.0f, 0.0f, 1.0f);
this.up = new Vector3(0.0f, 1.0f, 0.0f);

viewMatrix = Matrix.LookAtLH(eye, lookAt, up);
projectionMatrix = Matrix.OrthoLH(1 * zoomLevel, 1 * zoomLevel, 0.0f, 10000000.0f); :D

I'll read again what you said, and will think about a nicest fix :)


I think my problem is relative to my vertices ... for exemple, I generate a sphere with a radius of 20, then I transform that vertices to correspond to a 20px wide sphere, by scaling according to my screen coordinates


        worldMatrix = SlimDX.Matrix.Identity;
worldMatrix = SlimDX.Matrix.Scaling(new Vector3(2.0f / ControlWidth, 2.0f / ControlHeight, 1.0f));
worldMatrix = SlimDX.Matrix.Multiply(worldMatrix, SlimDX.Matrix.Translation(new Vector3(-1.0f, -1.0f, 0.0f)));

My X / Y scaling is ok. But how to scale the Z coordinate ? 2.0 / ((ControlHeight + ControlWidth ) / 2 ) ?


I'll read your anszer again, to understand everything :)


0 commentaires:

Enregistrer un commentaire