Page 1 of 1

Emit Particles when Area turns into specific color

PostPosted: Mon Mar 08, 2021 7:08 pm
by Shivvycakes
Hello!

I am looking to make a piano synesthesia video. (I would post a URL but I am not allowed to :| )
In these videos, there is a virtual keyboard in which a key changes color when it is getting hit. It also emits particles vertically when the virtual key is being pressed.

I understand how to make particles and change their basic properties in fusion from all the tutorials out there, but I was wondering if anyone can fill me in on how to make the particles emit automatically once the piano key is hit (and the color in that area changes) as in the videos? I know that I can probably do it manually using keyframes but I would rather have it automatically change as it would save me a lot of time.

Thanks ahead of time for anyone that looks into this. If something is unclear let me know. :D

Re: Emit Particles when Area turns into specific color

PostPosted: Tue Mar 09, 2021 4:22 pm
by Jim Simon
I imagine that's a scripting kind of thing.

Not my forte.

Re: Emit Particles when Area turns into specific color

PostPosted: Tue Mar 09, 2021 8:30 pm
by Okke Verbart
Hi -you can definitely do this automatically. What I would do is to use a keyer (like the delta keyer) and set that to the color you're targeting. Then feed the output into a bitmap node and tick the "invert" box. This then can be used as an input bitmap for the particle emitter. Subsequently, it will only emit particles from that area.

I constructed a simple example below. If you're in Fusion standalone you can just copy & paste it into it. If you're in Resolve, first create an empty Fusion clip, go into the Fusion tab, and paste it there.

(bear in mind that I did not make any attempt to make it look pretty; it's just to illustrate the concept!)

Code: Select all
{
   Tools = ordered() {
      Rectangle1 = RectangleMask {
         Inputs = {
            MaskWidth = Input { Value = 1920, },
            MaskHeight = Input { Value = 1080, },
            PixelAspect = Input { Value = { 1, 1 }, },
            ClippingMode = Input { Value = FuID { "None" }, },
            Center = Input {
               SourceOp = "Perturb1",
               Source = "Value",
            },
            Width = Input { Value = 0.056, },
            Height = Input { Value = 0.9375, },
         },
         ViewInfo = OperatorInfo { Pos = { 307, 5 } },
      },
      Perturb1 = PerturbPoint {
         CtrlWZoom = false,
         Inputs = {
            YScale = Input { Value = 0, },
            Strength = Input { Value = 0.77, },
         },
      },
      FastNoise1_1 = FastNoise {
         Inputs = {
            Width = Input { Value = 20, },
            Height = Input { Value = 2, },
            ["Gamut.SLogVersion"] = Input { Value = FuID { "SLog2" }, },
            Color1Alpha = Input { Value = 1, },
            Color2Green = Input { Value = 0, },
            Color2Blue = Input { Value = 0, },
            EffectMask = Input {
               SourceOp = "Rectangle1",
               Source = "Mask",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 494, 4 } },
      },
      Resize1 = BetterResize {
         Inputs = {
            Width = Input { Value = 1920, },
            Height = Input { Value = 1080, },
            PixelAspect = Input { Value = { 1, 1 }, },
            Input = Input {
               SourceOp = "Merge1",
               Source = "Output",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 602, 136 } },
      },
      FastNoise1 = FastNoise {
         Inputs = {
            Width = Input { Value = 20, },
            Height = Input { Value = 2, },
            ["Gamut.SLogVersion"] = Input { Value = FuID { "SLog2" }, },
            Color1Alpha = Input { Value = 1, },
         },
         ViewInfo = OperatorInfo { Pos = { 382, 136 } },
      },
      Merge1 = Merge {
         Inputs = {
            Background = Input {
               SourceOp = "FastNoise1",
               Source = "Output",
            },
            Foreground = Input {
               SourceOp = "FastNoise1_1",
               Source = "Output",
            },
            PerformDepthMerge = Input { Value = 0, },
         },
         ViewInfo = OperatorInfo { Pos = { 492, 136 } },
      },
      Crop1 = Crop {
         Inputs = {
            YOffset = Input { Value = 538, },
            XSize = Input { Value = 1920, },
            YSize = Input { Value = 1080, },
            Input = Input {
               SourceOp = "Resize1",
               Source = "Output",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 745, 134 } },
      },
      DeltaKeyer1 = DeltaKeyer {
         Inputs = {
            BackgroundRed = Input { Value = 0.48235297203064, },
            BackgroundGreen = Input { Value = 0, },
            BackgroundBlue = Input { Value = 0, },
            TuningRanges = Input {
               Value = ColorCurves {
                  Curves = {
                     {
                        Points = {
                           { 0, 1 },
                           { 0.4, 0.2 },
                           { 0.6, 0 },
                           { 1, 0 }
                        }
                     },
                     {
                        Points = {
                           { 0, 0 },
                           { 0.4, 0 },
                           { 0.6, 0.2 },
                           { 1, 1 }
                        }
                     }
                  }
               },
            },
            Input = Input {
               SourceOp = "Crop1",
               Source = "Output",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 755, 192 } },
      },
      Bitmap1 = BitmapMask {
         Inputs = {
            Invert = Input { Value = 1, },
            MaskWidth = Input { Value = 1920, },
            MaskHeight = Input { Value = 1080, },
            PixelAspect = Input { Value = { 1, 1 }, },
            ClippingMode = Input { Value = FuID { "None" }, },
            Image = Input {
               SourceOp = "DeltaKeyer1",
               Source = "Output",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 763, 241 } },
      },
      pRender1 = pRender {
         Inputs = {
            _MotionBlurWarning = Input { Disabled = true, },
            Width = Input { Value = 1920, },
            Height = Input { Value = 1080, },
            ["Gamut.SLogVersion"] = Input { Value = FuID { "SLog2" }, },
            OutputMode = Input {
               Value = FuID { "TwoD" },
               Disabled = true,
            },
            IntegrationMethod = Input { Value = FuID { "RK4" }, },
            ["MaterialID.MaterialID"] = Input { Value = 1, },
            ["ObjectID.ObjectID"] = Input { Value = 1, },
            Input = Input {
               SourceOp = "pDirectionalForce1",
               Source = "Output",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 987, 319 } },
      },
      pEmitter1 = pEmitter {
         ID = 11,
         CtrlWZoom = false,
         Inputs = {
            Style = Input { Value = FuID { "ParticleStyleBlob" }, },
            Region = Input { Value = FuID { "BitmapRgn" }, },
            ["ParticleStyle.SizeControls"] = Input { Value = 1, },
            ["ParticleStyle.Size"] = Input { Value = 1, },
            ["ParticleStyle.SizeOverLife"] = Input {
               SourceOp = "pEmitter1SizeoverLife",
               Source = "Value",
            },
            ["ParticleStyle.BlurOverLife"] = Input {
               SourceOp = "pEmitter1BluroverLife2D",
               Source = "Value",
            },
            ["BitmapRgn.Bitmap"] = Input {
               SourceOp = "Bitmap1",
               Source = "Mask",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 758, 319 } },
      },
      pEmitter1SizeoverLife = LUTBezier {
         KeyColorSplines = {
            [0] = {
               [0] = { 0.5, RH = { 0.3, 0.5 }, Flags = { Linear = true } },
               [1] = { 0.5, LH = { 0.7, 0.5 }, Flags = { Linear = true } }
            }
         },
         SplineColor = { Red = 192, Green = 128, Blue = 64 },
         NameSet = true,
      },
      pEmitter1BluroverLife2D = LUTBezier {
         KeyColorSplines = {
            [0] = {
               [0] = { 0.5, RH = { 0.3, 0.5 }, Flags = { Linear = true } },
               [1] = { 0.5, LH = { 0.7, 0.5 }, Flags = { Linear = true } }
            }
         },
         SplineColor = { Red = 192, Green = 128, Blue = 64 },
         NameSet = true,
      },
      pDirectionalForce1 = pDirectionalForce {
         ID = 19,
         Inputs = {
            Direction = Input { Value = 90, },
            Input = Input {
               SourceOp = "pEmitter1",
               Source = "Output",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 869, 319 } },
      },
      Merge2 = Merge {
         Inputs = {
            Background = Input {
               SourceOp = "Crop1",
               Source = "Output",
            },
            Foreground = Input {
               SourceOp = "pRender1",
               Source = "Output",
            },
            PerformDepthMerge = Input { Value = 0, },
         },
         ViewInfo = OperatorInfo { Pos = { 1097, 319 } },
      }
   }
}

Re: Emit Particles when Area turns into specific color

PostPosted: Tue Mar 09, 2021 8:33 pm
by Okke Verbart
One sec.... weird....just tested it in Resolve, and seems there it's broken (it works in Fusion standalone)...let me check what's going on.

Re: Emit Particles when Area turns into specific color

PostPosted: Tue Mar 09, 2021 8:38 pm
by Okke Verbart
OK, for Resolve, use example below (works in Fusion standalone too). For whatever reason, the behaviour of the bitmap node is a bit different between Fusion (9) and Resolve 17.

Code: Select all
{
   Tools = ordered() {
      Rectangle1 = RectangleMask {
         Inputs = {
            MaskWidth = Input { Value = 1920, },
            MaskHeight = Input { Value = 1080, },
            PixelAspect = Input { Value = { 1, 1 }, },
            ClippingMode = Input { Value = FuID { "None" }, },
            Center = Input {
               SourceOp = "Perturb1",
               Source = "Value",
            },
            Width = Input { Value = 0.056, },
            Height = Input { Value = 0.9375, },
         },
         ViewInfo = OperatorInfo { Pos = { 492.545, 95.2793 } },
      },
      Perturb1 = PerturbPoint {
         CtrlWZoom = false,
         Inputs = {
            YScale = Input { Value = 0, },
            Strength = Input { Value = 0.77, },
         },
      },
      FastNoise1_1 = FastNoise {
         Inputs = {
            EffectMask = Input {
               SourceOp = "Rectangle1",
               Source = "Mask",
            },
            GlobalOut = Input { Value = 143, },
            Width = Input { Value = 20, },
            Height = Input { Value = 2, },
            ["Gamut.SLogVersion"] = Input { Value = FuID { "SLog2" }, },
            Color1Alpha = Input { Value = 1, },
            Color2Green = Input { Value = 0, },
            Color2Blue = Input { Value = 0, },
         },
         ViewInfo = OperatorInfo { Pos = { 679.545, 94.2793 } },
      },
      Merge1 = Merge {
         Inputs = {
            Background = Input {
               SourceOp = "FastNoise1",
               Source = "Output",
            },
            Foreground = Input {
               SourceOp = "FastNoise1_1",
               Source = "Output",
            },
            PerformDepthMerge = Input { Value = 0, },
         },
         ViewInfo = OperatorInfo { Pos = { 677.545, 226.279 } },
      },
      FastNoise1 = FastNoise {
         Inputs = {
            GlobalOut = Input { Value = 143, },
            Width = Input { Value = 20, },
            Height = Input { Value = 2, },
            ["Gamut.SLogVersion"] = Input { Value = FuID { "SLog2" }, },
            Color1Alpha = Input { Value = 1, },
         },
         ViewInfo = OperatorInfo { Pos = { 567.545, 226.279 } },
      },
      Resize1 = BetterResize {
         Inputs = {
            Width = Input { Value = 1920, },
            Height = Input { Value = 1080, },
            PixelAspect = Input { Value = { 1, 1 }, },
            Input = Input {
               SourceOp = "Merge1",
               Source = "Output",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 787.545, 226.279 } },
      },
      Background1 = Background {
         Inputs = {
            GlobalOut = Input { Value = 143, },
            Width = Input { Value = 1920, },
            Height = Input { Value = 1080, },
            UseFrameFormatSettings = Input { Value = 1, },
            ["Gamut.SLogVersion"] = Input { Value = FuID { "SLog2" }, },
         },
         ViewInfo = OperatorInfo { Pos = { 770.673, 300.983 } },
      },
      Crop1 = Crop {
         Inputs = {
            YOffset = Input { Value = 538, },
            XSize = Input { Value = 1920, },
            YSize = Input { Value = 1080, },
            Input = Input {
               SourceOp = "Resize1",
               Source = "Output",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 930.545, 224.279 } },
      },
      Bitmap1 = BitmapMask {
         Inputs = {
            Invert = Input { Value = 1, },
            MaskWidth = Input { Value = 1920, },
            MaskHeight = Input { Value = 1080, },
            PixelAspect = Input { Value = { 1, 1 }, },
            ClippingMode = Input { Value = FuID { "None" }, },
            Image = Input {
               SourceOp = "DeltaKeyer1",
               Source = "Output",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 956.087, 359.564 } },
      },
      DeltaKeyer1 = DeltaKeyer {
         Inputs = {
            BackgroundRed = Input { Value = 0.48235297203064, },
            BackgroundGreen = Input { Value = 0, },
            BackgroundBlue = Input { Value = 0, },
            TuningRanges = Input {
               Value = ColorCurves {
                  Curves = {
                     {
                        Points = {
                           { 0, 1 },
                           { 0.4, 0.2 },
                           { 0.6, 0 },
                           { 1, 0 }
                        }
                     },
                     {
                        Points = {
                           { 0, 0 },
                           { 0.4, 0 },
                           { 0.6, 0.2 },
                           { 1, 1 }
                        }
                     }
                  }
               },
            },
            Input = Input {
               SourceOp = "Merge3",
               Source = "Output",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 964.115, 324.277 } },
      },
      Merge3 = Merge {
         Inputs = {
            Background = Input {
               SourceOp = "Background1",
               Source = "Output",
            },
            Foreground = Input {
               SourceOp = "Crop1",
               Source = "Output",
            },
            PerformDepthMerge = Input { Value = 0, },
         },
         ViewInfo = OperatorInfo { Pos = { 963.949, 290.698 } },
      },
      pEmitter1 = pEmitter {
         ID = 12,
         Inputs = {
            Style = Input { Value = FuID { "ParticleStyleBlob" }, },
            Region = Input { Value = FuID { "BitmapRgn" }, },
            ["BitmapRgn.Bitmap"] = Input {
               SourceOp = "Bitmap1",
               Source = "Mask",
            },
            ["BitmapRgn.Low"] = Input { Value = 0.433, },
            ["ParticleStyle.SizeControls"] = Input { Value = 1, },
            ["ParticleStyle.Size"] = Input { Value = 1, },
            ["ParticleStyle.SizeOverLife"] = Input {
               SourceOp = "pEmitter1SizeoverLife",
               Source = "Value",
            },
            ["ParticleStyle.BlurOverLife"] = Input {
               SourceOp = "pEmitter1BluroverLife2D",
               Source = "Value",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 943.545, 409.279 } },
      },
      pEmitter1SizeoverLife = LUTBezier {
         KeyColorSplines = {
            [0] = {
               [0] = { 0.5, RH = { 0.333333333333333, 0.5 }, Flags = { Linear = true } },
               [1] = { 0.5, LH = { 0.666666666666667, 0.5 }, Flags = { Linear = true } }
            }
         },
         SplineColor = { Red = 192, Green = 128, Blue = 64 },
      },
      pEmitter1BluroverLife2D = LUTBezier {
         KeyColorSplines = {
            [0] = {
               [0] = { 0.5, RH = { 0.333333333333333, 0.5 }, Flags = { Linear = true } },
               [1] = { 0.5, LH = { 0.666666666666667, 0.5 }, Flags = { Linear = true } }
            }
         },
         SplineColor = { Red = 192, Green = 128, Blue = 64 },
      },
      pDirectionalForce1 = pDirectionalForce {
         ID = 15,
         Inputs = {
            Direction = Input { Value = 90, },
            Input = Input {
               SourceOp = "pEmitter1",
               Source = "Output",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 1054.54, 409.279 } },
      },
      pRender1 = pRender {
         Inputs = {
            IntegrationMethod = Input { Value = FuID { "RK4" }, },
            _MotionBlurWarning = Input { Disabled = true, },
            GlobalOut = Input { Value = 143, },
            Width = Input { Value = 1920, },
            Height = Input { Value = 1080, },
            ["Gamut.SLogVersion"] = Input { Value = FuID { "SLog2" }, },
            OutputMode = Input {
               Value = FuID { "TwoD" },
               Disabled = true,
            },
            ["MaterialID.MaterialID"] = Input { Value = 1, },
            ["ObjectID.ObjectID"] = Input { Value = 1, },
            Input = Input {
               SourceOp = "pDirectionalForce1",
               Source = "Output",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 1172.54, 409.279 } },
      },
      Merge2 = Merge {
         Inputs = {
            Background = Input {
               SourceOp = "Crop1",
               Source = "Output",
            },
            Foreground = Input {
               SourceOp = "pRender1",
               Source = "Output",
            },
            PerformDepthMerge = Input { Value = 0, },
         },
         ViewInfo = OperatorInfo { Pos = { 1287.26, 409.279 } },
      }
   }
}

Re: Emit Particles when Area turns into specific color

PostPosted: Thu Mar 11, 2021 1:06 am
by Shivvycakes
WOW Okke, thank you SOOOO much. This looks awesome and I can't wait to add this to my videos thanks again!!