diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index d70cbe4a145..9c6e82cf998 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7355,6 +7355,23 @@ static void do_version_node_fix_translate_wrapping(void *UNUSED(data), ID *UNUSE } } +static void do_version_node_straight_image_alpha_workaround(void *data, ID *UNUSED(id), bNodeTree *ntree) +{ + FileData *fd = (FileData *) data; + bNode *node; + + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == CMP_NODE_IMAGE) { + Image *image = blo_do_versions_newlibadr(fd, ntree->id.lib, node->id); + + if (image) { + if ((image->flag & IMA_DO_PREMUL) == 0 && image->alpha_mode == IMA_ALPHA_STRAIGHT) + node->custom1 |= CMP_NODE_IMAGE_USE_STRAIGHT_OUTPUT; + } + } + } +} + static void do_version_node_fix_internal_links_264(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) { bNode *node; @@ -8648,6 +8665,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main) Scene *scene; Image *image, *nimage; Tex *tex, *otex; + bNodeTreeType *ntreetype; + bNodeTree *ntree; for (scene = main->scene.first; scene; scene = scene->id.next) { Sequence *seq; @@ -8752,6 +8771,13 @@ static void do_versions(FileData *fd, Library *lib, Main *main) for (image = main->image.first; image; image = image->id.next) image->flag &= ~IMA_DONE_TAG; + + ntreetype = ntreeGetType(NTREE_COMPOSIT); + if (ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(main, fd, do_version_node_straight_image_alpha_workaround); + + for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next) + do_version_node_straight_image_alpha_workaround(fd, NULL, ntree); } if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 7)) { diff --git a/source/blender/compositor/nodes/COM_ImageNode.cpp b/source/blender/compositor/nodes/COM_ImageNode.cpp index 864d6f08311..e4dd72d79e9 100644 --- a/source/blender/compositor/nodes/COM_ImageNode.cpp +++ b/source/blender/compositor/nodes/COM_ImageNode.cpp @@ -25,6 +25,7 @@ #include "COM_ExecutionSystem.h" #include "COM_ImageOperation.h" #include "COM_MultilayerImageOperation.h" +#include "COM_ConvertPremulToStraightOperation.h" #include "BKE_node.h" #include "BLI_utildefines.h" @@ -72,6 +73,7 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c ImageUser *imageuser = (ImageUser *)editorNode->storage; int framenumber = context->getFramenumber(); int numberOfOutputs = this->getNumberOfOutputSockets(); + bool outputStraightAlpha = editorNode->custom1 & CMP_NODE_IMAGE_USE_STRAIGHT_OUTPUT; BKE_image_user_frame_calc(imageuser, context->getFramenumber(), 0); /* force a load, we assume iuser index will be set OK anyway */ @@ -138,7 +140,15 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c if (numberOfOutputs > 0) { ImageOperation *operation = new ImageOperation(); if (outputImage->isConnected()) { - outputImage->relinkConnections(operation->getOutputSocket()); + if (outputStraightAlpha) { + NodeOperation *alphaConvertOperation = new ConvertPremulToStraightOperation(); + addLink(graph, operation->getOutputSocket(0), alphaConvertOperation->getInputSocket(0)); + outputImage->relinkConnections(alphaConvertOperation->getOutputSocket()); + graph->addOperation(alphaConvertOperation); + } + else { + outputImage->relinkConnections(operation->getOutputSocket()); + } } operation->setImage(image); operation->setImageUser(imageuser); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 72b8d0381df..8a2e03f2660 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1608,12 +1608,15 @@ static void node_composit_buts_image_details(uiLayout *layout, bContext *C, Poin node_composit_buts_image(layout, C, ptr); + uiItemR(layout, ptr, "use_straight_alpha_output", 0, NULL, 0); + if (!node->id) return; imaptr = RNA_pointer_get(ptr, "image"); uiTemplateColorspaceSettings(layout, &imaptr, "colorspace_settings"); + uiItemR(layout, &imaptr, "alpha_mode", 0, NULL, 0); } static void node_composit_buts_renderlayers(uiLayout *layout, bContext *C, PointerRNA *ptr) diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 5aaf46a541f..62c997b72c6 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -854,4 +854,7 @@ typedef struct NodeShaderNormalMap { #define CMP_NODE_MASK_MBLUR_SAMPLES_MAX 64 +/* image */ +#define CMP_NODE_IMAGE_USE_STRAIGHT_OUTPUT 1 + #endif diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 1fff567f25c..73fe5f3a48d 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -2412,7 +2412,12 @@ static void def_cmp_image(StructRNA *srna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Image", ""); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); - + + prop = RNA_def_property(srna, "use_straight_alpha_output", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "custom1", CMP_NODE_IMAGE_USE_STRAIGHT_OUTPUT); + RNA_def_property_ui_text(prop, "Straight Alpha Output", "Put Node output buffer to straight alpha instead of premultiplied"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + /* NB: image user properties used in the UI are redefined in def_node_image_user, * to trigger correct updates of the node editor. RNA design problem that prevents * updates from nested structs ...