#android #opengl-es #opengl-es-2.0 #depth
#Android #opengl-es #opengl-es-2.0 #глубина
Вопрос:
Я пытаюсь изучить OpenGL ES 2.0, и я пошел загружать 3D-модели на Android. Теперь я могу правильно загружать текстуру модели, но у меня проблема с глубиной отображения. Когда я помещаю свою модель в перспективу, а часть модели скрыта другой ее частью, у меня случается, что один или два треугольника перед другим рисуются, и это то, что я вижу через некоторые части.
Я пытаюсь setEGLConfigChooser (8, 8, 8, 8, 16, 0); и (8, 8, 8, 8, 24, 0), но моя проблема остается той же, за исключением того, что когда я помещаю (8, 8, 8, 8, 24, 0) и отображение немного более четкое, но когда 3D-объект перемещается, цвета создают эффект стробоскопа, который меня беспокоит.
Я также пробую функцию glDepthFunc (GL_LEQUAL); с glEnable (GL_DEPTH_TEST), но это не решает мою проблему.
Вот изображения проблемы:
Проблема: Ссылка повреждена
Хорошая: Ссылка не работает
Извините за мою ссылку на картинку, у меня репутация не более 10, чтобы опубликовать картинку в вопросе.
Вот мой код, мой GLSurfaceView
public MyGLSurfaceView(Context context) {
super(context);
this.context = context;
setEGLContextClientVersion(2);
setEGLConfigChooser(true);
//setZOrderOnTop(true);
//setEGLConfigChooser(8, 8, 8, 8, 16, 0);
//setEGLConfigChooser(8, 8, 8, 8, 24, 0);
//getHolder().setFormat(PixelFormat.RGBA_8888);
mRenderer = new Renderer(context);
setRenderer(mRenderer);
}
Мой рендерер
@Override
public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
glEnable(GL_DEPTH_TEST);
mushroom = new Mushroom();
textureProgram = new TextureShaderProgram(context);
texture = TextureHelper.loadTexture(context, R.drawable.mushroom);
}
@Override
public void onSurfaceChanged(GL10 glUnused, int width, int height) {
glViewport(0, 0, width, height);
MatrixHelper.perspectiveM(projectionMatrix, 45, (float) width
/ (float) height, 0f, 10f);
setLookAtM(viewMatrix, 0, 0f, 1.2f, -10.2f, 0f, 0f, 0f, 0f, 1f, 0f);
}
@Override
public void onDrawFrame(GL10 glUnused) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
multiplyMM(viewProjectionMatrix, 0, projectionMatrix, 0, viewMatrix, 0);
glDepthFunc(GL_LEQUAL);
//glDepthMask(true);
positionMushroomInScene();
textureProgram.useProgram();
textureProgram.setUniforms(modelViewProjectionMatrix, texture);
mushroom.bindData(textureProgram);
mushroom.draw();
//glDepthFunc(GL_LESS);
}
private void positionMushroomInScene() {
setIdentityM(modelMatrix, 0);
translateM(modelMatrix, 0, 0f, 0f, 5f);
rotateM(modelMatrix, 0, -yRotation, 1f, 0f, 0f);
rotateM(modelMatrix, 0, xRotation, 0f, 1f, 0f);
multiplyMM(modelViewProjectionMatrix, 0, viewProjectionMatrix,
0, modelMatrix, 0);
}
Мой матричный помощник
public static void perspectiveM(float[] m, float yFovInDegrees, float aspect, float n, float f) {
final float angleInRadians = (float) (yFovInDegrees * Math.PI / 180.0);
final float a = (float) (1.0 / Math.tan(angleInRadians / 2.0));
m[0] = a / aspect;
m[1] = 0f;
m[2] = 0f;
m[3] = 0f;
m[4] = 0f;
m[5] = a;
m[6] = 0f;
m[7] = 0f;
m[8] = 0f;
m[9] = 0f;
m[10] = -((f n) / (f - n));
m[11] = -1f;
m[12] = 0f;
m[13] = 0f;
m[14] = -((2f * f * n) / (f - n));
m[15] = 0f;
}
Комментарии:
1. вообще не похоже на проблему с тестом глубины. Возможно, это просто отсечение, но я не совсем уверен.
Ответ №1:
Проблема, скорее всего, в том, как вы настроили свою матрицу проекции:
MatrixHelper.perspectiveM(projectionMatrix, 45, (float) width
/ (float) height, 0f, 10f);
4-м аргументом в вашем определении этой функции является ближняя плоскость. Это значение никогда не должно быть 0.0. Обычно это должна быть разумная доля дальнего расстояния. Выбор идеального значения может быть своего рода компромиссом. Чем больше far / near
, тем меньшую точность глубины вы получаете. С другой стороны, если вы установите near
значение слишком большим, вы рискуете обрезать близкую геометрию, которую вы действительно хотели видеть.
Соотношение, возможно, 100 или 1000 для far / near
обычно должно обеспечивать разумную точность глубины без нежелательного обрезания передней части. Вам нужно быть немного более консервативным в отношении соотношения, если вы используете 16-битный буфер глубины, чем если у вас есть 24-битный буфер глубины.
Для вашей цели попробуйте изменить near
значение 0.1 и посмотрите, как это работает для вас:
MatrixHelper.perspectiveM(projectionMatrix, 45, (float) width
/ (float) height, 0.1f, 10f);