查找矩阵是否相交以进行剔除测试?
find if matrices intersect for culling test?
我正在开发一款 2d 游戏,我无法使用旋转传感器旋转视图并在屏幕上查看不同的纹理。
我正在使用这种方法散射所有纹理:
public void position(ShaderProgram program, float[] rotationMatrix , float[] projectionMatrix , float longitude , float latitude , float radius)
{
this.radius = radius;
viewMat = new float[MATRIX_SIZE];
mvpMatrix = new float[MATRIX_SIZE];
// correct coordinate system to fit landscape orientation
SensorManager.remapCoordinateSystem(rotationMatrix, SensorManager.AXIS_Y, SensorManager.AXIS_MINUS_X, viewMat);
//correct the axis so that the direction of Y axis is to the sky and Z is to the front
Matrix.rotateM(viewMat, 0, -90f, 1f, 0f, 0f);
// first rotation - longitude
Matrix.rotateM(viewMat, 0, longitude, 0f, 1f, 0f);
//second rotation - latitude
Matrix.rotateM(viewMat, 0, latitude, 1f, 0f, 0f);
// used to control the distance of viewing the texture (currently only z translation is used)
Matrix.translateM(viewMat, 0 , 0f , 0f , radius);
//multiply the adjusted view matrix with projection matrix
Matrix.multiplyMM(mvpMatrix, 0, projectionMatrix, 0, viewMat, 0);
//send mvp matrix to shader
GLES20.glUniformMatrix4fv(program.getMatrixLocation(), 1, false, mvpMatrix, 0);
}
然而,当我渲染大量纹理时,帧速率变得非常缓慢。所以我考虑使用剔除。
每个纹理都有不同的视图矩阵后,我应该如何进行剔除测试?
我的意思是,我如何比较表示我现在正在查看的位置的矩阵是否与表示每个纹理的矩阵相交,以便我决定是否绘制它?
有很多方法可以做到这一点,但每一种方法都需要更多,而不仅仅是一个矩阵。单独使用矩阵(假设对象的中心位于 0,0 且不应用任何矩阵)无法处理您可能只看到对象的一部分的情况。
您可以用8个点定义原始对象的边界,例如立方体。想象一下,如果你用与对象相同的矩阵绘制这 8 个点,这些点将出现在对象周围,这样它们就可以定义一个将对象本身框起来的表面。
因此,这些点可能会与您生成的矩阵(整个 MVP 矩阵)相乘,该矩阵会将它们投影到坐标系的 openGL 可绘制部分。现在你只需要检查这些点中的任何一个是否在每个轴的 [-1,1] 内,那么你必须绘制对象。所以 x、y 和 z 必须在 -1 和 1 之间。
更新:
实际上这还不够,因为即使所有 8 个点都在这些坐标之外,交集也可能发生。您将需要一个合适的算法来找到 2 个形状的交点...
我正在开发一款 2d 游戏,我无法使用旋转传感器旋转视图并在屏幕上查看不同的纹理。
我正在使用这种方法散射所有纹理:
public void position(ShaderProgram program, float[] rotationMatrix , float[] projectionMatrix , float longitude , float latitude , float radius)
{
this.radius = radius;
viewMat = new float[MATRIX_SIZE];
mvpMatrix = new float[MATRIX_SIZE];
// correct coordinate system to fit landscape orientation
SensorManager.remapCoordinateSystem(rotationMatrix, SensorManager.AXIS_Y, SensorManager.AXIS_MINUS_X, viewMat);
//correct the axis so that the direction of Y axis is to the sky and Z is to the front
Matrix.rotateM(viewMat, 0, -90f, 1f, 0f, 0f);
// first rotation - longitude
Matrix.rotateM(viewMat, 0, longitude, 0f, 1f, 0f);
//second rotation - latitude
Matrix.rotateM(viewMat, 0, latitude, 1f, 0f, 0f);
// used to control the distance of viewing the texture (currently only z translation is used)
Matrix.translateM(viewMat, 0 , 0f , 0f , radius);
//multiply the adjusted view matrix with projection matrix
Matrix.multiplyMM(mvpMatrix, 0, projectionMatrix, 0, viewMat, 0);
//send mvp matrix to shader
GLES20.glUniformMatrix4fv(program.getMatrixLocation(), 1, false, mvpMatrix, 0);
}
然而,当我渲染大量纹理时,帧速率变得非常缓慢。所以我考虑使用剔除。
每个纹理都有不同的视图矩阵后,我应该如何进行剔除测试?
我的意思是,我如何比较表示我现在正在查看的位置的矩阵是否与表示每个纹理的矩阵相交,以便我决定是否绘制它?
有很多方法可以做到这一点,但每一种方法都需要更多,而不仅仅是一个矩阵。单独使用矩阵(假设对象的中心位于 0,0 且不应用任何矩阵)无法处理您可能只看到对象的一部分的情况。
您可以用8个点定义原始对象的边界,例如立方体。想象一下,如果你用与对象相同的矩阵绘制这 8 个点,这些点将出现在对象周围,这样它们就可以定义一个将对象本身框起来的表面。
因此,这些点可能会与您生成的矩阵(整个 MVP 矩阵)相乘,该矩阵会将它们投影到坐标系的 openGL 可绘制部分。现在你只需要检查这些点中的任何一个是否在每个轴的 [-1,1] 内,那么你必须绘制对象。所以 x、y 和 z 必须在 -1 和 1 之间。
更新:
实际上这还不够,因为即使所有 8 个点都在这些坐标之外,交集也可能发生。您将需要一个合适的算法来找到 2 个形状的交点...