# Reptorian's adventure with recreating patterns found in plugins for Paint.NET

#1

Hi guys, thanks to people at G’MIC exercises, I was able to recreate the effect Vibrato plugin found as a plugin for Paint .NET.

Right now, all I have is a test picture, and…

The local code test before it is transformed as an actual filter.

``````f "n=5;
o=1;
e=0;
t=1;
f=-5;
a=1;
b=1;
s=2;
t=2;
m=20;
k=30;

q=(m/100)*w;
l=(k/100)*h;

X=((a>0?w-x+q:x+q)/w-.5) * 2 * s;
Y=((b>0?h-y+l:y+l)/h-.5) * 2 *t;

g=1*10^(-f);

U=sqrt(n);
V=sqrt(o);

Z=((X-Y) * (X-U) * (X+U) * (Y-V) * (Y+V))+e;
D=t>0?(1-(Z>g?Z:1-Z * -1)):Z;
C=D*D;

F=abs(C)>1?C-int(C):C;1-F;
"
``````

EDIT: Code would not result into the picture as I have updated the code.

With this code, I can flip orientation, change scale factor by axis, change elevation, change orientation… So, essentially, it has the potential to become much better than the original PDN Vibrato filter. After this filter, I will work on recreating Nebulous next.

EDIT - Current proof of concept code for G’MIC

``````#@gui Vibrato Filter : fx_vibrato, fx_vibrato_preview(0)
#@gui : note = note("This filter is inspired by the Paint.NET plugin named Vibrato authored by MadJik for Paint.NET.")
#@gui : sep = separator()
#@gui : 1. X-Orientation = bool(1)
#@gui : 2. Y-Orientation = bool(1)
#@gui : 3. U- Factor = float(1,.25,15)
#@gui : 4. V- Factor = float(1,.25,15)
#@gui : 5. X-Scale Factor = float(1,.5,5)
#@gui : 6. Y-Scale Factor = float(1,.5,5)
#@gui : 7. Percentage-Based X Pixel Shift = float(0,0,100)
#@gui : 8. Percentage-Based Y Pixel Shift = float(0,0,100)
#@gui : 9. Elevation = float(0,-250,250)
#@gui : 10. Apply Inversion Factor = bool(1)
#@gui : 11. Inversion Factor = float(1,-1,10)
#@gui : 12. Final Mod Factor = float(1,1,32)
#@gui : sep = separator(), Preview type = choice("Full","Forward horizontal","Forward vertical","Backward horizontal","Backward vertical","Duplicate top","Duplicate left","Duplicate bottom","Duplicate right","Duplicate horizontal","Duplicate vertical","Checkered","Checkered inverse")
#@gui : sep = separator(), note = note("<small>Author : <i>Reptorian</i>.      Latest update : <i>2018/09/22</i>.</small>")
fx_vibrato:
repeat \$! l[\$>]
if {x+\$1}
n 0,255 f "q=(\$7/100)*w; l=(\$8/100)*h; X=((\$1?w-x+q:x+q)/w-.5) * 2 * \$5; Y=((\$2?h-y+l:y+l)/h-.5) * 2 * \$6; g=1*10^(-\$11); U=sqrt(\$3); V=sqrt(\$4); Z=((X-Y) * (X-U) * (X+U) * (Y-V) * (Y+V))+ \$9; D=\$10?(1-(Z>g?Z:1-Z * -1)):Z;C=D*D;F=abs(C)>1?C-int(C):C;1-F;" n 0,255 mul \$12 mod 256
fi endl done
fx_vibrato_preview :
gui_split_preview "fx_vibrato \${1--2}",\$-1
``````

Something is really fishy about the \$1. I believe it’s a bug. But, in any case, that can be worked around by adding a line of code somewhere else.

(G'MIC staff) #2

What is this line intended for ?

``````if {x+\$1}
``````

In this case, `x` will always evaluate to `0` , so this is equivalent to

``````if \$1
``````

which has actually nothing to do with the `X-Orientation` parameter you deal with.
So what is the point of having this if defined like this ? I don’t get it.

#3

It’s for the preview thing. I moved it, and preview still works out as well as the x-flipping factor. I’ll continue working on the filter later. My goals are:

• Vibrato can work on individual channels
• Vibrato can work on RGB, HSL, HSV, LAB, LCH, YUV…
• Vibrato can be used to distort channels
• Vibrato can have blending modes
• Vibrato can be used to generate the texture only with or without alpha

I think I might just make two different version. One just for the texture, and the other would technically be Vibrato+.

(G'MIC staff) #4

I still don’t get it.

#5

Remove it, and see preview timeout which is not what I want to happen.

(G'MIC staff) #6

With:

``````#@gui Vibrato Filter : fx_vibrato, fx_vibrato_preview(0)
#@gui : note = note("This filter is inspired by the Paint.NET plugin named Vibrato authored by MadJik for Paint.NET.")
#@gui : sep = separator()
#@gui : 1. X-Orientation = bool(1)
#@gui : 2. Y-Orientation = bool(1)
#@gui : 3. U- Factor = float(1,.25,15)
#@gui : 4. V- Factor = float(1,.25,15)
#@gui : 5. X-Scale Factor = float(1,.5,5)
#@gui : 6. Y-Scale Factor = float(1,.5,5)
#@gui : 7. Percentage-Based X Pixel Shift = float(0,0,100)
#@gui : 8. Percentage-Based Y Pixel Shift = float(0,0,100)
#@gui : 9. Elevation = float(0,-250,250)
#@gui : 10. Apply Inversion Factor = bool(1)
#@gui : 11. Inversion Factor = float(1,-1,10)
#@gui : 12. Final Mod Factor = float(1,1,32)
#@gui : sep = separator(), Preview type = choice("Full","Forward horizontal","Forward vertical","Backward horizontal","Backward vertical","Duplicate top","Duplicate left","Duplicate bottom","Duplicate right","Duplicate horizontal","Duplicate vertical","Checkered","Checkered inverse")
#@gui : sep = separator(), note = note("<small>Author : <i>Reptorian</i>.      Latest update : <i>2018/09/22</i>.</small>")
fx_vibrato:
repeat \$! l[\$>]
#if {x+\$1}
n 0,255 f "q=(\$7/100)*w; l=(\$8/100)*h; X=((\$1?w-x+q:x+q)/w-.5) * 2 * \$5; Y=((\$2?h-y+l:y+l)/h-.5) * 2 * \$6; g=1*10^(-\$11); U=sqrt(\$3); V=sqrt(\$4); Z=((X-Y) * (X-U) * (X+U) * (Y-V) * (Y+V))+ \$9; D=\$10?(1-(Z>g?Z:1-Z * -1)):Z;C=D*D;F=abs(C)>1?C-int(C):C;1-F;" n 0,255 mul \$12 mod 256
# fi
endl done

fx_vibrato_preview :
gui_split_preview "fx_vibrato \${1--2}",\$-1
``````

I don’t get any preview timeout :

I don’t see why this line would change something about the computation time used for the preview.
What version of G’MIC do you use ? on GIMP, Krita ?

#7

Krita is my main 2D software of choice. Without having that line, preview wouldn’t work from what I seen, but again I do acknowledge Krita G’MIC has more problems than GIMP G’MIC though both have their own series of issues filters. But your solution with # works too. Moving it just before fi endl done also works.

EDIT: Now, I’m up to here. -

``````#@gui Vibrato Texture : fx_vibrato_texture, fx_vibrato_texture_preview(0)
#@gui : note = note("This filter is inspired by the Paint.NET plugin named Vibrato authored by MadJik for Paint.NET.")
#@gui : sep = separator()
#@gui : 1. X-Orientation = bool(1)
#@gui : 2. Y-Orientation = bool(1)
#@gui : 3. U- Factor = float(1,.25,15)
#@gui : 4. V- Factor = float(1,.25,15)
#@gui : 5. X-Scale Factor = float(1,.5,5)
#@gui : 6. Y-Scale Factor = float(1,.5,5)
#@gui : 7. Percentage-Based X Pixel Shift = float(0,-100,100)
#@gui : 8. Percentage-Based Y Pixel Shift = float(0,-100,100)
#@gui : 9. Elevation = float(0,-250,250)
#@gui : 10. Apply Inversion Factor = bool(1)
#@gui : 11. Inversion Factor = float(1,-1,10)
#@gui : 12. Final Mod Factor = float(1,1,32)
#@gui : sep = separator(), Channel(s) = choice{"All","RGBA [all]","RGB [all]","RGB [red]","RGB [green]","RGB [blue]","RGBA [alpha]","Linear RGB [all]","Linear RGB [red]","Linear RGB [green]","Linear RGB [blue]","YCbCr [luminance]","YCbCr [blue-red chrominances]","YCbCr [blue chrominance]","YCbCr [red chrominance]","YCbCr [green chrominance]","Lab [lightness]","Lab [ab-chrominances]","Lab [a-chrominance]","Lab [b-chrominance]","Lch [ch-chrominances]","Lch [c-chrominance]","Lch [h-chrominance]","HSV [hue]","HSV [saturation]","HSV [value]","HSI [intensity]","HSL [lightness]","CMYK [cyan]","CMYK [magenta]","CMYK [yellow]","CMYK [key]","YIQ [luma]","YIQ [chromas]"}
#@gui : sep = separator(), Preview type = choice("Full","Forward horizontal","Forward vertical","Backward horizontal","Backward vertical","Duplicate top","Duplicate left","Duplicate bottom","Duplicate right","Duplicate horizontal","Duplicate vertical","Checkered","Checkered inverse")
#@gui : sep = separator(), note = note("<small>Author : <i>Reptorian</i>.      Latest update : <i>2018/09/22</i>.</small>")
fx_vibrato_texture:
repeat \$! l[\$>]
#if {x+\$1}
n 0,255 f "q=(\$7/100)*w; l=(\$8/100)*h; X=((\$1?w-x+q:x+q)/w-.5) * 2 * \$5; Y=((\$2?h-y+l:y+l)/h-.5) * 2 * \$6; g=1*10^(-\$11); U=sqrt(\$3); V=sqrt(\$4); Z=((X-Y) * (X-U) * (X+U) * (Y-V) * (Y+V))+ \$9; D=\$10?(1-(Z>g?Z:1-Z * -1)):Z;C=D*D;F=abs(C)>1?C-int(C):C;1-F;" n 0,255 mul \$12 mod 256
apply_channels "fx_vibrato_texture \${1-13}",\$13,0 endl done
# fi
endl done

fx_vibrato_texture_preview :
gui_split_preview "fx_vibrato_texture \${1--2}",\$-1
``````

a c doesn’t seem to be doing it. nor +channels. nor channel spread. I’m trying to make the filter apply to only to specified channels or using specified channels. I’d really like to see if I can overlay the pattern on to a specific picture channel.

#8

Do you really want to define a recursive filter (it calls itself)?

``````fx_vibrato_texture:
...
apply_channels "fx_vibrato_texture..."
``````

Something which might be causing issues while developing is how the parameter evaluation works. If a parameter is not referenced within the filter, it can do some unexpected things (because gmic then thinks it requires none). At least that used to be the case. So something you often see is this:

``````my_filter : skip \${1=1},\${2=1}
``````

The skip command tells gmic to ignore the next statement, but the macro/substitution will happen anyway. In other words it protects against the situation where your parameter is not used in the filter. Maybe that will help avoiding the preview timeout!

#9

EDIT: I have completed the basic version!
EDIT: Well, almost there. Doesn’t work like how I want it to, but it’ll do for now. Works great for generating vibrato background. For generic editing, a new version will be created.

``````#@gui Vibrato Texture : fx_vibrato_texture, fx_vibrato_texture_preview(0)
#@gui : note = note("This filter is inspired by the Paint.NET plugin named Vibrato authored by MadJik for Paint.NET.")
#@gui : sep = separator()
#@gui : 1. X-Orientation = bool(1)
#@gui : 2. Y-Orientation = bool(1)
#@gui : 3. U- Factor = float(1,.25,15)
#@gui : 4. V- Factor = float(1,.25,15)
#@gui : 5. X-Scale Factor = float(1,.5,5)
#@gui : 6. Y-Scale Factor = float(1,.5,5)
#@gui : 7. Percentage-Based X Pixel Shift = float(0,-100,100)
#@gui : 8. Percentage-Based Y Pixel Shift = float(0,-100,100)
#@gui : 9. Elevation = float(0,-250,250)
#@gui : 10. Apply Inversion Factor = bool(1)
#@gui : 11. Inversion Factor = float(1,-1,10)
#@gui : 12. Final Mod Factor = float(1,1,32)
#@gui : sep = separator(), Channel(s) = choice{"All","RGBA [all]","RGB [all]","RGB [red]","RGB [green]","RGB [blue]","RGBA [alpha]","Linear RGB [all]","Linear RGB [red]","Linear RGB [green]","Linear RGB [blue]","YCbCr [luminance]","YCbCr [blue-red chrominances]","YCbCr [blue chrominance]","YCbCr [red chrominance]","YCbCr [green chrominance]","Lab [lightness]","Lab [ab-chrominances]","Lab [a-chrominance]","Lab [b-chrominance]","Lch [ch-chrominances]","Lch [c-chrominance]","Lch [h-chrominance]","HSV [hue]","HSV [saturation]","HSV [value]","HSI [intensity]","HSL [lightness]","CMYK [cyan]","CMYK [magenta]","CMYK [yellow]","CMYK [key]","YIQ [luma]","YIQ [chromas]"}
#@gui : sep = separator(), Preview type = choice("Full","Forward horizontal","Forward vertical","Backward horizontal","Backward vertical","Duplicate top","Duplicate left","Duplicate bottom","Duplicate right","Duplicate horizontal","Duplicate vertical","Checkered","Checkered inverse")
#@gui : sep = separator(), note = note("<small>Author : <i>Reptorian</i>.      Latest update : <i>2018/09/22</i>.</small>")
fx_vibrato_texture:
ac "_fx_vibrato_texture \${1-13}",\$13

_fx_vibrato_texture:
repeat \$! l[\$>]
#if {x+\$1}
n 0,255 f "q=(\$7/100)*w; l=(\$8/100)*h; X=((\$1?w-x+q:x+q)/w-.5) * 2 * \$5; Y=((\$2?h-y+l:y+l)/h-.5) * 2 * \$6; g=1*10^(-\$11); U=sqrt(\$3); V=sqrt(\$4); Z=((X-Y) * (X-U) * (X+U) * (Y-V) * (Y+V))+ \$9; D=\$10?(1-(Z>g?Z:1-Z * -1)):Z;C=D*D;F=abs(C)>1?C-int(C):C;1-F;" n 0,255 mul \$12 mod 256
# fi
endl done

fx_vibrato_texture_preview :
gui_split_preview "fx_vibrato_texture \${1--2}",\$-1
``````

Sample of the Basic Vibrato Texture :

I think that’s enough pictures.

Now, I call the basic done as I’m not interested into adding more conditions inside the code to have image influence vibrato result over 1.0. There is a mathematical mechanic to force the image to not influence it as much in case if it goes way under 1 or way over 1. If you remove that, you can get the image to alter the vibrato result a lot more. :

``````#@gui Vibrato Texture : fx_vibrato_texture, fx_vibrato_texture_preview(0)
#@gui : note = note("This filter is inspired by the Paint.NET plugin named Vibrato authored by MadJik for Paint.NET.")
#@gui : sep = separator()
#@gui : 1. X-Orientation = bool(1)
#@gui : 2. Y-Orientation = bool(1)
#@gui : 3. U- Factor = float(.85,.25,15)
#@gui : 4. V- Factor = float(.85,.25,15)
#@gui : 5. X-Scale Factor = float(1,.5,5)
#@gui : 6. Y-Scale Factor = float(1,.5,5)
#@gui : 7. Percentage-Based X Pixel Shift = float(0,-100,100)
#@gui : 8. Percentage-Based Y Pixel Shift = float(0,-100,100)
#@gui : 9. Elevation = float(.7,-1,1)
#@gui : 10. Z-Multiplier = float(.5,0,5)
#@gui : 11. Apply Inversion Factor = bool(0)
#@gui : 12. Inversion Factor = float(1,-1,10)
#@gui : 13. Final Mod Factor = float(1,1,32)
#@gui : sep = separator(), 14. Image Influence Factor = float(1,0,1)
#@gui : sep = separator(), Channel(s) = choice{"All","RGBA [all]","RGB [all]","RGB [red]","RGB [green]","RGB [blue]","RGBA [alpha]","Linear RGB [all]","Linear RGB [red]","Linear RGB [green]","Linear RGB [blue]","YCbCr [luminance]","YCbCr [blue-red chrominances]","YCbCr [blue chrominance]","YCbCr [red chrominance]","YCbCr [green chrominance]","Lab [lightness]","Lab [ab-chrominances]","Lab [a-chrominance]","Lab [b-chrominance]","Lch [ch-chrominances]","Lch [c-chrominance]","Lch [h-chrominance]","HSV [hue]","HSV [saturation]","HSV [value]","HSI [intensity]","HSL [lightness]","CMYK [cyan]","CMYK [magenta]","CMYK [yellow]","CMYK [key]","YIQ [luma]","YIQ [chromas]"}
#@gui : sep = separator(), Preview type = choice("Full","Forward horizontal","Forward vertical","Backward horizontal","Backward vertical","Duplicate top","Duplicate left","Duplicate bottom","Duplicate right","Duplicate horizontal","Duplicate vertical","Checkered","Checkered inverse")
#@gui : sep = separator(), note = note("<small>Author : <i>Reptorian</i>.      Latest update : <i>2018/09/22</i>.</small>")
fx_vibrato_texture:
ac "_fx_vibrato_texture \${1-15}",\$15

_fx_vibrato_texture:
repeat \$! l[\$>]
#if {x+\$1}
n 0,255 f "q=(\$7/100)*w;
l=(\$8/100)*h;
X=((\$1?w-x+q:x+q)/w-.5) * 2 * \$5;
Y=((\$2?h-y+l:y+l)/h-.5) * 2 * \$6;
g=1*11^(-\$12);
U=sqrt(\$3);
V=sqrt(\$4);
Z=((X-Y) * (X-U) * (X+U) * (Y-V) * (Y+V))+ \$9;
D=\$11?(1-(Z>g?Z:1-Z * -1)):Z;
C=(D+((1-i/255)/((\$3>1?\$3:1/\$3)*(\$4>1?\$4:1/\$4)))*\$14)*(D+((1-i/255)/((\$3>1?\$3:1/\$3)*(\$4>1?\$4:1/\$4)))*\$14)*\$10;
F=abs(C)>1?C-int(C):C;
1-F;
" n 0,255 mul \$13 mod 256
# fi
endl done

fx_vibrato_texture_preview :
gui_split_preview "fx_vibrato_texture \${1--2}",\$-1``````

(dumb) #10

Changed the parameter ranges:

``````#@gui : 1. X-Orientation = bool(1)
#@gui : 2. Y-Orientation = bool(1)
#@gui : 3. U- Factor = float(.85,.1,15)
#@gui : 4. V- Factor = float(.85,.1,15)
#@gui : 5. X-Scale Factor = float(1,.1,5)
#@gui : 6. Y-Scale Factor = float(1,.1,5)
#@gui : 7. Percentage-Based X Pixel Shift = float(0,-200,200)
#@gui : 8. Percentage-Based Y Pixel Shift = float(0,-200,200)
#@gui : 9. Elevation = float(.7,-1,1)
#@gui : 10. Z-Multiplier = float(.5,0,5)
#@gui : 11. Apply Inversion Factor = bool(0)
#@gui : 12. Inversion Factor = float(1,-1,10)
#@gui : 13. Final Mod Factor = float(1,1,32)
#@gui : sep = separator(), 14. Image Influence Factor = float(1,-8,8)
``````

…so that it’s easier to make things like this:

Note that this doesn’t change the command itself, only what the GUI allows.

#11

I actually tested the new parameter, and it did shown that I didn’t need to add more conditions to make the image influence the vibrato more, it’s just a simple change, and also did saw that negatives would work too. So, I’m keeping the parameters, then.

I’m going to try to do Vibrato+, and Vibrato Distort. I think I only have to copy vibrato into the code of vibrato distort, and add -distort code into it with the only specified channels are luminosity varients. Vibrato+ will use vibrato distort, and the basic vibrato while it can be used to run on HSV, HSL, LCH, RGB, CMY as if you can work on vibrato’ing different channels, and have the option to distort channels. The only issue with the advanced vibrato idea is that it might involve adding a lot of lines of code, but if I could copy fx_something_something with X,Y,Z,C,D,E… next to it to define variables, that’ll reduce the lines of codes required for such a thing.

Changes

1. Scale Behavior is now more intuitive
2. Joan_Rake1 parameter suggestion considered.
3. Invert Vibrato Operation is now applicable
4. XY Scale Factor is now added. Now you can scale the entire vibrato form.

Here’s the final version of ‘Vibrato Texture’

``````#@gui Vibrato Texture : fx_vibrato_texture, fx_vibrato_texture_preview(0)
#@gui : note = note("This filter is inspired by the Paint.NET plugin named Vibrato authored by MadJik for Paint.NET.")
#@gui : sep = separator()
#@gui : 1. X-Orientation = bool(1)
#@gui : 2. Y-Orientation = bool(1)
#@gui : 3. U- Factor = float(.85,.1,15)
#@gui : 4. V- Factor = float(.85,.1,15)
#@gui : 5. X-Scale Factor = float(1,.1,15)
#@gui : 6. Y-Scale Factor = float(1,.1,15)
#@gui : 7. XY-Scale Factor = float(1,.1,3)
#@gui : 8. Percentage-Based X Pixel Shift = float(0,-200,200)
#@gui : 9. Percentage-Based Y Pixel Shift = float(0,-200,200)
#@gui : 10. Elevation = float(.7,-1,1)
#@gui : 11. Z 0-1 Multiplier = float(.5,0.1,1)
#@gui : 12. Z Exponential Multiplier = float(1,1,15)
#@gui : 13. Apply Inversion Factor = bool(0)
#@gui : 14. Inversion Factor = float(1,-1,10)
#@gui : 15. Final Mod Factor = float(1,1,32)
#@gui : 16. Invert Vibrato = bool(0)
#@gui : sep = separator(), 17. Image Influence Factor = float(1,-8,8)
#@gui : sep = separator(), Channel(s) = choice{"All","RGBA [all]","RGB [all]","RGB [red]","RGB [green]","RGB [blue]","RGBA [alpha]","Linear RGB [all]","Linear RGB [red]","Linear RGB [green]","Linear RGB [blue]","YCbCr [luminance]","YCbCr [blue-red chrominances]","YCbCr [blue chrominance]","YCbCr [red chrominance]","YCbCr [green chrominance]","Lab [lightness]","Lab [ab-chrominances]","Lab [a-chrominance]","Lab [b-chrominance]","Lch [ch-chrominances]","Lch [c-chrominance]","Lch [h-chrominance]","HSV [hue]","HSV [saturation]","HSV [value]","HSI [intensity]","HSL [lightness]","CMYK [cyan]","CMYK [magenta]","CMYK [yellow]","CMYK [key]","YIQ [luma]","YIQ [chromas]"}
#@gui : sep = separator(), Preview type = choice("Full","Forward horizontal","Forward vertical","Backward horizontal","Backward vertical","Duplicate top","Duplicate left","Duplicate bottom","Duplicate right","Duplicate horizontal","Duplicate vertical","Checkered","Checkered inverse")
#@gui : sep = separator(), note = note("<small>Author : <i>Reptorian</i>.      Latest update : <i>2018/09/26</i>.</small>")
fx_vibrato_texture:
ac "_fx_vibrato_texture \${1-18}",\$18

_fx_vibrato_texture:
repeat \$! l[\$>]
#if {x+\$1}
n 0,255 f "q=(\$8/100)*w;
l=(\$9/100)*h;
X=((\$1?w-x+q:x+q)/w-.5) * 2 * 1/\$5 * 1/\$7;
Y=((\$2?h-y+l:y+l)/h-.5) * 2 * 1/\$6 * 1/\$7;
g=1*13^(-\$14);
U=sqrt(\$3);
V=sqrt(\$4);
Z=((X-Y) * (X-U) * (X+U) * (Y-V) * (Y+V))+ \$10;
D=\$13?(1-(Z>g?Z:1-Z * -1)):Z;
C=(D+((1-i/255)/((\$3>1?\$3:1/\$3)*(\$4>1?\$4:1/\$4)))*\$17)*(D+((1-i/255)/((\$3>1?\$3:1/\$3)*(\$4>1?\$4:1/\$4)))*\$17)*\$11*\$12*\$12;
F=abs(C)>1?C-int(C):C;
\$16?F:1-F;
" n 0,255 mul \$15 mod 256
# fi
endl done

fx_vibrato_texture_preview :
gui_split_preview "fx_vibrato_texture \${1--2}",\$-1
``````

A quick screenie displaying the new changes

@Joan_Rake1

I’m testing this in the custom code to find out how warp works in order to make vibrato distort happen, but there’s something that’s confuse me though.

`````` 100%,100%,1,2,'X=x/w-0.5;Y=y/h-0.5;R=(X*X+Y*Y)^0.5;A=atan2(Y,X);130*R*if(c==0,cos(4*A),sin(8*A))' warp[-2] [-1],1,1,0
``````

What am I looking at in 1,2 section after 100%. I believe 100% refers to scale of X and Y axis. Also, I’m a little confused at the numbers after warp. The middle part, I do understand.

I’m looking at this section

`````` "{w}","{h}","{d}","{s}"
``````

d, and s are something… the 1 after [] seem to be about the field output. The 1 after seem to do with lightness/darkness. And the 0, I have no idea. I also am trying to input vibrato inside ‘’ to avoid having to copy and paste equation, but it seems that’s the direction I have to go in if I want to do vibrato distort.

#12

#13

I beleive that 100%,100%,1,2 …

means

• 100% of the width of the last image in the list
• 100% of the height of the last image in the list
• 1 pixel of depth (ie a flat image, not a 3D dataset)
• 2 colour channels (which are used to represent warping intensity in x and y directions)

#14

Just got into work into replicating nebulous from paint net plugin. I know the form is wrong, but I think I know how to fix that issue. There is a slant which is what created the nebulous look. atan2 is something i’ll use. I’m testing math expression in 3d mathematical software to evaluate before going into the local code, and then after that i create the g’mic function.

Here’s the one in paintnet

Here’s my major concern, I’m just not sure how to get G’MIC to define lightness by depth angle rather than z level. @David_Tschumperle , does G’MIC support this? z level wouldn’t work in this case unless I use a slope to differentiate between z, and find angle from there.

EDIT: Actually never mind, I think I might be able to get what I want using atan(x)+sin(x) as the difference surface.

EDIT: Leaving note here for the night

``````(atan(u^2+v^2)+sin(u*u+v*v)/2)+v/4
``````

EDIT: Using K3DSurf, I found this really interesting surface that might be just the one

`````` abs((atan2(x*1.5,abs(y^2))-cos(x^2+y^2)))
``````

There is a issue though. Moire would probably show up, and just in case it do indeed show up, I believe radial blur would fix the moire issue. There’s also some issue with the sin-like form in the x axis. Hmmm…

I also do have the source code for nebulous in case anyone wondering.

``````((atan2(x,y^2))-atan(x/2))
``````

`````` abs(((atan2(x*4,y^2))+atan(x/8))+(sin(sqrt(x^2+y^2))^2))
``````

Alternative version :

`````` (((atan2(x*4,y^2))+atan(x/8))+(sin(sqrt(x^2+y^2))^2))*2
``````

Possible final version :

``````(((atan2(x,(y/2)^2))+atan(x/8))+(sin(sqrt(x^2+y^2))^2))*2+(atan(x)+cos(y/8))
``````

This should get me real close to the nebulous formula, actually I might just make my own version of it.

#15

What is meant by “depth angle”? Is it surface normal or derivative or something else? It seems you’re nearly at the answer anyway, I think we’ll just watch your progress

Don’t forget gmic can render 3D objects/surfaces as well (admittedly it can be a bit tricky to get used to)!

#16

I wonder if it has to do with the angle or tilt of the 3d object relative to the 2d plane. I recall there being a discussion of that in the forum.

#17

There is a discussion of that? Yes, it has to do with surface normals. But, I’m confident I am getting closer anyway without taking into surface normals into account.