Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Sobre Direct3D

Iniciado por synchrnzr, 21 de Enero de 2009, 08:23:47 PM

« anterior - próximo »

synchrnzr

Sí,  no me he perdido, estoy en Programación Gráfica :P

Como no domino demasiado este tema, tengo una duda que igual es un poco absurda, pero en fin... Tengo una escena y quiero renderizarla desde dos puntos de vista distintos. Por la forma en que se dibujan las cosas, supongo que tengo que limpiar los buffers y volver a crear toda la escena. ¿Existe algún modo de guardar todo lo que hago mientras creo la primera escena para poderlo repetir de forma más eficiente? Ahora mismo estoy trabajando basándome en lo segundo pero, obviamente, el rendimiento es un poco chungo.

Ya os contaré cuando pueda de qué va el rollo ;)

sync

Prompt

Puedes renderizar en algun buffer acelerador por hardware auxiliar, hay decenas. Renderizar a textura y hacer "bind" de la textura en 2 quads (para ver 2) o crear 2 viewport... o...... mil cosas :P

Necesitas double buffering? o la escena está quieta?

synchrnzr

Perdón por mi ignorancia, lo único que sé de gráficos es lo que estudié en la Uni y fue hace tiempo ya y con OpenGL (aun así, veo que los principios vienen a ser los mismos, jeje) No es que Direct3D sea muy complicado, pero no lo tengo muy por la mano.

La escena es animada, pero eso es bastante irrelevante. En lo de los viewports pero no sé muy bien como funciona en Direct3D ¿Puedo crear un viewport para cada perspectiva de manera que cada cosa que dibuje se dibuje con su transformación correspondiente? De ser así, sería la solución óptima a mi problema, está claro. Voy a echarle un ojo más a fondo :)

sync

Prompt

No tengo ni idea que implica y que es exactamente una "perspectiva" en Direct3D. Y no quiero pensarlo :P que puede ser peor.

El caso es que puedes hacer varias cosas:
- Renderizar en diferentes buffers auxiliares acelerados por hardware.
- Render a Textura, PBO
- Frame Buffer Object. FBO

En cualquier caso de estos, debes crear 2 viewports, no se como se hace en D3D. Y yo lo que haría seríaan 2 QUAD en la pantalla, en proyeccion ortonormal (en 2D) y hacer "bind" de la textura o frame en cuestion.

Con los buffers auxiliares: en opengl existe "swapbuffer" que coge el buffer BACK y lo pone en el FRONT, que es el que vemos en la ventanita. Podrias coger y hacer de AUX_1 a FRONT, pero claro para 2 viewport no se como se "juntarian", es decir, crear un viewport no es mas que decirle al driver que pille un cacho de pantalla y pinte ahi nada más. Pero el "swapBuffer" de lo que sea aplastaría eso mmmmmmmmm...

Mi solución es FBO y 2 QUAD, yo uso 1 para el HDR, para sus filtros. No te puedo ayudar más con la teoría porque de D3D ni idea.

AK47

Lo que quieres hacer es guardar la "foto" de la escena, o aprovechar los calculos que se han hecho en el primer renderizado? Si es la primera opcion, debes renderizar la primera escena a un RenderTarget (e igual la segunda tambien, si lo necesitas). Para estas cosas D3DX dispone de algun clase.

Si es la segunda opcion, no hay tu tia, tienes que enviar otra vez todo a la tarjeta grafica, ya que se cambia la camara y hay que renderizarlo todo.

synchrnzr

Es lo segundo. Parto de que hay que volver a renderizarlo todo como dices, lo que a nivel de CPU me resulta muy costoso porque necesito renderizar el mismo frame 3 veces desde 3 cámaras distintas para calcular lo que quiero. Lo más interesante que he encontrado al respecto son los MRTs:

CitarMultiple Render Targets (MRT) refers to the ability to render to multiple surfaces (see IDirect3D9Surface) with a single draw call.

Pero tampoco parece que sirva para eso. En fin, algo haremos...

sync

senior wapo

Dirty rects (ajustando frustrum) y MRTs con lo poco que cuentas.

Si puedes ser un poco más específico con lo que pretendes conseguir tal vez pueda ayudarte con más detalles.

synchrnzr

Básicamente tengo una escena que tengo que renderizar con la cámara en un punto, hacer unos cálculos con los datos del depth buffer y volver a renderizarla reubicando las cámaras en otros dos puntos distintos en función de los resultados. Al tirar tantas veces el mismo frame se pierde un huevo de rendimiento, estoy buscando una manera de optimizarlo, por poco que se pueda.

sync

AK47

Podrias calcular la malla resultante una vez y enviarselo a la tarjeta tantas veces como sea necesario, pero no se si al final tendras la misma perdida o mas de rendimiento que haciendolo 3 veces

synchrnzr

Será cuestión de probar, como todo en la vida ;)

sync

pacomix

   Voy a mirar mañana en un código que tenía de hace un par de años cuando estuve trasteando con el direct3D. Básicamente si no creo recordar mal tenías que definir una RenderSurface (que definías con una cantidad de píxeles de anchoXalto) y hacerle ahí el render para luego aplicárselo a un quad como antes dijo Prompt (saludos desde Berlín ex-compi). Lo que ignoro es si ahí ya DirectX te optimiza todo lo que pueda con la tarjeta.

¡Un saludete!
=El verdadero guerrero de la luz se levanta cuando todos los demás han caído=-

Prompt

Cita de: pacomix en 26 de Enero de 2009, 11:59:45 PM
   Voy a mirar mañana en un código que tenía de hace un par de años cuando estuve trasteando con el direct3D. Básicamente si no creo recordar mal tenías que definir una RenderSurface (que definías con una cantidad de píxeles de anchoXalto) y hacerle ahí el render para luego aplicárselo a un quad como antes dijo Prompt (saludos desde Berlín ex-compi). Lo que ignoro es si ahí ya DirectX te optimiza todo lo que pueda con la tarjeta.

¡Un saludete!

Joé que lejos te has ido! :D, debe hacer tela de rasca por allí xD Que estas haciendo tan lejillos?

El caso es que, aunque uses FBO y renderices en 2 quad, tienes el problema de optimizar. Si cambias la cámara de posición no puedes re-aprovechar nada, he ahí el dile de calcular mas de una sombra, o mejor dicho, poner más de una luz que proyecte sombra. La GPU directamente se muere. Evidentemente no hace falta renderizarlo todo.

Como primer paso, yo cogería el estado actual del programita y quitaría cosas como pintar en el buffer de color, etc... una vez hagas los calculos desde 3 puntos diferentes ya renderizas... Con lo cual despues de calcular lo que sea, te puedes quedar con un buffer de información de lo que sea y aplicarlo a la escena. Es decir:

Algo comooo:
1- ...
- SwapBuffer
2- Dejas solo activado "pintar" en el buffer de profundidad ( o lo que quiera que estés haciendo )
3- Bind FBO_____n
4- setCameraPosition_______n(...)
5- Shader Begin
6- Draw
7- Shader End
8- Bind FBO OFF______n
9- Repetir desde el paso 3 las veces que sea necesario
10- Bind FBO_LEFT
11- setCameraPosition LEFT
12- draw
13- UnBind FBO_LEFT
10- Bind FBO_RIGHT
12- setCameraPosition RIGHT
13- Aqui haces lo que demonios sea que quieras hacer con los anteriores FBOs... que como no podemos saberlo este flujo de programacion puede estár mal y no necesitarse este paso.
14- UnBind FBO_RIGHT

15- Reset Camera, en ORTHO -(2D) y Activas el pintar en el buffer de color, etc...
16- bindTextureFBO(FBO_LEFT)
17- DrawQUAD_LEFT
18- Unbind...
19- bindTextureFBO(FBO_RIGHT)
20- DrawQUAD_RIGHT
21- Unbind...
-> GO TO "1"

El pintar el FBO RIGHT, no se que quieres hacer con esa información de las 3 camaras así que eso puede cambiar y ni siquiera necesitarse usar otro FBO pero bueno...

synchrnzr

Graciasa todos. Finalmente he conseguido optimizar un poco basándome en que del buffer de profundidad sólo necesitaba unos píxels, así que en principio sólo renderizo un área minúscula y me ahorra bastante cálculo. Probaré a desactivar lo de pintar el color, que seguro que ayuda un poco. No, si al final funcionará y todo... >:D

sync

Prompt

Cita de: synchrnzr en 28 de Enero de 2009, 11:15:20 AM
Graciasa todos. Finalmente he conseguido optimizar un poco basándome en que del buffer de profundidad sólo necesitaba unos píxels, así que en principio sólo renderizo un área minúscula y me ahorra bastante cálculo. Probaré a desactivar lo de pintar el color, que seguro que ayuda un poco. No, si al final funcionará y todo... >:D

sync

Queremos saber que haces!  :grrr:

synchrnzr

Bueno, pues pensaba yo que tenía el tema bastante solucionado, pero resulta que ahora tengo un problema un poco jodido que no pensaba que lo fuera a ser tanto. El caso es que no consigo leer los valores del Depth Buffer. Según la documentación de DirectX, debería poder crear una surface y copiar el contenido del Depth Buffer en ella, pero el UpdateSurface() no va. Es probable que sea por el formato de los píxeles, aunque de ser así estaría apañado, porque eso no lo puedo tocar :'(

¿Alguna vez habéis tenido que leer valores de profundidad de los píxeles con DirectX? ¿Hay alguna alternativa para saber qué profundidad tiene un pixel concreto?

CitarQueremos saber que haces!

Joer, qué cotillos :D

Se trata de un driver que intercepta las llamadas a DirectX y genera las imágenes 3D desde puntos de vista distintos. Por eso no puedo poner el formato de Depth Buffer que me dé la gana y por eso me supone un coñazo renderizar la escena desde distintos puntos de vista; tengo que capturar toda la geometría y reproducirla (aunque cueste creerlo, esto no tiene nada que ver con la ingeniería inversa :..)

Actualmente lo estoy probando con el Star Wars Battlefront II, que usa un DepthStencilBuffer con 24 bits de profundidad y 8 de stencil, por ejemplo.

sync






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.