From 6f620238505b4143c2bc4074d527e2d5ea82370a Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Fri, 17 Feb 2006 15:44:46 +0000 Subject: [PATCH] - Added option 'convert to premul' to AlphaOver node in Compositor - Fixed mix mode "Overlay", it was missing a multiplication with 2 :) - small bugix in Matts nodes commit, wrong pointers transfered to coltobw() --- source/blender/blenkernel/intern/material.c | 12 ++-- .../blenkernel/intern/node_composite.c | 60 ++++++++++++------- source/blender/src/drawnode.c | 15 +++++ 3 files changed, 61 insertions(+), 26 deletions(-) diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 26df3d187e7..03e9f7d4a6c 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -831,18 +831,18 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col) break; case MA_RAMP_OVERLAY: if(*r < 0.5f) - *r *= (facm + fac*col[0]); + *r *= (facm + 2.0f*fac*col[0]); else - *r = 1.0 - (facm + fac*(1.0 - col[0])) * (1.0 - *r); + *r = 1.0 - (facm + 2.0f*fac*(1.0 - col[0])) * (1.0 - *r); if(g) { if(*g < 0.5f) - *g *= (facm + fac*col[1]); + *g *= (facm + 2.0f*fac*col[1]); else - *g = 1.0 - (facm + fac*(1.0 - col[1])) * (1.0 - *g); + *g = 1.0 - (facm + 2.0f*fac*(1.0 - col[1])) * (1.0 - *g); if(*b < 0.5f) - *b *= (facm + fac*col[2]); + *b *= (facm + 2.0f*fac*col[2]); else - *b = 1.0 - (facm + fac*(1.0 - col[2])) * (1.0 - *b); + *b = 1.0 - (facm + 2.0f*fac*(1.0 - col[2])) * (1.0 - *b); } break; case MA_RAMP_SUB: diff --git a/source/blender/blenkernel/intern/node_composite.c b/source/blender/blenkernel/intern/node_composite.c index 1f022f92a4f..b04c540adcd 100644 --- a/source/blender/blenkernel/intern/node_composite.c +++ b/source/blender/blenkernel/intern/node_composite.c @@ -448,21 +448,6 @@ static void composit3_pixel_processor(bNode *node, CompBuf *out, CompBuf *src1_b } } -/* ok to delete this and use the generalised version below? */ -static CompBuf *alphabuf_from_rgbabuf(CompBuf *cbuf) -{ - CompBuf *valbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); - float *valf, *rectf; - int tot; - - valf= valbuf->rect; - rectf= cbuf->rect + 3; - for(tot= cbuf->x*cbuf->y; tot>0; tot--, valf++, rectf+=4) - *valf= *rectf; - - return valbuf; -} - static CompBuf *valbuf_from_rgbabuf(CompBuf *cbuf, int channel) { CompBuf *valbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); @@ -1571,7 +1556,7 @@ static void node_composit_exec_rgbtobw(void *data, bNode *node, bNodeStack **in, /* input no image? then only color operation */ if(in[0]->data==NULL) { - do_rgbtobw(node, out[0], in[0]); + do_rgbtobw(node, out[0]->vec, in[0]->vec); } else { /* make output size of input image */ @@ -1789,7 +1774,7 @@ static bNodeSocketType cmp_node_alphaover_out[]= { { -1, 0, "" } }; -static void do_alphaover(bNode *node, float *out, float *src, float *over) +static void do_alphaover_premul(bNode *node, float *out, float *src, float *over) { if(over[3]<=0.0f) { @@ -1817,6 +1802,37 @@ static void do_alphaover(bNode *node, float *out, float *src, float *over) } } +/* result will be still premul, but the over part is premulled */ +static void do_alphaover_key(bNode *node, float *out, float *src, float *over) +{ + + if(over[3]<=0.0f) { + QUATCOPY(out, src); + } + else if(over[3]>=1.0f) { + QUATCOPY(out, over); + } + else { + float premul= over[3]; + float mul= 1.0f - premul; + + /* handle case where backdrop has no alpha, but still color */ + if(src[0]==0.0f) { + out[0]= over[0]; + out[1]= (mul*src[1]) + premul*over[1]; + out[2]= (mul*src[2]) + premul*over[2]; + out[3]= (mul*src[3]) + premul*over[3]; + } + else { + out[0]= (mul*src[0]) + premul*over[0]; + out[1]= (mul*src[1]) + premul*over[1]; + out[2]= (mul*src[2]) + premul*over[2]; + out[3]= (mul*src[3]) + premul*over[3]; + } + } +} + + static void node_composit_exec_alphaover(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { /* stack order in: col col */ @@ -1824,24 +1840,28 @@ static void node_composit_exec_alphaover(void *data, bNode *node, bNodeStack **i /* input no image? then only color operation */ if(in[0]->data==NULL) { - do_alphaover(node, out[0]->vec, in[0]->vec, in[1]->vec); + do_alphaover_premul(node, out[0]->vec, in[0]->vec, in[1]->vec); } else { /* make output size of input image */ CompBuf *cbuf= in[0]->data; CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs - composit2_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_alphaover); + if(node->custom1) + composit2_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_alphaover_key); + else + composit2_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_alphaover_premul); out[0]->data= stackbuf; } } +/* custom1: convert 'over' to premul */ static bNodeType cmp_node_alphaover= { /* type code */ CMP_NODE_ALPHAOVER, /* name */ "AlphaOver", /* width+range */ 80, 40, 120, - /* class+opts */ NODE_CLASS_OPERATOR, 0, + /* class+opts */ NODE_CLASS_OPERATOR, NODE_OPTIONS, /* input sock */ cmp_node_alphaover_in, /* output sock */ cmp_node_alphaover_out, /* storage */ "", diff --git a/source/blender/src/drawnode.c b/source/blender/src/drawnode.c index bd21f4e9aea..d5546283774 100644 --- a/source/blender/src/drawnode.c +++ b/source/blender/src/drawnode.c @@ -885,6 +885,18 @@ static int node_composit_buts_time(uiBlock *block, bNodeTree *ntree, bNode *node return node->width-NODE_DY; } +static int node_composit_buts_alphaover(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) { + + /* alpha type */ + uiDefButS(block, TOG, B_NODE_EXEC+node->nr, "ConvertPremul", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 19, + &node->custom1, 0, 0, 0, 0, ""); + } + return 19; +} + /* only once called */ static void node_composit_set_butfunc(bNodeType *ntype) @@ -935,6 +947,9 @@ static void node_composit_set_butfunc(bNodeType *ntype) case CMP_NODE_TIME: ntype->butfunc= node_composit_buts_time; break; + case CMP_NODE_ALPHAOVER: + ntype->butfunc= node_composit_buts_alphaover; + break; default: ntype->butfunc= NULL; }