为什么移动眼睛位置会剪切(剪辑)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);
为什么使用 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);