Comencemos con lo básico.
Por lo general, desea transformar sus vértices del triángulo locales a través de los siguientes pasos:
local-space coords-> world-space coords -> view-space coords -> clip-space coords
en la norma GL, las 2 primeras transformaciones se realizan a través GL_MODELVIEW_MATRIX
, el tercero se realiza a través GL_PROJECTION_MATRIX
Estas transformaciones de vista de modelo, para las muchas transformaciones interesantes que generalmente queremos aplicar (por ejemplo, traducir, escalar y rotar, por ejemplo), se pueden expresar como multiplicación de matriz de vectores cuando representamos vértices en homogeneous coordinates. Normalmente, el vértice V = (x, y, z)
se representa en este sistema como (x, y, z, 1)
.
Ok. Digamos que queremos transformar un vértice V_local a través de una traducción, luego una rotación, luego una traducción. Cada transformada se puede representar como una matriz *, llamémoslos T1, R1, T2. Queremos aplicar la transformación a cada vértice: V_view = V_local * T1 * R1 * T2
.La multiplicación de la matriz es asociativa, podemos calcular de una vez por todas M = T1 * R1 * T2
.
De esta manera, solo tenemos que pasar M al programa de vértices y calcular V_view = V_local * M
. Al final, un sombreador de vértices típico multiplica la posición del vértice por una sola matriz. Todo el trabajo para calcular esa matriz es cómo mueve su objeto del espacio local al espacio del clip.
Ok ... Eché un vistazo a una serie de detalles importantes.
En primer lugar, lo que describí hasta ahora solo cubre la transformación que generalmente queremos hacer hasta el espacio de visualización, no el espacio de clip. Sin embargo, el hardware espera que la posición de salida del sombreador de vértices se represente en ese espacio de clips especial. Es difícil explicar las coordenadas de espacio de clip sin matemática significativa, así que lo dejo fuera, pero lo importante es que la transformación que trae los vértices a ese espacio de clip usualmente se puede expresar como el mismo tipo de multiplicación de matriz. Esto es lo que calculan los antiguos gluPerspective, glFrustum y glOrtho.
En segundo lugar, esto es lo que aplica a las posiciones de los vértices. La matemática para transformar las normales es algo diferente. Esto se debe a que desea que la normal permanezca perpendicular a la superficie después de la transformación (para referencia, requiere una multiplicación por la transposición inversa de la vista de modelo en el caso general, pero eso se puede simplificar en muchos casos)
Tercero, nunca se envían coordenadas 4-D al sombreador de vértices. En general, pasas los 3-D. OpenGL transformará esas coordenadas 3-D (o 2-D, btw) en 4-D para que el sombreado de vértices no tenga que agregar la coordenada extra. expande cada vértice para agregar el 1 como la coordenada w
.
Entonces ... para volver a unir todo eso, para cada objeto, necesita calcular esas matrices M mágicas basadas en todas las transformaciones que desea aplicar al objeto. Dentro del sombreador, debes multiplicar cada posición de vértice por esa matriz y pasarla a la salida de posición del sombreador de vértices. código típico es más o menos (esto es utilizando la nomenclatura antigua):
mat4 MVP;
gl_Position=MVP * gl_Vertex;
* las matrices reales se pueden encontrar en la web, sobre todo en las páginas del manual para cada una de esas funciones: rotate, translate, scale, perspective , ortho
¡Gracias por la gran respuesta! Un detalle que me había perdido fue que puedes cambiar la matriz MVP (por ejemplo, declararla uniforme) entre llamadas a glDrawElements ... Extraño cambio de khronos para dejar la especificación de estas matrices muy comunes para el programador. Espero que encuentren su camino hacia el glu o similares pronto ... – Wonko
Para eso es el middleware. GL3.2 es menos expresivo para una codificación rápida. Pero las versiones anteriores eran el nivel incorrecto de abstracción para la aplicación real de todos modos. Requería un marco de gestión estatal además. Además, supongamos que quieres mantener matrices. Eso significa que el controlador tiene que mantener todas las pilas de la matriz, cómo pasarlas solo a _all_ shaders que lo requieren (no solo el vértice), descubrir qué sabor necesita - M, MV, MVP, IT (MV), IT (M) La peor parte ? la aplicación es la única que puede hacer que las matemáticas sean eficientes al ejecutar muchas operaciones matriciales a la vez. GL no puede hacer eso de manera eficiente. – Bahbar