smcameron / gaseous-giganticus

This program procedurally generates gas giant cubemap textures for the game Space Nerds In Space. https://www.patreon.com/smcameron

Home Page:https://smcameron.github.io/space-nerds-in-space/gaseous-giganticus-slides/slideshow.html#1

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Color mixing is done with floats, and is a bottleneck

smcameron opened this issue · comments

Color blending is done by converting bytes to floats, mixing, then converting floats back to bytes. Additionally, color blending is a bottleneck in the program.

I have a strong suspicion this could all be speeded up a little bit by using fixed point arithmetic to do the blending, perhaps something like this: https://www.reddit.com/r/GraphicsProgramming/comments/qczmbi/can_someone_walk_me_through_why_this_blender_works/

uint32 blend(uint32 color1, uint32 color2, uint8 alpha) {
    uint32 rb = color1 & 0xff00ff;
    uint32 g  = color1 & 0x00ff00;
    rb += ((color2 & 0xff00ff) - rb) * alpha >> 8;
    g  += ((color2 & 0x00ff00) -  g) * alpha >> 8;
    return (rb & 0xff00ff) | (g & 0xff00);
}

I have not tried the above code, but I have tried this, below:

static struct color combine_color(struct color *oc, struct color *c)
{
        unsigned int alpha = oc->a + 1;
        unsigned int inv_alpha = 256 - alpha;

        struct color nc;

        nc.a = (c->a + oc->a * (256 - c->a)) >> 8;
        nc.r = (unsigned char) (alpha * oc->r + inv_alpha * c->r) >> 8;
        nc.g = (unsigned char) (alpha * oc->g + inv_alpha * c->g) >> 8;
        nc.b = (unsigned char) (alpha * oc->b + inv_alpha * c->b) >> 8;
        return nc;
}

but so far have not got anything working. In theory, using fixed point math for the color mixing rather than floating point should be an easy win.