From e15cdec2d49ee47a85897db9838578a298146513 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Sat, 26 Jul 2014 12:59:29 +0200 Subject: New compositor node "Sun Beams" This allows adding a "fake" sun beam effect, simulating crepuscular rays from light being scattered in a medium like the atmosphere or deep water. Such effects can be created also by renderers using volumetric lighting, but the compositor feature is a lot cheaper and is independent from 3D rendering. This makes it ideally suited for motion graphics. The implementation uses am optimized accumulation method for gathering color values along a line segment. The inner buffer loop uses fixed offset increments to avoid unnecessary multiplications and avoids variables by using compile-time specialization (see inline comments for further details). --- source/blender/blenkernel/BKE_node.h | 1 + source/blender/blenkernel/intern/node.c | 1 + source/blender/compositor/CMakeLists.txt | 5 + source/blender/compositor/intern/COM_Converter.cpp | 4 + .../blender/compositor/nodes/COM_SunBeamsNode.cpp | 42 +++ source/blender/compositor/nodes/COM_SunBeamsNode.h | 37 +++ .../operations/COM_SunBeamsOperation.cpp | 303 +++++++++++++++++++++ .../compositor/operations/COM_SunBeamsOperation.h | 48 ++++ source/blender/editors/space_node/drawnode.c | 9 + source/blender/makesdna/DNA_node_types.h | 6 + source/blender/makesrna/intern/rna_nodetree.c | 21 ++ source/blender/nodes/CMakeLists.txt | 1 + source/blender/nodes/NOD_composite.h | 2 +- source/blender/nodes/NOD_static_types.h | 1 + .../composite/nodes/node_composite_sunbeams.c | 63 +++++ 15 files changed, 543 insertions(+), 1 deletion(-) create mode 100644 source/blender/compositor/nodes/COM_SunBeamsNode.cpp create mode 100644 source/blender/compositor/nodes/COM_SunBeamsNode.h create mode 100644 source/blender/compositor/operations/COM_SunBeamsOperation.cpp create mode 100644 source/blender/compositor/operations/COM_SunBeamsOperation.h create mode 100644 source/blender/nodes/composite/nodes/node_composite_sunbeams.c (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 15e7efe7c6e..5e786cbfb53 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -894,6 +894,7 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMateria #define CMP_NODE_GLARE 301 #define CMP_NODE_TONEMAP 302 #define CMP_NODE_LENSDIST 303 +#define CMP_NODE_SUNBEAMS 304 #define CMP_NODE_COLORCORRECTION 312 #define CMP_NODE_MASK_BOX 313 diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 56a76a54955..0dee80e27cd 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -3406,6 +3406,7 @@ static void registerCompositNodes(void) register_node_type_cmp_inpaint(); register_node_type_cmp_despeckle(); register_node_type_cmp_defocus(); + register_node_type_cmp_sunbeams(); register_node_type_cmp_valtorgb(); register_node_type_cmp_rgbtobw(); diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index a19433436f1..9c539e2dd1c 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -175,6 +175,11 @@ set(SRC nodes/COM_GlareNode.cpp nodes/COM_GlareNode.h + nodes/COM_SunBeamsNode.cpp + nodes/COM_SunBeamsNode.h + operations/COM_SunBeamsOperation.cpp + operations/COM_SunBeamsOperation.h + nodes/COM_CornerPinNode.cpp nodes/COM_CornerPinNode.h nodes/COM_PlaneTrackDeformNode.cpp diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp index 9251e161839..99f66bcb5b4 100644 --- a/source/blender/compositor/intern/COM_Converter.cpp +++ b/source/blender/compositor/intern/COM_Converter.cpp @@ -99,6 +99,7 @@ extern "C" { #include "COM_SetValueOperation.h" #include "COM_SplitViewerNode.h" #include "COM_Stabilize2dNode.h" +#include "COM_SunBeamsNode.h" #include "COM_SwitchNode.h" #include "COM_TextureNode.h" #include "COM_TimeNode.h" @@ -394,6 +395,9 @@ Node *Converter::convert(bNode *b_node) case CMP_NODE_CORNERPIN: node = new CornerPinNode(b_node); break; + case CMP_NODE_SUNBEAMS: + node = new SunBeamsNode(b_node); + break; } return node; } diff --git a/source/blender/compositor/nodes/COM_SunBeamsNode.cpp b/source/blender/compositor/nodes/COM_SunBeamsNode.cpp new file mode 100644 index 00000000000..ed14acabf36 --- /dev/null +++ b/source/blender/compositor/nodes/COM_SunBeamsNode.cpp @@ -0,0 +1,42 @@ +/* + * Copyright 2014, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Lukas Toenne + */ + +#include "COM_SunBeamsNode.h" +#include "COM_SunBeamsOperation.h" + +SunBeamsNode::SunBeamsNode(bNode *editorNode) : Node(editorNode) +{ + /* pass */ +} + +void SunBeamsNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const +{ + NodeInput *inputSocket = this->getInputSocket(0); + NodeOutput *outputSocket = this->getOutputSocket(0); + NodeSunBeams *data = (NodeSunBeams *)getbNode()->storage; + + SunBeamsOperation *operation = new SunBeamsOperation(); + operation->setData(*data); + converter.addOperation(operation); + + converter.mapInputSocket(inputSocket, operation->getInputSocket(0)); + converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0)); +} diff --git a/source/blender/compositor/nodes/COM_SunBeamsNode.h b/source/blender/compositor/nodes/COM_SunBeamsNode.h new file mode 100644 index 00000000000..4024eb276bc --- /dev/null +++ b/source/blender/compositor/nodes/COM_SunBeamsNode.h @@ -0,0 +1,37 @@ +/* + * Copyright 2014, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Lukas Toenne + */ + +#ifndef _COM_SunBeamsNode_h_ +#define _COM_SunBeamsNode_h_ + +#include "COM_Node.h" + +/** + * @brief SunBeamsNode + * @ingroup Node + */ +class SunBeamsNode : public Node { +public: + SunBeamsNode(bNode *editorNode); + void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; +}; + +#endif diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp new file mode 100644 index 00000000000..a267a1f0099 --- /dev/null +++ b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp @@ -0,0 +1,303 @@ +/* + * Copyright 2014, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Lukas Toenne + */ + +#include "MEM_guardedalloc.h" + +#include "COM_SunBeamsOperation.h" + +SunBeamsOperation::SunBeamsOperation() : NodeOperation() +{ + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + this->setResolutionInputSocketIndex(0); + + this->setComplex(true); +} + +void SunBeamsOperation::initExecution() +{ + /* convert to pixels */ + this->m_source_px[0] = this->m_data.source[0] * this->getWidth(); + this->m_source_px[1] = this->m_data.source[1] * this->getHeight(); + this->m_ray_length_px = this->m_data.ray_length * max(this->getWidth(), this->getHeight()); +} + +/** + * Defines a line accumulator for a specific sector, + * given by the four matrix entries that rotate from buffer space into the sector + * + * (x,y) is used to designate buffer space coordinates + * (u,v) is used to designate sector space coordinates + * + * For a target point (x,y) the sector should be chosen such that + * ``u >= v >= 0`` + * This removes the need to handle all sorts of special cases. + */ +template +struct BufferLineAccumulator { + + /* utility functions implementing the matrix transform to/from sector space */ + + static inline void buffer_to_sector(int x, int y, int &u, int &v) + { + u = x * fxx + y * fyx; + v = x * fxy + y * fyy; + } + + static inline void buffer_to_sector(float x, float y, float &u, float &v) + { + u = x * fxx + y * fyx; + v = x * fxy + y * fyy; + } + + static inline void sector_to_buffer(int u, int v, int &x, int &y) + { + x = u * fxx + v * fxy; + y = u * fyx + v * fyy; + } + + static inline void sector_to_buffer(float u, float v, float &x, float &y) + { + x = u * fxx + v * fxy; + y = u * fyx + v * fyy; + } + + /** + * Set up the initial buffer pointer and calculate necessary variables for looping. + * + * Note that sector space is centered around the "source" point while the loop starts + * at dist_min from the target pt. This way the loop can be cancelled as soon as it runs + * out of the buffer rect, because no pixels further along the line can contribute. + * + * \param x, y Start location in the buffer + * \param num Total steps in the loop + * \param v, dv Vertical offset in sector space, for line offset perpendicular to the loop axis + */ + static float *init_buffer_iterator(MemoryBuffer *input, const float source[2], const float pt_ofs[2], + float dist_min, float dist_max, + int &x, int &y, int &num, float &v, float &dv) + { + float pu, pv; + buffer_to_sector(pt_ofs[0], pt_ofs[1], pu, pv); + + /* line angle */ + float tan_phi = pv / pu; + float cos_phi = 1.0f / sqrtf(tan_phi * tan_phi + 1.0f); + + float umin = pu - cos_phi * dist_min; + float umax = pu - cos_phi * dist_max; + v = umin * tan_phi; + dv = tan_phi; + + sector_to_buffer(umin, v, x, y); + x += source[0]; + y += source[1]; + + num = (int)ceilf(umin) - max_ii((int)floorf(umax), 1); + + float *iter = input->getBuffer() + COM_NUMBER_OF_CHANNELS * (x + input->getWidth() * y); + return iter; + } + + /** + * Perform the actual accumulation along a ray segment from source to pt. + * Only pixels withing dist_min..dist_max contribute. + * + * The loop runs backwards(!) over the primary sector space axis u, i.e. increasing distance to pt. + * After each step it decrements v by dv < 1, adding a buffer shift when necesserary. + */ + static void eval(MemoryBuffer *input, float output[4], const float pt_ofs[2], const float source[2], + float dist_min, float dist_max) + { + rcti rect = *input->getRect(); + int buffer_width = input->getWidth(); + int x, y, num; + float v, dv; + + /* initialise the iteration variables */ + float *buffer = init_buffer_iterator(input, source, pt_ofs, dist_min, dist_max, x, y, num, v, dv); + + float falloff_factor = num > 1 ? 1.0f / (float)(num - 1) : 0.0f; + + int tot = 0; + + /* v_local keeps track of when to decrement v (see below) */ + float v_local = v - floorf(v); + + for (int i = 0; i < num; i++) { + /* range check, abort when running beyond the image border */ + if (x < rect.xmin || x >= rect.xmax || y < rect.ymin || y >= rect.ymax) + break; + + float f = 1.0f - (float)i * falloff_factor; + madd_v4_v4fl(output, buffer, buffer[3] * f * f); + /* TODO implement proper filtering here, see + * http://en.wikipedia.org/wiki/Lanczos_resampling + * http://en.wikipedia.org/wiki/Sinc_function + * + * using lanczos with x = distance from the line segment, + * normalized to a == 0.5f, could give a good result + * + * for now just count samples and divide equally at the end ... + */ + tot++; + + /* decrement u */ + x -= fxx; + y -= fyx; + buffer -= (fxx + fyx * buffer_width) * COM_NUMBER_OF_CHANNELS; + + /* decrement v (in steps of dv < 1) */ + v_local -= dv; + if (v_local < 0.0f) { + v_local += 1.0f; + + x -= fxy; + y -= fyy; + buffer -= (fxy + fyy * buffer_width) * COM_NUMBER_OF_CHANNELS; + } + } + + /* normalize */ + if (num > 0) { + mul_v4_fl(output, 1.0f / (float)num); + } + } +}; + +/** + * Dispatch function which selects an appropriate accumulator based on the sector of the target point, + * relative to the source. + * + * The BufferLineAccumulator defines the actual loop over the buffer, with an efficient inner loop + * due to using compile time constants instead of a local matrix variable defining the sector space. + */ +static void accumulate_line(MemoryBuffer *input, float output[4], const float co[2], const float source[2], + float dist_min, float dist_max) +{ + /* coordinates relative to source */ + float pt_ofs[2] = {co[0] - source[0], co[1] - source[1]}; + + /* The source sectors are defined like so: + * + * \ 3 | 2 / + * \ | / + * 4 \ | / 1 + * \|/ + * ----------- + * /|\ + * 5 / | \ 8 + * / | \ + * / 6 | 7 \ + * + * The template arguments encode the transformation into "sector space", + * by means of rotation/mirroring matrix elements. + */ + + if (fabsf(pt_ofs[1]) > fabsf(pt_ofs[0])) { + if (pt_ofs[0] > 0.0f) { + if (pt_ofs[1] > 0.0f) { + /* 2 */ + BufferLineAccumulator<0, 1, 1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max); + } + else { + /* 7 */ + BufferLineAccumulator<0, 1, -1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max); + } + } + else { + if (pt_ofs[1] > 0.0f) { + /* 3 */ + BufferLineAccumulator<0, -1, 1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max); + } + else { + /* 6 */ + BufferLineAccumulator<0, -1, -1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max); + } + } + } + else { + if (pt_ofs[0] > 0.0f) { + if (pt_ofs[1] > 0.0f) { + /* 1 */ + BufferLineAccumulator< 1, 0, 0, 1>::eval(input, output, pt_ofs, source, dist_min, dist_max); + } + else { + /* 8 */ + BufferLineAccumulator< 1, 0, 0, -1>::eval(input, output, pt_ofs, source, dist_min, dist_max); + } + } + else { + if (pt_ofs[1] > 0.0f) { + /* 4 */ + BufferLineAccumulator<-1, 0, 0, 1>::eval(input, output, pt_ofs, source, dist_min, dist_max); + } + else { + /* 5 */ + BufferLineAccumulator<-1, 0, 0, -1>::eval(input, output, pt_ofs, source, dist_min, dist_max); + } + } + } +} + +void *SunBeamsOperation::initializeTileData(rcti *rect) +{ + void *buffer = getInputOperation(0)->initializeTileData(NULL); + return buffer; +} + +void SunBeamsOperation::executePixel(float output[4], int x, int y, void *data) +{ + const float co[2] = {(float)x, (float)y}; + + accumulate_line((MemoryBuffer *)data, output, co, this->m_source_px, 0.0f, this->m_ray_length_px); +} + +static void calc_ray_shift(rcti *rect, float x, float y, const float source[2], float ray_length) +{ + float co[2] = {x, y}; + float dir[2], dist; + + /* move (x,y) vector toward the source by ray_length distance */ + sub_v2_v2v2(dir, co, source); + dist = normalize_v2(dir); + mul_v2_fl(dir, min_ff(dist, ray_length)); + sub_v2_v2(co, dir); + + int ico[2] = {(int)co[0], (int)co[1]}; + BLI_rcti_do_minmax_v(rect, ico); +} + +bool SunBeamsOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) +{ + /* Enlarges the rect by moving each corner toward the source. + * This is the maximum distance that pixels can influence each other + * and gives a rect that contains all possible accumulated pixels. + */ + rcti rect = *input; + calc_ray_shift(&rect, input->xmin, input->ymin, this->m_source_px, this->m_ray_length_px); + calc_ray_shift(&rect, input->xmin, input->ymax, this->m_source_px, this->m_ray_length_px); + calc_ray_shift(&rect, input->xmax, input->ymin, this->m_source_px, this->m_ray_length_px); + calc_ray_shift(&rect, input->xmax, input->ymax, this->m_source_px, this->m_ray_length_px); + + return NodeOperation::determineDependingAreaOfInterest(&rect, readOperation, output); +} + diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.h b/source/blender/compositor/operations/COM_SunBeamsOperation.h new file mode 100644 index 00000000000..ef80a31fe40 --- /dev/null +++ b/source/blender/compositor/operations/COM_SunBeamsOperation.h @@ -0,0 +1,48 @@ +/* + * Copyright 2014, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor: + * Lukas Toenne + */ + +#ifndef _COM_SunBeamsOperation_h +#define _COM_SunBeamsOperation_h + +#include "COM_NodeOperation.h" + +class SunBeamsOperation : public NodeOperation { +public: + SunBeamsOperation(); + + void executePixel(float output[4], int x, int y, void *data); + + void initExecution(); + + void *initializeTileData(rcti *rect); + + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + + void setData(const NodeSunBeams &data) { m_data = data; } + +private: + NodeSunBeams m_data; + + float m_source_px[2]; + float m_ray_length_px; +}; + +#endif diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index ef23fc24194..6fa9290c732 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -2307,6 +2307,12 @@ static void node_composit_buts_cornerpin(uiLayout *UNUSED(layout), bContext *UNU { } +static void node_composit_buts_sunbeams(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiItemR(layout, ptr, "source", UI_ITEM_R_EXPAND, "", ICON_NONE); + uiItemR(layout, ptr, "ray_length", UI_ITEM_R_SLIDER, NULL, ICON_NONE); +} + /* only once called */ static void node_composit_set_butfunc(bNodeType *ntype) { @@ -2531,6 +2537,9 @@ static void node_composit_set_butfunc(bNodeType *ntype) case CMP_NODE_CORNERPIN: ntype->draw_buttons = node_composit_buts_cornerpin; break; + case CMP_NODE_SUNBEAMS: + ntype->draw_buttons = node_composit_buts_sunbeams; + break; } } diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index b13353609c6..e0d25e763d4 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -852,6 +852,12 @@ typedef struct NodeShaderUVMap { char uv_map[64]; } NodeShaderUVMap; +typedef struct NodeSunBeams { + float source[2]; + + float ray_length; +} NodeSunBeams; + /* script node mode */ #define NODE_SCRIPT_INTERNAL 0 #define NODE_SCRIPT_EXTERNAL 1 diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 065b6f787b6..8a177c6e2f9 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -6187,6 +6187,27 @@ static void def_cmp_planetrackdeform(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } +static void def_cmp_sunbeams(StructRNA *srna) +{ + PropertyRNA *prop; + + RNA_def_struct_sdna_from(srna, "NodeSunBeams", "storage"); + + prop = RNA_def_property(srna, "source", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "source"); + RNA_def_property_range(prop, -100.0f, 100.0f); + RNA_def_property_ui_range(prop, -10.0f, 10.0f, 10, 3); + RNA_def_property_ui_text(prop, "Source", "Source point of rays as a factor of the image width & height"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "ray_length", PROP_FLOAT, PROP_UNSIGNED); + RNA_def_property_float_sdna(prop, NULL, "ray_length"); + RNA_def_property_range(prop, 0.0f, 100.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 10, 3); + RNA_def_property_ui_text(prop, "Ray Length", "Length of rays as a factor of the image size"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); +} + /* -- Texture Nodes --------------------------------------------------------- */ static void def_tex_output(StructRNA *srna) diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 6fed0d16848..e09a0892370 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -105,6 +105,7 @@ set(SRC composite/nodes/node_composite_setalpha.c composite/nodes/node_composite_splitViewer.c composite/nodes/node_composite_stabilize2d.c + composite/nodes/node_composite_sunbeams.c composite/nodes/node_composite_texture.c composite/nodes/node_composite_tonemap.c composite/nodes/node_composite_trackpos.c diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h index ad5f35b8faa..961fdbfc0fb 100644 --- a/source/blender/nodes/NOD_composite.h +++ b/source/blender/nodes/NOD_composite.h @@ -125,7 +125,7 @@ void register_node_type_cmp_mask(void); void register_node_type_cmp_glare(void); void register_node_type_cmp_tonemap(void); void register_node_type_cmp_lensdist(void); - +void register_node_type_cmp_sunbeams(void); void register_node_type_cmp_colorcorrection(void); void register_node_type_cmp_boxmask(void); diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 8d6c4abaef6..be87abd7b7e 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -208,6 +208,7 @@ DefNode( CompositorNode, CMP_NODE_TRACKPOS, def_cmp_trackpos, "TRACK DefNode( CompositorNode, CMP_NODE_PIXELATE, 0, "PIXELATE", Pixelate, "Pixelate", "" ) DefNode( CompositorNode, CMP_NODE_PLANETRACKDEFORM,def_cmp_planetrackdeform,"PLANETRACKDEFORM",PlaneTrackDeform,"Plane Track Deform","" ) DefNode( CompositorNode, CMP_NODE_CORNERPIN, 0, "CORNERPIN", CornerPin, "Corner Pin", "" ) +DefNode( CompositorNode, CMP_NODE_SUNBEAMS, def_cmp_sunbeams, "SUNBEAMS", SunBeams, "Sun Beams", "" ) DefNode( TextureNode, TEX_NODE_OUTPUT, def_tex_output, "OUTPUT", Output, "Output", "" ) DefNode( TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" ) diff --git a/source/blender/nodes/composite/nodes/node_composite_sunbeams.c b/source/blender/nodes/composite/nodes/node_composite_sunbeams.c new file mode 100644 index 00000000000..4d937d63b75 --- /dev/null +++ b/source/blender/nodes/composite/nodes/node_composite_sunbeams.c @@ -0,0 +1,63 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2014 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Lukas Toenne + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/composite/nodes/node_composite_sunbeams.c + * \ingroup cmpnodes + */ + +#include "node_composite_util.h" + +static bNodeSocketTemplate inputs[] = { + { SOCK_RGBA, 1, N_("Image"), 1.0f, 1.0f, 1.0f, 1.0f}, + { -1, 0, "" } +}; +static bNodeSocketTemplate outputs[] = { + { SOCK_RGBA, 0, N_("Image")}, + { -1, 0, "" } +}; + +static void init(bNodeTree *UNUSED(ntree), bNode *node) +{ + NodeSunBeams *data = MEM_callocN(sizeof(NodeSunBeams), "sun beams node"); + + data->source[0] = 0.5f; + data->source[1] = 0.5f; + + node->storage = data; +} + +void register_node_type_cmp_sunbeams(void) +{ + static bNodeType ntype; + + cmp_node_type_base(&ntype, CMP_NODE_SUNBEAMS, "Sun Beams", NODE_CLASS_OP_FILTER, 0); + node_type_socket_templates(&ntype, inputs, outputs); + node_type_init(&ntype, init); + node_type_storage(&ntype, "NodeSunBeams", node_free_standard_storage, node_copy_standard_storage); + + nodeRegisterType(&ntype); +} -- cgit v1.2.3