在主题中我想将对象空间中的3d点转换为屏幕空间。通过在互联网上阅读一些解决方案,我已经失去了一些时间来弄清楚这一点,但我仍然有错误的结果。这里是我获得最接近结果的图片:
"屏幕空间"范围由红线表示,这显然是错误的。顶点应该像那里一样放置(看蓝线):
我的func将对象转换为屏幕:
public Vector2 WorldToScreen( Vector3 pos, int width, int height) {
var pos4 = Vector4.Transform (new Vector4 (pos, 1), modelViewMatrix*projectionMatrix);
var NDCSpace=pos4.Xyz/pos4.W;
return new Vector2(NDCSpace.X*(width/2f),NDCSpace.Y*(height/2f));
}
这里是设置proj的func和相机的modelView矩阵:
public void SetProjectionMatrix()
{
projectionMatrix = Matrix4.CreatePerspectiveFieldOfView((float)(FieldOfView * Math.PI / 180.0), AspectRatio, ZNear, ZFar);
}
public void SetModelviewMatrix()
{
var translationMatrix = Matrix4.CreateTranslation(-entityObject.position);
var rotationMatrix = Matrix4.CreateFromQuaternion(ToQuaterion(entityObject.rotation));
//modelViewMatrix = rotationMatrix*translationMatrix; orbit
modelViewMatrix = translationMatrix*rotationMatrix; //pan
}
在我看来,NDCSpace它们返回正确的值(完全在视锥体内部时为-1..1)所以我认为错误是在最终矩阵变换的渲染部分。这是我绘制屏幕空间范围的函数。为了绘制调试信息,我使用立即模式。 (别担心,对于使用VBO的网格物体)
int[] size=new int[4];
GL.GetInteger (GetPName.Viewport,size);
var orthoProjMatrix=Matrix4.CreateOrthographic(size[2],size[3],Camera.main.ZNear,Camera.main.ZFar);
var tmpMat = orthoProjMatrix;
GL.MultMatrix (ref tmpMat);
GL.PushMatrix ();
GL.Color3(System.Drawing.Color.Red);
DrawHelper.DrawRectangle (Camera.main.WorldToScreen(mesh.bounds.Min,size[2],size[3]),Camera.main.WorldToScreen(mesh.bounds.Max,size[2],size[3]));
GL.PopMatrix ();
最后的想法是尝试使用广告牌矩阵但没有成功。我没有广泛测试这个想法,不确定这是否适用于这种情况。
谁能帮帮我?编辑: 这是DrawRectangle
public static void DrawRectangle(Vector3 pos1, Vector3 pos2){
GL.Begin(PrimitiveType.LineLoop);
GL.Vertex3(pos1.X, pos1.Y,pos1.Z);
GL.Vertex3(pos1.X, pos2.Y,pos1.Z);
GL.Vertex3(pos2.X, pos2.Y,pos2.Z);
GL.Vertex3(pos2.X, pos1.Y,pos2.Z);
GL.Vertex3(pos1.X, pos1.Y,pos1.Z);
GL.End ();
}
这里是模型矩阵,这是网格模型矩阵
public void SetModelMatrix(){
mesh.ModelMatrix=Matrix4.CreateScale(entityObject.scale)*Matrix4.CreateRotationX(entityObject.rotation.X) * Matrix4.CreateRotationY(entityObject.rotation.Y) * Matrix4.CreateRotationZ(entityObject.rotation.Z) *Matrix4.CreateTranslation(entityObject.position) ;
}
旋转以度为单位