我有一个OpenGL视图,它显示一组带有一些基本着色器的3D点:
// Fragment Shader
static const char* PointFS = STRINGIFY
(
void main(void)
{
gl_FragColor = vec4(0.8, 0.8, 0.8, 1.0);
}
);
// Vertex Shader
static const char* PointVS = STRINGIFY
(
uniform mediump mat4 uProjectionMatrix;
attribute mediump vec4 position;
void main( void )
{
gl_Position = uProjectionMatrix * position;
gl_PointSize = 3.0;
}
);
MVP矩阵计算如下:
- (void)setMatrices
{
// ModelView Matrix
GLKMatrix4 modelViewMatrix = GLKMatrix4Identity;
modelViewMatrix = GLKMatrix4Scale(modelViewMatrix, 2, 2, 2);
// Projection Matrix
const GLfloat aspectRatio = (GLfloat)(self.view.bounds.size.width) / (GLfloat)(self.view.bounds.size.height);
const GLfloat fieldView = GLKMathDegreesToRadians(90.0f);
const GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(fieldView, aspectRatio, 0.1f, 10.0f);
glUniformMatrix4fv(self.pointShader.uProjectionMatrix, 1, 0, GLKMatrix4Multiply(projectionMatrix, modelViewMatrix).m);
}
这很好用,但是我有一套500分,我只看到一些。
如何缩放/翻译MVP矩阵以显示所有这些矩阵(它们是动态集)?理想情况下,“质心”应位于原点,并且所有点都可见。它应该能够适应视图的旋转(手势是我想要实现的下一步)。
答案 0 :(得分:1)
看到你如何表达这一点你可能需要很多......我猜最佳方法可能正在使用"看看",你所看到的点是(0,0,0)
如你所说,相机位置可能应为(0,0,Z)
及更高(0,1,0)
。所以这里唯一的问题是相机位置的Z分量。
如果您使用例如-.1
启动Z并迭代所有点,则sin(fieldView*.5f) * (p.z-Z) >= point.y
表示该点可见。因此,您可以计算Z1 = p.z-(point.y/sin(fieldView*.5f))
和Z1<Z
,然后计算Z=Z1
。此检查仅适用于正Y检查,对于负Y也需要相同,对于+ -X也需要相同。这些规避非常相似,但在检查X时你也可以考虑屏幕比例。
此程序应该为您提供可以查看所有点的最小字段(具有给定的限制,例如查看(0,0,0))但远非最简单的。如果p.z<-Z
,您还需要考虑方程式是否有效。
另一种更简单的方法是生成围绕中心的最小立方体,其中包含所有点:迭代点并获得具有最大绝对值的坐标(X,Y或Z中的任何一个)。如果你使用它而使用视锥体而不是透视图,那么所有矩形参数(顶部,底部,左侧和右侧)都使用此值生成+-largest
。然后,您需要计算90度字段为Z = (largest*.5)
的平移。 Z是截锥体的zNear,然后也用-(Z+largest)
转换矩阵。同样,平截头体中的一个坐标必须乘以屏幕比率。
在任何情况下都要注意你的zFar
是什么,只有10.0f在你的情况下可能有点太短。在您需要深度缓冲区之前,您不必担心该值太大。