Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Shadow Volumes con proyección ortogonal

Iniciado por SergiDíaz, 17 de Mayo de 2007, 12:51:25 PM

« anterior - próximo »

SergiDíaz

Buenas a todos.

Antes de nada presentarme, ya que acabo de descubrir este foro. Soy de Barcelona y trabajo de programador para una empresa de desarollo de software gráfico.

Ahora mismo estoy desarrollando un renderizador no fotorealistico básado en OpenGL, concretamente es la segunda versión del producto.

Pues bien, entre otras características, le estoy añadiendo la posibilidad de renderizar con sombras proyectadas. He optado por shadow volumes usando el stencil a diferencia de shadow maps porque al ser un render para programas de diseño la geometría puede ser muy variada (objetos abiertos, cóncavos y convexos, escensa grandes o pequeñas, etc.), además de que me iba mejor este algoritmo para mezclarlo con lo que ya tenía hecho.
El hecho es que ya lo tengo hecho y me funciona... en proyección perspectiva, que es para lo que está pensado. El problema es que el usuario también puede querer hacer un render de una vista que esté en proyección paralela, y aquí es dónde me encuentro un problema.

Para renderizar con shadow volumes, tenemos que colocar el plano de corte posterior ("far plane") en el infinito, porque sino nos corta los volúmenes de sombra y el algoritmo no funciona (Aquí lo explica bastante bien). Para ello cambio la matriz de proyección típica; en los campos dónde encuentro "far" calculo el límite cuando tiende a infinito y lo sustituyo por el valor que me da. En vez de usar las llamadas glFrustrum o glOrtho calculo yo manualmente la matriz de proyección y la aplico usando glMatrixMode, glLoadIdentity y glMultMatrixf.

Felicidades si has conseguido leer hasta aquí y entender todo lo que he escrito, por cierto :P.

Pues bien, con proyección perspectiva me funciona correctamente, pero con proyección paralela no me pinta absolutamente nada, como si todo quedara fuera de los planos de corte.

La matriz de proyección ortogonal se supone que es la siguiente:

2 / (right - left) 0 0 - (right+left) / (right-left)

0 2 / (top - bottom) 0 - (top+bottom) / (top-bottom)

0 0 -2 / (far - near) - (far+near) / (far-near)

0 0 0 1


Aunque en la web de Microsoft en vez de ese 1 pone un -1. Da igual, lo he probado de ambas maneras.

Al hacer que far sea infinito, me queda la siguiente matriz:


2 / (right - left) 0 0 - (right+left) / (right-left)

0 2 / (top - bottom) 0 - (top+bottom) / (top-bottom)

0 0 0 -1

0 0 0 1


Y con esta matriz no me pinta absolutamente nada en la escena.

¿Alguien puede ayudarme?

Muchísimas gracias.

-Sergi Díaz
url=www.penguin3d.com]Mi "hijo"[/url]

SergiDíaz

Y ahora es cuando me doy cuenta que estaba multiplicando en un sitio en el que tenía que dividir :roll: .

Pero sigo teniendo problemas, tranquilos. Pintar pinta, pero las sombras son lo más impreciso que he visto en mi vida. No veía tantos artefactos desde la última vez que intente hacer un dibujo a mano.
url=www.penguin3d.com]Mi "hijo"[/url]

josepzin


SergiDíaz

Gracies ;).

Sigo haciendo pruebas. Ahora en vez de poner el far en el infinito lo incremento e intento "tapar" los shadow volumes antes de que el far los corte, pero asegurándome siempre de que la escena entera queda dentro. Es más lento, pero como estoy haciendo un render y no una aplicación en tiempo real puedo permitírmelo.
Claro que a este paso me saldrá más a cuenta hacer raytracing :P.
De momento me peta, modo debug activado :D.
url=www.penguin3d.com]Mi "hijo"[/url]

Prompt

Una pregunta, imagino que has caido en el asunto.

Cuando mentas que en la web de microsoft en la matriz pone un -1... ¿ tienes en cuenta que microsoft / DirectX no maneja las matrices como OpenGL ?

Si no recuerdo mal le llaman left-aligned y right-aligned.

Topper

CitarSi no recuerdo mal le llaman left-aligned y right-aligned.

Creo que te refieres a Left Handed y Right Handed. OpenGL usa ésta última, al igual que el nuevo framework de Microsoft XNA...

SergiDíaz

Bueno, de hecho estoy usando OpenGL. Cuando hablaba de la web de Microsoft, me refería al MSDN y la información sobre las llamadas glFrustum y glOrtho, que muestran la matriz de proyección para cada caso. Aunque sea Microsoft, no es información sobre DirectX.
Gracias por el aviso de todas formas, no estoy muy ducho en DirectX.
url=www.penguin3d.com]Mi "hijo"[/url]

Elvis Enmanuel

/// Construct a orthogonal projection matrix
   template<typename type>
   void orthoProjection(type left,type right,type top,type bottom,type zNear,type zFar) {
   type rl = right - left;
   type tb = top - bottom;
   type fn = zFar - zNear;

       M00=(2/rl); M01=0;      M02=0;       M03=-(right + left) / rl;
       M10=0;      M11=(2/tb); M12=0;       M13=-(top + bottom) / tb;
       M20=0;      M21=0;      M22=-(2/fn); M23=-(zFar + zNear) / fn;
       M30=0;      M31=0;      M32=0;       M33=1;
   }

Recuerda que en openGL (si haces tú el cálculo) tienes que transponer la matriz de proyección (solo esta última) antes de pasársela con el glLoadMatrixfv();

ains






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.