¿Cómo puedo doblar un objeto en OpenGL?

11

¿Hay alguna manera de doblar un objeto, como un cilindro o un plano con OpenGL?

Soy un principiante de OpenGL (estoy usando OpenGL ES 2.0, si eso importa, aunque sospecho que las matemáticas son las más importantes en este caso, por lo que es de alguna manera independiente de la versión), entiendo los conceptos básicos: traducir, rotar, transformaciones de matriz, etc. Me preguntaba si existe una técnica que le permita cambiar realmente la geometría de sus objetos (en este caso doblándolos).

Cualquier enlace, tutoriales u otras referencias son bienvenidas!

Valentin Radu
fuente

Respuestas:

11

Lo que debería hacer para "doblar" un objeto es aplicar una combinación apropiada de traslación / rotación / escala a solo un subconjunto de los vértices del objeto en cuestión, probablemente ponderando esa transformación en consecuencia.

Hacer esto de una manera agradable necesitará usar más vértices de los que de otra manera serían estrictamente necesarios para describir la malla original. Por ejemplo, un cilindro simple solo puede tener vértices en cada extremo, pero si desea que ese cilindro se doble en el medio, también necesitará vértices allí.

Si todo lo que le interesa es deformaciones puntuales muy específicas de formas muy simples (como su plano antes mencionado), probablemente podría hacerlo manualmente. Por ejemplo, decida sobre el "eje de curvatura" para su plano y calcule las transformaciones apropiadas para cada fila de vértices del plano para lograr la rotación apropiada alrededor de ese eje de curvatura dependiendo de su distancia del mismo, y luego aplíquelo a la geometría (posiblemente en el CPU ya que sería la más sencilla, al menos inicialmente). Pero tal técnica no se escalaría bien y sería muy tediosa.

Dado que puede ser tan engorroso descubrir correctamente cómo ponderar una transformación en cada vértice individual en un conjunto para lograr la deformación deseada (especialmente para objetos más prácticos y complicados), muchos juegos usan una técnica llamada animación esquelética . En un nivel alto, esto implica asociar un conjunto separado de geometría (el "esqueleto") con su malla. Esa geometría representa los huesos de su objeto, y usted define (a menudo en herramientas de modelado) un mapeo entre los vértices del modelo real y los huesos del esqueleto, qué huesos están asociados con cada vértice y cuánto afecta ese hueso a la deformación. de ese vértice. Luego, el esqueleto se anima directamente, y la animación se transfiere al modelo real a través de la relación entre los huesos y sus vértices.

Típicamente en esta técnica, el mapeo entre el esqueleto y la malla real se define en el momento de la producción de activos. Las animaciones también se pueden construir en ese momento, o se pueden construir de manera procesal en tiempo de ejecución. La aplicación de las transformaciones de animación a la malla real se produce en tiempo de ejecución. En general, no se generan vértices nuevos en tiempo de ejecución, lo que significa que el rango de deformaciones atractivas se fija implícitamente en la malla cuando se crea originalmente.

En teoría, uno también podría aplicar teselación y subdivisión a la malla en tiempo de ejecución en función del análisis de las transformaciones en la animación, y así producir los vértices apropiados para crear una animación que no estaba necesariamente planificada. No estoy al tanto, de improviso, de ningún documento sobre este tema.

Ver también:

Vaillancourt
fuente
9

Para la matemática real de la deformación, esto puede ser muy complicado, ¿por qué no comienzas aquí? .

Ahora hablaré sobre cómo puede aplicar esto, suponiendo que ya tenga las matemáticas de cómo reducirá sus deformaciones.

2 maneras:

1) Cada cuadro, visite cada vértice en el modelo de cilindro y desfasarlo de alguna manera.

2) Desplaza los vértices en el sombreador de vértices mientras estás renderizando. OpenGL ES 2.0 admite sombreadores de vértices. Entonces tienes suerte, de alguna manera.

¿Desea deformar solo el objeto tal como aparece en la pantalla , o desea deformar el objeto para que cada objeto en el juego sepa que se ha deformado?

Si deforma el objeto en el sombreador de vértices, eso sucede solo inmediatamente antes de la visualización / rasterización , por lo que esto significa que ninguno de los objetos del juego sabrá sobre la deformación . Esto está bien si simplemente está haciendo un protector de pantalla, o si las deformaciones son tan pequeñas que no tienen impacto en la forma colisionable del objeto.

Cuando deforma la geometría en el sombreador de vértices, los vértices originales del modelo en realidad no se mueven (solo parecen moverse ).

Deformación en vertex shader

No deformado:

no deformado

Deformado

deformado

Esto es del capítulo 6 del tutorial de CG , (programa # 14).

El código de sombreador para producir esta deformación es algo así como

// choose a displacement amount
float displacement = scaleFactor * 0.5 * sin(position.y * frequency * time) + 1 ;

// displace it in the direction of the normal
float4 displacementDirection = float4(normal.x, normal.y, normal.z, 0) ;

// move the vertex
float4 newPosition = position + displacement * displacementDirection ;

// transform (as normal)
oPosition = mul(modelViewProj, newPosition) ;

Como puede ver, esto sucede JUSTO ANTES de la pantalla (el sombreador de vértices ocurre en la GPU), por lo que el código de la CPU prácticamente no tiene forma de acceder a la posición del vértice transformado (hay formas de enviar datos desde la GPU a la CPU (principalmente a través de texturas) pero No iré allí).

bobobobo
fuente
8

Lo que está tratando de lograr es básicamente un subconjunto del tema de la deformación de la malla. Pero como eres un principiante, me temo que este tipo de información podría ser demasiado extraña por ahora. Sin embargo, intentaré establecer las nociones básicas.

Para hacer esto necesitarás dos cosas:

  1. Su malla necesita tener vértices suficientes para que pueda transformar. Por ejemplo, si se trata de un plano, deberá asegurarse de que realmente se crea como una especie de cuadrícula, con muchos vértices para que se deforme. Lo mismo con un cilindro. Podría ser posible lograr esto en tiempo de ejecución con teselación, pero no sé mucho sobre el tema.
  2. Necesitas usar un sombreador de vértices para deformar los vértices. Básicamente, el sombreador de vértices se encarga de calcular la posición transformada final de cada vértice, por lo que puede aprovechar la posibilidad de aplicarles deformaciones.

No estoy seguro de lo útil que será, pero eche un vistazo a este recurso OpenGL, ya que parece ser el tipo de cosa que necesita:

http://www.ozone3d.net/tutorials/mesh_deformer_p3.php#part_3

Captura de pantalla de ese enlace:

ingrese la descripción de la imagen aquí

Editar

Acabo de ver la respuesta de Josh y estoy de acuerdo, la animación esquelética también es una forma muy elegante de encapsular este problema, especialmente cuando sus deformaciones comienzan a ser más complejas y difíciles de representar matemáticamente.

Pero recuerde, los dos puntos anteriores todavía se aplican: solo puede deformar los vértices, por lo que obviamente deben existir en primer lugar, por lo que su malla debe tener una cantidad decente de densidad de vértices. Y generalmente es el sombreador de vértices el que impulsa la animación esquelética y hace la mezcla de vértices y demás.

Y, por cierto, también puedes hacer esto en la CPU, pero hoy en día suele ser una mejor opción hacerlo en la GPU, por eso pongo énfasis en el sombreador de vértices, y debes investigarlo. En realidad, no es mucho más difícil en el programa que hacerlo en la CPU de todos modos.

David Gouveia
fuente