2010-04-07 9 views
5

Por lo que sé, no podemos leer el valor de Z (profundidad) en OpenGL ES 2.0. Así que me pregunto cómo podemos obtener las coordenadas del mundo 3D desde un punto en la pantalla 2D?OpenGL es 2.0 Búfer de profundidad de lectura

En realidad, tengo algunos pensamientos aleatorios que podrían funcionar. Como podemos leer el valor de RGBA usando glReadPixels, ¿qué tal si duplicamos el buffer de profundidad y lo almacenamos en un buffer de color (por ejemplo, ColorforDepth). Por supuesto, debe haber alguna buena convención para que no perdamos ninguna información del buffer de profundidad. Y luego, cuando necesitamos las coordenadas mundiales de un punto, conectamos este búfer de color ColorforDepth al framebuffer y luego lo renderizamos. Entonces cuando usamos glReadPixels para leer la información de profundidad en este marco.

Sin embargo, esto dará lugar a 1 fotograma flash ya que el buffer de color es un búfer raro traducido del búfer de profundidad. Todavía me pregunto si hay alguna forma estándar de obtener la profundidad en OpenGL es 2.0.

Thx por adelantado! :)

Respuesta

7

Al usar un FBO, puede procesar sin mostrar los resultados. Si está en ES 2.0, su sombreador de fragmentos puede acceder a la profundidad del fragmento actual (en coordenadas de ventana) como parte de gl_FragCoord, para que pueda escribir eso en el búfer de color, use glReadPixels para obtener el resultado y continuar. Alternativamente, puede cargar el espacio-mundo z como variable y escribirlo desde su sombreador de fragmentos, en caso de que sea una forma más fácil.

Para convencerse, intente escribir un sombreador rápido que saque gl_FragCoord.z ​​apresuradamente en baja precisión, p. Ej. solo

gl_FragColor = vec4(vec3(gl_FragCoord.z), 1.0); 

Debería obtener una escala de grises con la intensidad del color que representa la profundidad. Debido a que está en las coordenadas de la ventana, la intensidad oscilará entre 0.0 (el fragmento más cercano posible sin recortar) y 1.0 (el fragmento más alejado posible recortado). Para no perder mucha precisión, probablemente sea más útil dividir el valor entre los componentes, ya que es casi seguro que su proveedor no admita buffers de destino de coma flotante.

+0

Tommy, podría decirnos un poco más sobre la división de gl_FragCoord.z ​​entre los componentes. No seguir. Aclamaciones. – dugla

+1

@dugla Si la profundidad fuera un entero de 32 bits, podrías tener 8 bits en cada una de R, G, B y A. Así que, en la práctica, lo que harías es algo así como multiplicar el vector '(1, 256 , 65536, 16777216) ', luego almacene cada componente de ese vector mod 1.0 en los canales relevantes. Puede recombinarse más tarde al dividir por los componentes relevantes y sumarlos. – Tommy

0

que utilizan un rayo básica casting para recoger un objeto 3D a partir de una pantalla táctil. En realidad, calculo la intersección entre la pantalla normal en el punto de contacto y una esfera que contiene mi objeto. Para un picking muy preciso o una forma complicada, debes usar varias esferas.

También puede proyectar algunos puntos clave de su objeto en el espacio 2D de su pantalla (multiplicando su punto 3D por su matriz de transformación) y luego hacer una comparación 2D (distancia) con su punto de contacto.

0

También me gustaría poder leer los valores en el búfer de profundidad, pero la investigación indica que no se puede hacer.

como Vincent sugiere, si tiene formas simples como esferas, la fundición de rayos es probablemente mejor.

para formas más complejas Tho, i estoy pensando de hacer que el objeto a una (potencialmente más pequeño) fuera de la pantalla buffer, manualmente la asignación de uno de los componentes de color de cada vértice de ser la profundidad de ese vértice, y luego leyendo los valores de color. esto es algo poco elegante y molesto, y requiere que seas capaz de convertir el espacio-objeto al espacio de la pantalla (estoy usando mis propios cuaterniones para manejar las matrices, así que eso se encarga de eso). puede haber una forma con los sombreadores de escribir la información de profundidad en el búfer de color o esténcil (¿GL ES incluso tiene una memoria tampón?)

si alguien tiene un enfoque más limpio, me encantaría escucharlo.

Cuestiones relacionadas