Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Efecto de blending

Iniciado por Drácula, 01 de Enero de 1970, 01:00:00 AM

« anterior - próximo »

Drácula

                                Quier hacer que un sprite cuando pase por encima del fondo, actue como si fuera un foco. Es una especie de LightMap, pero en lugar de utilizar dos texturas en la misma cascada, primero dibujo el fondo, y luego quiero que la siguiente textura que dibujo(que es el sprite) ilumine el fondo.
He probado con:
   s->m_ListaState.Insertar(0, D3DTSS_COLOROP,   D3DTOP_ADD);
   s->m_ListaState.Insertar( 0, D3DTSS_COLORARG1, D3DTA_CURRENT );
   s->m_ListaState.Insertar( 0, D3DTSS_COLORARG2, D3DTA_TEXTURE );

Pero me sale el sprite totalmente blanco, y no hace el efecto que yo espero. ¿Qué es lo correcto?

Por cierto, la textura del sprite tiene Aplha, que se mezcla utilizando:

   EstablecerTextureStageState(0,D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
   EstablecerTextureStageState(0,D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
   EstablecerTextureStageState(0,D3DTSS_ALPHAOP,   D3DTOP_MODULATE );
                               
ltimas mejoras en Merlín: Multitextura.Control y generación automática de LOD.Importa ASE y X. Frustum Clipping por BB.Render añadido de wireframe y del BB.Animaciones por interpolación.Animaciones de textura...
Actualmente:Octree y jerarquías

BeRSeRKeR

                                Puedes crear una textura que simule el cristal y entonces cuando vayas a pintar el sprite que representa el cristal, activas el additive blending

Source y Dest: D3DBLEND_ONE

de esa forma los píxels negros de la textura no se plasmarán en el frame buffer.

Evidentemente todo depende de escoger una buena textura para el cristal...la cual no necesitaría tener canal alpha, por cierto...

Creo que así se podría conseguir el efecto que deseas..

Un saludo
                               
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

BeRSeRKeR

                                Hmm vaya vaya, desde luego tengo que leer mejor las cosas :riendo:
                               
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

BeRSeRKeR

                                Bien veamos...¿lo que quieres es que toda la escena se quede en negro y cuando pase el sprite por encima, sólo ese trozo se ilumine?...si es así crea el lightmap por ejemplo de color blanco y entonces haces:

s->m_ListaState.Insertar(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
s->m_ListaState.Insertar( 1, D3DTSS_COLORARG1, D3DTA_CURRENT );
s->m_ListaState.Insertar( 1, D3DTSS_COLORARG2, D3DTA_TEXTURE );

Pero para que esto funcione, como ves he puesto el stage a 1 porque si no, al hacer el D3DTA_CURRENT pues no se encuentran los colores sobre los que hay que realizar la operación de modulación...así que en el stage 0 deberás poner el fondo...

Ahora, si no quieres hacerlo de una sola pasada supongo que deberías utilizar algún modo de blending...

Un saludo

PD: Si quieres mas brillo, utiliza D3DTOP_MODULATE2X y si aun quieres más pues D3DTOP_MODULATE4X :sonriendo:

_________________
BeRSeRKeR
http://www.planetquake.com/digitalys">DiGiTALYS TEAM

[ Este Mensaje fue editado por: BeRSeRKeR el 2002-04-05 20:32 ]                                
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

BeRSeRKeR

                                Bien, le he estado dando vueltas al efecto del que hablas y he llegado a la conclusión de que lo que te he puesto ahí arriba no funcionará ya que para ello tienes que pintar de una vez fondo y sprite con lo cual tendrías que hacer que el sprite estuviese plasmado en un polígono que tuviese el mismo tamaño del fondo pero con otras coordenadas de textura (para que no ocupase todo el polígono) lo cual como que mejor no hacerlo...porque entre otras cosas necesitarías que tu vértice tuviese dos sets de coordenadas de textura :sonriendo:

La verdad es que te he puesto eso de primeras porque así es como hago yo el lightmapping y bueno pues se me han descruzado los cables (eso es lo que decía mi profesora de biología :riendo:)

Y bueno, seguire pensando a ver si se me ocurre algo.

Un saludo.
                               
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

BeRSeRKeR

                                Bueno, pues he estado trasteando con el efecto del que hablas...y he conseguido algo que podría ser lo que pedías. Te dejo el http://www.arrakis.es/~jonathan01/lightmap.zip">ejecutable con el código y a ver si te sirve de algo.

El programilla que te paso tiene un problema y es que si no limpias el frame buffer de negro, el efecto no es el deseado...pero supongo que será por algún render o texture state...seguiré mirando

Un saludo
                               
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

BeRSeRKeR

                                Para terminar por hoy con este tema, comentaré ciertas limitaciones que se presentan a la hora de utilizar esta técnica tal y como la he intentado implementar.

En principio pasamos a comentarla.

Si no he entendido mal, de lo que se trata es de cubrir la escena con un telo negro y tener un sprite que haga la función de foco de luz por lo que allá por donde pase, "iluminará" el fondo.

De la forma que yo lo he planteado, esto se consigue pintando primero el sprite que hace de foco de luz que se trata de una imagen (JPG) con fondo negro y un flare en el centro con un degradado radial blanco. Seguidamente activamos el alpha blending y especificamos los modos zero para la mezcla fuente y srccolor para la mezcla destino. El motivo de esto es simple...echemos un vistazo a la fórmula de blending:

R(final) = R(source) * 0 + R(destino) * R(source)
G(final) = G(source) * 0 + G(dest) * G(source)
B(final) = B(source) * 0 + B(dest) * B(source)

Bien, RGB(source) es un pixel en una posición determinada del frame buffer correspondiente a la imagen del fondo y RGB(dest) es un pixel en una posición determinada del frame buffer correspondiente a la imagen del foco de luz. Así tenemos que si por ejemplo en una posición determinada nos encontramos con que el pixel source es rojo (1, 0, 0) y el pixel destino es blanco (1, 1, 1) (precisamente el blanco del foco de luz) pues tenemos que aplicando la fórmula obtenemos el siguiente color final

RGB(final) = (1, 0, 0) * (0, 0, 0) + (1, 1, 1) * (1, 0, 0) = (1, 0, 0)

es decir rojo como era de esperar...

Seguimos...una vez activado el alpha blending, pintamos la imagen de fondo y ya está, ya hemos conseguido lo que buscábamos. En el post anterior mencioné que si no se limpiaba el frame buffer de color negro, la mezcla no se realizaba correctamente. Esto es lógico si tenemos en cuenta que primero pintamos el foco de luz el cual debe pintarse sobre negro para que posteriormente el blending tenga el efecto deseado.

Pero ahora se presentan problemas...y es que evidentemente, querremos que en nuestra pantalla no sólo haya un foco y un fondo sino que querremos que sobre ese fondo hayan otros sprites que también estén afectados por la oscuridad o por la luz (si sobre ellos está el foco de luz) y es aquí, a la hora de pintar los otros sprites donde se presenta el problema. ¿Por qué?...pues porque imagináos que queremos un sprite con oquedades (como al fin y al cabo son los sprites). Una solución podría ser realizar color keying...la otra sería activar el alpha test...¿pero qué pasa si queremos que nuestro sprite tenga un cierto grado de translucidez?...pues que evidentemente tendremos que activar el alpha blending con las funciones srcalpha fuente e invsrcalpha para el destino con lo cual ese sprite al que se le aplica dicho blending ya no se encontrará en la oscuridad sino que estará "sobre ella", es decir, ni le afectará la oscuridad y ni le afectará el foco de luz...

Y bien, ahora mismo no me encuentro con ganas de seguir pensando sino más bien de echarme una partidilla al quake3 :sonriendo:) y aportáis algún otro punto de vista para llevar a cabo el efecto que tratamos y solucionar así el problema expuesto.

Un saludo.
                               
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

mallrat

                                Drácula, no termino de pillar lo que quieres hacer, el fondo es uno sola imagen o es una composicion con muchos sprites? hay solo un foco o varios? el resto que no esté en el area del foco tiene que quedar negro o con el color original del fondo? la iluminación del fondo sería sumando, por ejemplo, color blanco, o como si fuera un foco real de luz, o como? puedes poner alguna imagen del fondo y de lo que quieres usar de foco, canal alpha, etc. para que nos hagamos una idea? y también el resultado final que buscas, hecho con el photoshop o lo que sea. Venga, un saludo.
                               

Drácula

                                Gracias por la ayuda.
Tu demo berserker es correcto pero como tu bien dices...¡al reves!

Primero DEBO dibujar el fondo y después el sprite que se dibuja encima es el que hace el efecto.
Ahora no puedo estudiar el tema, tengo que ir a trabajar, pero espero hoy solventarlo con vuestra ayuda y en cuanto esté resuelto lo pondré aquí para que todo el mundo pueda utilzarlo.
                               
ltimas mejoras en Merlín: Multitextura.Control y generación automática de LOD.Importa ASE y X. Frustum Clipping por BB.Render añadido de wireframe y del BB.Animaciones por interpolación.Animaciones de textura...
Actualmente:Octree y jerarquías

Drácula

                                Bien, pues la solución es:

   s->m_ListaState.Insertar(LISTA_STAGE_RENDERSTATE,D3DRS_SRCBLEND,D3DBLEND_SRCCOLOR);
   s->m_ListaState.Insertar(LISTA_STAGE_RENDERSTATE,D3DRS_DESTBLEND,D3DBLEND_ONE );

Muchas gracias a todos, ahora ya entiendo perfectamente el blending, y sobre todo a Berserker, que incluso me ha mandado código fuente! Si seguimos así ayudándonos, seguro que aprenderemos todos un montón.

                               
ltimas mejoras en Merlín: Multitextura.Control y generación automática de LOD.Importa ASE y X. Frustum Clipping por BB.Render añadido de wireframe y del BB.Animaciones por interpolación.Animaciones de textura...
Actualmente:Octree y jerarquías

BeRSeRKeR

                                De nada...creo que así aprendemos todos algo nuevo cada vez. Me alegro de que lo hayas solucionado.

Un saludo
                               
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!






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.