为什么移动眼睛位置会剪切(剪辑)3d 对象?

Why moving eye position will cut (clip) 3d object?

为什么使用 setLookAtM 移动眼睛位置会裁剪模型的 3d 视图? 我正在使用时间移动眼睛 Z 位置。 请查看视频和代码:

import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10

import android.opengl.GLES20
import android.opengl.GLSurfaceView
import android.opengl.Matrix
import android.os.SystemClock
import com.daftar.planetarium.SkyGrid
import com.daftar.planetarium.Square
import com.daftar.planetarium.Triangle
import kotlin.math.cos
import kotlin.math.sin

// number of coordinates per vertex in this array
const val COORDS_PER_VERTEX = 3


class MyGLRenderer : GLSurfaceView.Renderer {

    private lateinit var mTriangle: Triangle
    private lateinit var mSquare: Square
    private lateinit var mSkyGrid:SkyGrid

    override fun onSurfaceCreated(unused: GL10, config: EGLConfig) {
        // Set the background frame color
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f)
        // initialize a triangle
        mTriangle = Triangle()
        // initialize a square
        mSquare = Square()

        mSkyGrid = SkyGrid()
    }

    private val rotationMatrix = FloatArray(16)

    override fun onDrawFrame(unused: GL10) {
        // Redraw background color
        val time = SystemClock.uptimeMillis() % 12400
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
        // Set the camera position (View matrix)
        Matrix.setLookAtM(viewMatrix, 0,
                0f,0f,-time/1500f,
                0f, 0f, 0f,
                0f, 1.0f, 0.0f)

        // Calculate the projection and view transformation
        Matrix.multiplyMM(vPMatrix, 0, projectionMatrix, 0, viewMatrix, 0)

        val scratch = FloatArray(16)

        // Create a rotation transformation for the triangle
        val angle = 0*0.090f * time.toInt()
        Matrix.setRotateM(rotationMatrix, 0, angle, 0f, 0f, -1.0f)

        // Combine the rotation matrix with the projection and camera view
        // Note that the vPMatrix factor *must be first* in order
        // for the matrix multiplication product to be correct.
        Matrix.multiplyMM(scratch, 0, vPMatrix, 0, rotationMatrix, 0)

        // Draw triangle
//        mTriangle.draw(scratch)

        mSkyGrid.draw(scratch)
    }

    // vPMatrix is an abbreviation for "Model View Projection Matrix"
    private val vPMatrix = FloatArray(16)
    private val projectionMatrix = FloatArray(16)
    private val viewMatrix = FloatArray(16)

    override fun onSurfaceChanged(unused: GL10, width: Int, height: Int) {
        GLES20.glViewport(0, 0, width, height)

        val ratio: Float = width.toFloat() / height.toFloat()

        // this projection matrix is applied to object coordinates
        // in the onDrawFrame() method
        Matrix.frustumM(projectionMatrix, 0, -ratio, ratio, -1f, 1f, 3f, 7f)
    }
}

裁剪与投影矩阵有关。投影矩阵指定了一个Viewing frustum。所有不在观察体积(截锥体)中的几何体都被剪裁。因此,所有不在近平面和远平面之间的几何体都被剪裁:

几何体和相机之间的距离必须存储在深度缓冲区中。近平面和远平面之间的距离(归一化设备 z 坐标)映射到深度缓冲区中的值范围。

在你的例子中,到近平面的距离是 3,到远平面的距离是 7

Matrix.frustumM(projectionMatrix, 0, -ratio, ratio, -1f, 1f, 3f, 7f);

你必须增加到远位面的距离。例如:

Matrix.frustumM(projectionMatrix, 0, -ratio, ratio, -1f, 1f, 3f, 20f);