2.8 F-Curve with seamless noise modifier idea

I’m glad to see that blender has a noise feature for bones and objects, the problem here is that when the animation loops, the transition from end to start doesn’t seem too seamless.
So maybe a little option which fixes that problem will be helpful?
Let me know if its possible to achieve this without a new option.
If there is no possibility, then I would be really happy to see this feature existing and working good :smiley:

At bottom of noise modifier, there is a Restrict from Range option.
You can decide when Noise effect starts and when it ends. You can define a margin to make a smooth transition.

If you set a Cycles modifier before Noise modifier, you can choose a Repeat Mirrored option to produce loops.

1 Like

I tried to do that but couldn’t get it to work :thinking: I tried playing with the in and out aswell but nothing
and when I tried adding the cycles after the noise modifier, it gave me an error not letting me add it
Hmmm, I need to do some more play around with it

EDIT: YES, it was so late that night I my mind couldn’t process properly and that made me lose focus a lot. Now I got the seamless loop perfectly with no problem
Thanks :smiley:

Now I wonder how to close this topic as solves :thinking:

i been trying to do that loop with noise modifier, BUT I CANT!!, can you help me? pleaseeee

I had the same problem. You can sortof fake a smooth transition by easing the noise in&out but it’s not really cyclic noise and that’s very apparent if you have noise on multiple axes to see them all go to zero at the same time when your animation loops. Same with mirroring, which also looks quite bad.

I proposed a true cyclic noise option with a quick&dirty implementation on RightClickSelect, but no reactions so far. Apparently not many people need this.

(Or there is some mysterious way to get true cyclic noise which eludes me).

Anyway, if you compile your own blender, you could try this patch ( don’t claim this is the best way to do this, it was meant as a proof-of-concept. Also the name of the actual option should probably be thought through better, and more documentation added and things like that):

diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index c85283e3653..5e23a4cd479 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -821,11 +821,27 @@ static void fcm_noise_evaluate(
   FMod_Noise *data = (FMod_Noise *)fcm->data;
   float noise;
 
-  /* generate noise using good old Blender Noise
-   * - 0.1 is passed as the 'z' value, otherwise evaluation fails for size = phase = 1
-   *   with evaltime being an integer (which happens when evaluating on frame by frame basis)
-   */
-  noise = BLI_turbulence(data->size, evaltime - data->offset, data->phase, 0.1f, data->depth);
+  short cyclic = data->cyclic;
+
+  if (cyclic)
+  {
+    /* wrap around in a circle */
+    float alongcircle = evaltime - data->offset;
+
+    float angle = alongcircle * 2 * M_PI / cyclic;
+    float radius = cyclic * .5 * M_1_PI;
+
+    noise = BLI_turbulence(data->size, radius * cos(angle), radius*sin(angle), data->phase,  data->depth);
+  }
+  else
+  {
+   /* generate noise using good old Blender Noise
+    * - 0.1 is passed as the 'z' value, otherwise evaluation fails for size = phase = 1
+    *   with evaltime being an integer (which happens when evaluating on frame by frame basis)
+    */
+   noise = BLI_turbulence(data->size, evaltime - data->offset, data->phase, 0.1f, data->depth);
+  }
+
 
   /* combine the noise with existing motion data */
   switch (data->modification) {
diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c
index eadaa449b92..c80a694562a 100644
--- a/source/blender/editors/animation/fmodifier_ui.c
+++ b/source/blender/editors/animation/fmodifier_ui.c
@@ -562,6 +562,7 @@ static void draw_modifier__noise(uiLayout *layout,
   col = uiLayoutColumn(split, false);
   uiItemR(col, &ptr, "phase", 0, NULL, ICON_NONE);
   uiItemR(col, &ptr, "depth", 0, NULL, ICON_NONE);
+  uiItemR(col, &ptr, "cyclic", 0, NULL, ICON_NONE);
 }
 
 /* callback to add new envelope data point */
diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h
index 6a024ec9e7e..15ed80ed2ad 100644
--- a/source/blender/makesdna/DNA_anim_types.h
+++ b/source/blender/makesdna/DNA_anim_types.h
@@ -260,6 +260,8 @@ typedef struct FMod_Noise {
 
   short depth;
   short modification;
+  short cyclic;
+  char _pad[2];
 } FMod_Noise;
 
 /* modification modes */
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index e49186f4cb1..3b78780af55 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -1524,6 +1524,12 @@ static void rna_def_fmodifier_noise(BlenderRNA *brna)
   RNA_def_property_int_sdna(prop, NULL, "depth");
   RNA_def_property_ui_text(prop, "Depth", "Amount of fine level detail present in the noise");
   RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
+
+  prop = RNA_def_property(srna, "cyclic", PROP_INT, PROP_UNSIGNED);
+  RNA_def_property_int_sdna(prop, NULL, "cyclic");
+  RNA_def_property_ui_text(prop, "Cycle", "Repeat noise after number of frames (0 means infinite)");
+  RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
+
 }
 
 /* --------- */