Fix T51308: Bright/Contrast Doesn't respect Pre-multiplied Alpha
Brightness/contrast node was changing color but did not modify alpha or ensured colors are premultiplied on the output. This was giving artifacts later on unless alpha was manually converted. Compositor is supposed to work in premultiplied alpha (except of some really corner cases) so it makes sense to ensure premultiplied alpha after brightness/contrast node. This is now done as an option enabled by default, so we: (a) Keep compatibility with old files. (b) Have correct behavior for newly created files. Later on we can get rid of this option.
This commit is contained in:
parent
849e77b1f9
commit
8cc4c3da8c
Notes:
blender-bot
2023-02-14 07:02:37 +01:00
Referenced by issue #51308, Bright/Contrast Doesn't respect Pre-multiplied Alpha
|
@ -31,7 +31,9 @@ BrightnessNode::BrightnessNode(bNode *editorNode) : Node(editorNode)
|
|||
|
||||
void BrightnessNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const
|
||||
{
|
||||
bNode *bnode = this->getbNode();
|
||||
BrightnessOperation *operation = new BrightnessOperation();
|
||||
operation->setUsePremultiply((bnode->custom1 & 1) != 0);
|
||||
converter.addOperation(operation);
|
||||
|
||||
converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
|
||||
|
|
|
@ -29,7 +29,14 @@ BrightnessOperation::BrightnessOperation() : NodeOperation()
|
|||
this->addInputSocket(COM_DT_VALUE);
|
||||
this->addOutputSocket(COM_DT_COLOR);
|
||||
this->m_inputProgram = NULL;
|
||||
this->m_use_premultiply = false;
|
||||
}
|
||||
|
||||
void BrightnessOperation::setUsePremultiply(bool use_premultiply)
|
||||
{
|
||||
this->m_use_premultiply = use_premultiply;
|
||||
}
|
||||
|
||||
void BrightnessOperation::initExecution()
|
||||
{
|
||||
this->m_inputProgram = this->getInputSocketReader(0);
|
||||
|
@ -64,11 +71,16 @@ void BrightnessOperation::executePixelSampled(float output[4], float x, float y,
|
|||
delta *= -1;
|
||||
b = a * (brightness + delta);
|
||||
}
|
||||
|
||||
if (this->m_use_premultiply) {
|
||||
premul_to_straight_v4(inputValue);
|
||||
}
|
||||
output[0] = a * inputValue[0] + b;
|
||||
output[1] = a * inputValue[1] + b;
|
||||
output[2] = a * inputValue[2] + b;
|
||||
output[3] = inputValue[3];
|
||||
if (this->m_use_premultiply) {
|
||||
straight_to_premul_v4(output);
|
||||
}
|
||||
}
|
||||
|
||||
void BrightnessOperation::deinitExecution()
|
||||
|
|
|
@ -34,6 +34,8 @@ private:
|
|||
SocketReader *m_inputBrightnessProgram;
|
||||
SocketReader *m_inputContrastProgram;
|
||||
|
||||
bool m_use_premultiply;
|
||||
|
||||
public:
|
||||
BrightnessOperation();
|
||||
|
||||
|
@ -52,5 +54,6 @@ public:
|
|||
*/
|
||||
void deinitExecution();
|
||||
|
||||
void setUsePremultiply(bool use_premultiply);
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -2478,6 +2478,11 @@ static void node_composit_buts_sunbeams(uiLayout *layout, bContext *UNUSED(C), P
|
|||
uiItemR(layout, ptr, "ray_length", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
|
||||
}
|
||||
|
||||
static void node_composit_buts_brightcontrast(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
|
||||
{
|
||||
uiItemR(layout, ptr, "use_premultiply", 0, NULL, ICON_NONE);
|
||||
}
|
||||
|
||||
/* only once called */
|
||||
static void node_composit_set_butfunc(bNodeType *ntype)
|
||||
{
|
||||
|
@ -2705,6 +2710,8 @@ static void node_composit_set_butfunc(bNodeType *ntype)
|
|||
case CMP_NODE_SUNBEAMS:
|
||||
ntype->draw_buttons = node_composit_buts_sunbeams;
|
||||
break;
|
||||
case CMP_NODE_BRIGHTCONTRAST:
|
||||
ntype->draw_buttons = node_composit_buts_brightcontrast;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5239,6 +5239,16 @@ static void def_cmp_luma_matte(StructRNA *srna)
|
|||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
}
|
||||
|
||||
static void def_cmp_brightcontrast(StructRNA *srna)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
prop = RNA_def_property(srna, "use_premultiply", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1);
|
||||
RNA_def_property_ui_text(prop, "Convert Premul", "Keep output image premultiplied alpha");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
}
|
||||
|
||||
static void def_cmp_chroma_matte(StructRNA *srna)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
|
|
@ -179,7 +179,7 @@ DefNode( CompositorNode, CMP_NODE_DISPLACE, 0, "DISPL
|
|||
DefNode( CompositorNode, CMP_NODE_COMBHSVA, 0, "COMBHSVA", CombHSVA, "Combine HSVA", "" )
|
||||
DefNode( CompositorNode, CMP_NODE_MATH, def_math, "MATH", Math, "Math", "" )
|
||||
DefNode( CompositorNode, CMP_NODE_LUMA_MATTE, def_cmp_luma_matte, "LUMA_MATTE", LumaMatte, "Luminance Key", "" )
|
||||
DefNode( CompositorNode, CMP_NODE_BRIGHTCONTRAST, 0, "BRIGHTCONTRAST", BrightContrast, "Bright/Contrast", "" )
|
||||
DefNode( CompositorNode, CMP_NODE_BRIGHTCONTRAST, def_cmp_brightcontrast, "BRIGHTCONTRAST", BrightContrast, "Bright/Contrast", "" )
|
||||
DefNode( CompositorNode, CMP_NODE_GAMMA, 0, "GAMMA", Gamma, "Gamma", "" )
|
||||
DefNode( CompositorNode, CMP_NODE_INVERT, def_cmp_invert, "INVERT", Invert, "Invert", "" )
|
||||
DefNode( CompositorNode, CMP_NODE_NORMALIZE, 0, "NORMALIZE", Normalize, "Normalize", "" )
|
||||
|
|
|
@ -46,6 +46,10 @@ static bNodeSocketTemplate cmp_node_brightcontrast_out[] = {
|
|||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static void node_composit_init_brightcontrast(bNodeTree *UNUSED(ntree), bNode *node)
|
||||
{
|
||||
node->custom1 = 1;
|
||||
}
|
||||
|
||||
void register_node_type_cmp_brightcontrast(void)
|
||||
{
|
||||
|
@ -53,6 +57,7 @@ void register_node_type_cmp_brightcontrast(void)
|
|||
|
||||
cmp_node_type_base(&ntype, CMP_NODE_BRIGHTCONTRAST, "Bright/Contrast", NODE_CLASS_OP_COLOR, 0);
|
||||
node_type_socket_templates(&ntype, cmp_node_brightcontrast_in, cmp_node_brightcontrast_out);
|
||||
node_type_init(&ntype, node_composit_init_brightcontrast);
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue