User Tag List

Resultados 1 al 11 de 11

Tema: Una ayuda mezclando colores

  1. #1

    Fecha de ingreso
    Feb 2005
    Mensajes
    1,120
    Mencionado
    7 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    60
    Agradecer Thanks Received 
    84
    Thanked in
    Agradecido 50 veces en [ARG:2 UNDEFINED] posts

    Una ayuda mezclando colores

    Buenas, tengo un problemilla de rendimiento a la hora de suavizar texturas, y estoy buscando una forma de suavizarla que sea mas rapida.
    Digamos que tengo los 6 puntos de la primera imagen, y necesito colorear el espacio intermedio.
    La forma que mas rapida me va, es la de no interpolar y pintar la mitad de cada color.
    Interpolando el color de cada punto en funcion de la distancia a cada vertice da una resultado impresionante, pero es MUY lento, al menos con las funciones que uso de una-i para hacer blend entre dos colores RGB565.
    Lo que busco es hacer una especie de "dither", aunque sea de baja calidad, para mezclar los colores, ahorrando crear otros nuevos. Adjunto tambien imagen de el dither que hablo, aunque no necesito que sea de tanta calida claro.
    ¿Alguien sabe una forma rapida de conseguir esto? La funcion que uso ahora para hallar el color del punto es GE_BlendColors565(color1, color2, porcentaje)
    Gracias
    Imágenes adjuntadas Imágenes adjuntadas     

  2. #2

    Fecha de ingreso
    Sep 2006
    Ubicación
    Malaga
    Mensajes
    8,153
    Mencionado
    48 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    1,942
    Agradecer Thanks Received 
    2,352
    Thanked in
    Agradecido 1,565 veces en [ARG:2 UNDEFINED] posts
    Con dithering siempre sera mas lento, si interpolas el color sin "desempaquetarlo" ira mas rapido pero tendra un poco menos de calidad... pon el codigo de la funcion y se podra ver que se puede mejorar.

  3. #3

    Fecha de ingreso
    Feb 2005
    Mensajes
    1,120
    Mencionado
    7 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    60
    Agradecer Thanks Received 
    84
    Thanked in
    Agradecido 50 veces en [ARG:2 UNDEFINED] posts
    Intente encontrar una manera de interpolar el color directamente, sin descomponerlo, pero no se me ocurrio como :S
    La funcion esta sacada de aqui: http://www.flipcode.com/archives/Col...pulation.shtml
    Y es esta:
    //----------------------------------------------------------------------
    // Use: Make a 32 levels alfa blend betwen two 565 colours.
    // Returns: The blended colour.
    // Parameters: iAlfa=0 Only c1 is set, iAlfa=32 only c2 is set
    //----------------------------------------------------------------------
    __inline unsigned GE_BlendColors565( const unsigned c1, const unsigned c2, int iAlfa)
    {
    unsigned ta = c1 & MASCARA_A; // 0000__g1__
    unsigned tb = c2 & MASCARA_B; // 0000r2__b2

    ta *= (32-iAlfa);
    tb *= ( iAlfa);

    ta += ( iAlfa) *(c2 & MASCARA_A); // 0000__g2__
    tb += (32-iAlfa) *(c1 & MASCARA_B); // 0000r1__b1

    ta = (ta>>BITS_BAJOS) & MASCARA_A;
    ta += (tb>>BITS_BAJOS) & MASCARA_B;

    return(ta);
    }
    (En el link salen los defines que faltan)

    A mi me daba la impresion que el dithering seria mucho mas rapido, digamos que la funcion que te dice el color en funcion de un parametro, lo calcularia a partir de un valor predefinido.
    El problema es que no se como calcular ese valor predefinido. Habia pensado crear un vector tal que asi (de 16 niveles por ejemplo): [1110110101001000] y si le pido el nivel 0, devolveria el color de la derecha pq hay un 1, si le pido el nivel 3 devolveria el de la izquierda, y asi...pero sale un bodrio
    Si se pudiese hacer algo asi, se podrian implementar en un numero de 16 o 32bits en vez de un vector, y aun iria mas rapido
    Última edición por anibarro; 18/03/2008 a las 21:43

  4. #4

    Fecha de ingreso
    Jun 2004
    Ubicación
    Malaga
    Mensajes
    2,601
    Mencionado
    10 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    7
    Agradecer Thanks Received 
    43
    Thanked in
    Agradecido 39 veces en [ARG:2 UNDEFINED] posts
    y no has pensado en hacer una escala menos suave? se ve que con el blend recalculas todos los colores pero yo pienso que con calcular unos pocos y hacer alguna media con los restantes deberia quedar decente, es que con lo del "porcentaje" creo que se va un buen pico de CPU y recurrir a ella menos es lo suyo.

    Quizad lo que te interese sea mas algún calculo de filtrado bilinear, quizad mirando el codigo de algun que otro emulador puedas sacar algo util.

  5. #5

    Fecha de ingreso
    Feb 2005
    Mensajes
    1,120
    Mencionado
    7 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    60
    Agradecer Thanks Received 
    84
    Thanked in
    Agradecido 50 veces en [ARG:2 UNDEFINED] posts
    Darumo no se cuanto ayudaria eso...en realidad lo que hace es filtrado bilinear, y el porcentaje solo tiene 32 niveles, no creo que bajarlo mas ayudase mucho :/
    Adjunto 3 imagenes, una sin filtrado, otra con filtrado bilinear y otra con el cutre dither que probe...la idea es encontrar un dither que sea rapido y no quede tan mal como ese :/
    Yo busco conseguir algo como este dithering: http://www.flipcode.com/archives/Rea...rovement.shtml
    Imágenes adjuntadas Imágenes adjuntadas    
    Última edición por anibarro; 18/03/2008 a las 23:46

  6. #6

    Fecha de ingreso
    Sep 2006
    Ubicación
    Malaga
    Mensajes
    8,153
    Mencionado
    48 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    1,942
    Agradecer Thanks Received 
    2,352
    Thanked in
    Agradecido 1,565 veces en [ARG:2 UNDEFINED] posts
    Ahi va mi dithering que hice el siglo pasado...

    Código:
    #include "dither.h"
    #define ABS(x) ((x>0)? ( x) : (-x) )
    #define SGN(x) ((x<0)? (-1) : ( 1) )
    
    #define SCREEN_ADR 0xa000
    #define SCREEN_ADR_LIN ((SCREEN_ADR) << 4 )
    
    void DitherUp(int xi, int xf, int y, unsigned ci, unsigned cf)
    {
        char *screen;
    
        long dcolor;
        short int icolor,error;
        short unsigned color;
        char c;
    
        screen=(char *)SCREEN_ADR_LIN+xi+y*320;
        c=ci>>8;
        dcolor=((long)(cf-ci)<<8) / (xf-xi);
        icolor=(dcolor>>16);
        dcolor&=0xffff;
    
        color=ci<<8;
        error=0x8000;
    
        while (xi<=xf) {
            if ( (error+=(color>>1)) >0 ){
                error+=0x8000;
                *screen++=(c+1);
            } else
                *screen++=c;
    
            c+=icolor;
            if ((color+=dcolor) < dcolor)
                c++;
            xi++;
        }
    }
    
    void DitherDown(int xi, int xf, int y, unsigned ci, unsigned cf)
    {
        char *screen;
    
        long dcolor;
        short int icolor,error;
        short unsigned color;
        char c;
    
        screen=(char *)SCREEN_ADR_LIN+xf+y*320;
        c=cf>>8;
        dcolor=( (long) (ci-cf)<<8 ) / (xf-xi);
        icolor=(dcolor>>16);
        dcolor&=0xffff;
    
        color=cf<<8;
        error=0x8000;
    
        while (xi<=xf) {
            if ( (error+=(color>>1)) >0 ) {
                error+=0x8000;
                *screen--=(c+1);
            } else
                *screen--=c;
    
            c+=icolor;
            if ((color+=dcolor) < dcolor)
                c++;
    
            xi++;
        }
    }
    
    void DitherSpan(short xi, short xf, short y, short unsigned ci, short unsigned cf)
    {
        if(xi<xf)
            ((ci<=cf)? DitherUp(xi,xf,y,ci,cf) : DitherDown(xi,xf,y,ci,cf) );
    }
    uff, cuantos comentarios, ya se sabe, si costo programarlo debe costar entenderlo...

    Un par de cosas, como se ve esta hecho para el modo 0x13, pero no creo que tengas muchos problemas en cambiarlo, incluso en usar colores leyendolos de una tabla.

    Hay dos rutinas una para hacer el dithering hacia arriba (con colores cada vez mayores o con un incide mayor), y otra hacia abajo. Se supone que estas dos versiones serian privadas, el usuario solo usaria DitherSpan.

    En el codigo veras cosas un poco raras como los 0x8000, esto es porque la primera version la hice en ensamblador del 68000 y las rutinas usaban el bit de carry, como en C no puedes hacer saltos dependiedo de los bits de estado hay que hacer estas chapucillas.

    Los parametros son los siguientes:
    • xi : coordenada x Inicial...
    • xf : coordenada x final, siempre mayor que xi
    • y : coordenada y de la linea horizontal con dithering
    • ci : color inicial (16 bits), se supone que el byte alto es el indice del color o a una tabla, la parte baja serian la parte decimal del color
    • cf: color final, igual que el inicial
    Para hacer dithering en un cuadrado asegurate de que la parte decimal del color varia, o apareceran unas lineas verticales.

    No tengo imagenes de como queda pero si has visto la intro del Interfase del Atari ST (el cubo con sombreado gouraud), es exactamente igual... la saque de ahi

  7. #7

    Fecha de ingreso
    Feb 2005
    Mensajes
    1,120
    Mencionado
    7 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    60
    Agradecer Thanks Received 
    84
    Thanked in
    Agradecido 50 veces en [ARG:2 UNDEFINED] posts
    Ahora veo porque decias que iba a ser mas lento xD Muchas gracias pero necesito algo mucho mas simple Creo que al final se quedara sin filtrar...

  8. #8

    Fecha de ingreso
    Dec 2004
    Mensajes
    28,655
    Mencionado
    204 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    192
    Agradecer Thanks Received 
    2,658
    Thanked in
    Agradecido 1,654 veces en [ARG:2 UNDEFINED] posts
    Entradas de blog
    11
    &#191;Y se puede saber que estas haciendo para la 2x? es que tiene una pintaza...
    Google stadia es un fracaso, google stadia funciona mal, google admite su fracaso con stadia la latencia es el problema intrinseco de stadia, el público abandona google stadia, stadia mal.

  9. #9

    Fecha de ingreso
    Feb 2005
    Mensajes
    1,120
    Mencionado
    7 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    60
    Agradecer Thanks Received 
    84
    Thanked in
    Agradecido 50 veces en [ARG:2 UNDEFINED] posts
    De momento solo estoy viendo si es viable hacer una especie de remake del outcast, pero hasta que no acabe de a&#241;adirle cosas y empiece a optimizar no lo sabre...
    No tengo la gp2x, por lo que lo estoy haciendo las pruebas en un gps con un ARM9 y 64MB. Esta todo programado a partir de un acceso directo al buffer de la pantalla, por lo que compilarlo para la GP2X serian 2 minutos

  10. #10

    Fecha de ingreso
    Dec 2005
    Ubicación
    Berlin
    Mensajes
    96
    Mencionado
    0 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    0
    Agradecer Thanks Received 
    0
    Thanked in
    Agradecido 0 veces en [ARG:2 UNDEFINED] posts
    Uau! un remake del outcast! seria increible.
    Pero el outcast original necesitava un pentium 3 a 500Mhz con 128 megas para ir bien... aunque si le quitas todos los efectos...
    http://canuda.net - Das Experimental Kunstwerk
    http://canuda10.blogspot.com - GP2X development

  11. #11

    Fecha de ingreso
    Jan 2005
    Ubicación
    Esquina inferior derecha(almeria)
    Mensajes
    798
    Mencionado
    1 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    0
    Agradecer Thanks Received 
    0
    Thanked in
    Agradecido 0 veces en [ARG:2 UNDEFINED] posts
    aunque sea sin filtrar ya mereceria la pena

Permisos de publicación

  • No puedes crear nuevos temas
  • No puedes responder temas
  • No puedes subir archivos adjuntos
  • No puedes editar tus mensajes
  •