Go-GL "Project" 方法给出了意想不到的结果
Go-GL "Project" method giving unexpected results
Go-GL 的 Project 方法给我意外的大屏幕坐标。
总结:
// Screen is 800x600.
projection := mgl32.Perspective(
mgl32.DegToRad(45), // Field of view (45 degrees).
800.0 / 600.0, // Aspect ratio.
0.1, // Near Z at 0.1.
10) // Far Z at 10.
camera := mgl32.LookAtV(
mgl32.Vec3{0, 0.1, 10}, // Camera out on Z and slightly above.
mgl32.Vec3{0, 0, 0}, // Looking at the origin.
mgl32.Vec3{0, 1, 0} // Up is positive Y.
model := mgl32.Ident4() // Simple model matrix, to avoid confusion.
modelView := camera.Mul4(model) // The model-view matrix (== camera, here).
// Okay, so what does the origin translate to? Expect center-of-screen, with arbitrary-seeming depth.
origin := mgl32.Vec3{0, 0, 0}
screenOrigin := mgl32.Project(origin, modelView, projection, 0, 0, 800, 600)
fmt.Printf("Origin: (%v, %v, %v)", screenOrigin[0], screenOrigin[1], screenOrigin[2])
// What about the point 5 to the right of the origin?
// Expect increased X, but still less than screenWidth.
// Y and Z should be the same as for the origin.
// In my actual program, I drew (-1,-1,-1)-(1,1,1) cube at (5,0,0) and
// it is completely visible in the window.
test := mgl32.Vec3{5, 0, 0}
screenTest := mgl32.Project(test, modelView, projection, 0, 0, 800, 600)
fmt.Printf("Test: (%v, %v, %v)", screenTest[0], screenTest[1], screenTest[2])
结果?
Origin: (400, 300, 5.500255)
Test: (4021.32, 300, 5.500255)
4021.32?这离屏幕太远了!
我几乎排除了所有我能想到的变量,除了我用作基本提示的立方体渲染。我的代码是基于这个,但是我移动了相机和立方体:https://github.com/go-gl/examples/tree/master/gl41core-cube
如果我使用 (0, 0, 0) 作为输入向量并在 +X 中将 Ident4() 翻译 5 个单位(这是有道理的),我会得到相同的结果。
那我做错了什么?根据我正在绘制的立方体的位置,我希望 X = 625.
出于好奇,我查看了 mgl32 的源代码。 project
方法似乎完全错误:
obj4 := obj.Vec4(1)
vpp := projection.Mul4(modelview).Mul4x1(obj4)
win[0] = float32(initialX) + (float32(width)*(vpp[0]+1))/2
win[1] = float32(initialY) + (float32(height)*(vpp[1]+1))/2
win[2] = (vpp[2] + 1) / 2
可能会注意到,矩阵乘法后缺少透视除法,因此该函数在 w != 1.0f
时不起作用。
在第一个示例中,由于 x 和 y 在矩阵乘法后为零,因此无法注意到错误,因此除以 w 没有区别(z 除外)。在第二个示例中,x 坐标不再为零,错误变得可见。
Go-GL 的 Project 方法给我意外的大屏幕坐标。
总结:
// Screen is 800x600.
projection := mgl32.Perspective(
mgl32.DegToRad(45), // Field of view (45 degrees).
800.0 / 600.0, // Aspect ratio.
0.1, // Near Z at 0.1.
10) // Far Z at 10.
camera := mgl32.LookAtV(
mgl32.Vec3{0, 0.1, 10}, // Camera out on Z and slightly above.
mgl32.Vec3{0, 0, 0}, // Looking at the origin.
mgl32.Vec3{0, 1, 0} // Up is positive Y.
model := mgl32.Ident4() // Simple model matrix, to avoid confusion.
modelView := camera.Mul4(model) // The model-view matrix (== camera, here).
// Okay, so what does the origin translate to? Expect center-of-screen, with arbitrary-seeming depth.
origin := mgl32.Vec3{0, 0, 0}
screenOrigin := mgl32.Project(origin, modelView, projection, 0, 0, 800, 600)
fmt.Printf("Origin: (%v, %v, %v)", screenOrigin[0], screenOrigin[1], screenOrigin[2])
// What about the point 5 to the right of the origin?
// Expect increased X, but still less than screenWidth.
// Y and Z should be the same as for the origin.
// In my actual program, I drew (-1,-1,-1)-(1,1,1) cube at (5,0,0) and
// it is completely visible in the window.
test := mgl32.Vec3{5, 0, 0}
screenTest := mgl32.Project(test, modelView, projection, 0, 0, 800, 600)
fmt.Printf("Test: (%v, %v, %v)", screenTest[0], screenTest[1], screenTest[2])
结果?
Origin: (400, 300, 5.500255)
Test: (4021.32, 300, 5.500255)
4021.32?这离屏幕太远了!
我几乎排除了所有我能想到的变量,除了我用作基本提示的立方体渲染。我的代码是基于这个,但是我移动了相机和立方体:https://github.com/go-gl/examples/tree/master/gl41core-cube
如果我使用 (0, 0, 0) 作为输入向量并在 +X 中将 Ident4() 翻译 5 个单位(这是有道理的),我会得到相同的结果。
那我做错了什么?根据我正在绘制的立方体的位置,我希望 X = 625.
出于好奇,我查看了 mgl32 的源代码。 project
方法似乎完全错误:
obj4 := obj.Vec4(1)
vpp := projection.Mul4(modelview).Mul4x1(obj4)
win[0] = float32(initialX) + (float32(width)*(vpp[0]+1))/2
win[1] = float32(initialY) + (float32(height)*(vpp[1]+1))/2
win[2] = (vpp[2] + 1) / 2
可能会注意到,矩阵乘法后缺少透视除法,因此该函数在 w != 1.0f
时不起作用。
在第一个示例中,由于 x 和 y 在矩阵乘法后为零,因此无法注意到错误,因此除以 w 没有区别(z 除外)。在第二个示例中,x 坐标不再为零,错误变得可见。