Initial community commit
This commit is contained in:
@@ -0,0 +1,772 @@
|
||||
<HTML>
|
||||
<A NAME="milkdrop_preset_authoring_top">
|
||||
<PRE>
|
||||
|
||||
<B>MILKDROP preset authoring guide</B>
|
||||
<A HREF="milkdrop.html">return to milkdrop.html</A>
|
||||
|
||||
|
||||
|
||||
* * *
|
||||
Note that there is another, quite comprehensive, Preset Authoring Guide
|
||||
available on the web at <A HREF="http://www.milkdrop.co.uk/">http://www.milkdrop.co.uk/</A>, which is continually
|
||||
updated and expanded through the hard work of a few dedicated preset
|
||||
authors. Whereas this guide (the one you are currently viewing) gives the bare
|
||||
technical specifications for writing your own presets, the guide at milkdrop.co.uk
|
||||
'starts at the beginning' and walks you through all of the mathematics and subtleties
|
||||
of 'rolling your own', explaining things in great detail. The guide at milkdrop.co.uk
|
||||
is very highly recommended to anyone who wishes to learn more about creating their
|
||||
own presets.
|
||||
* * *
|
||||
|
||||
|
||||
<B>Section Listing</B>
|
||||
-----------------------
|
||||
1. <A HREF="#1">about presets</A>
|
||||
2. <A HREF="#2">preset authoring - basic</A>
|
||||
3. <A HREF="#3">preset authoring - advanced</A>
|
||||
a. <A HREF="#3a">per-frame equations</A>
|
||||
b. <A HREF="#3b">per-pixel equations</A>
|
||||
c. <A HREF="#3c">preset initialization code and q1-q8</A>
|
||||
d. <A HREF="#3d">custom shapes & waves</A>
|
||||
e. <A HREF="#3e">quality assurance</A>
|
||||
f. <A HREF="#3f">debugging</A>
|
||||
g. <A HREF="#3g">function reference</A>
|
||||
|
||||
|
||||
<A NAME="1">
|
||||
<B>1. About Presets</B>
|
||||
-----------------------
|
||||
A 'preset' is a collection of parameters that tell MilkDrop how to
|
||||
draw the wave, how to warp the image around, and so on. MilkDrop
|
||||
ships with around ~100 built-in presets, each one having a distinct
|
||||
look and feel to it.
|
||||
|
||||
Using MilkDrop's built-in "preset-editing menu", you can edit presets
|
||||
on the fly, from within the program. You can make slight adjustments
|
||||
to existing presets, then save over them; or you can change lots of
|
||||
things, so the preset doesn't look anything like the original, and
|
||||
then save it under a new name. You can even write insane new
|
||||
mathematical equations, of your own imagination, into your preset
|
||||
files and come up with things that MilkDrop has never done before!
|
||||
|
||||
Each preset is saved as a file with the ".milk" extension, so you can
|
||||
easily send them to your friends or post them on the web. You can also
|
||||
go to <A HREF="http://www.nullsoft.com/free/milkdrop">http://www.nullsoft.com/free/milkdrop</A> and then jump to the
|
||||
"preset sharing forum" to see what other people have come up with,
|
||||
or post your own cool, new presets.
|
||||
|
||||
|
||||
<A NAME="2">
|
||||
<B>2. Preset Authoring - Basic</B>
|
||||
-----------------------
|
||||
|
||||
You can edit the properties of the current preset by hitting 'M',
|
||||
which brings up the "preset-editing menu". From this menu you
|
||||
can use the up and down arrow keys to select an item. Press
|
||||
the RIGHT arrow key to move forward through the menu and select
|
||||
the item (note: you can also hit SPACE or RETURN to do this);
|
||||
***press the LEFT arrow key to go back to the previous menu.***
|
||||
|
||||
Pressing 'M' while the menu is already showing will hide the menu;
|
||||
pressing ESCAPE will do the same thing. Press 'M' again to bring
|
||||
the menu back.
|
||||
|
||||
Once you've reached an item on the menu whose value can be edited,
|
||||
use the UP and DOWN arrow keys to increase or decrease its value,
|
||||
respectively. Changes will register immediately. Use PAGE UP and
|
||||
PAGE DOWN to increase the value more quickly. Hold down SHIFT
|
||||
and use the UP/DOWN arrow keys to change the value very slowly.
|
||||
Hit RETURN To keep the new value, or ESC to abort the change.
|
||||
|
||||
If the item you're editing is a text string, you can use the
|
||||
arrow keys to move around. The Insert key can be used to toggle
|
||||
between insert and overtype modes. You can hold shift and use
|
||||
the arrow keys (home, end, left, right) to make a selection,
|
||||
which will be identified by brackets []. You can then use CTRL-C
|
||||
or CTRL-X to copy or cut text. CTRL-P pastes. When finished
|
||||
editing, hit RETURN To keep the new string, or ESC to abort the
|
||||
change.
|
||||
|
||||
You'll want to get into the habit of using SCROLL LOCK whenever
|
||||
you're making changes to a preset that you intend to save;
|
||||
otherwise, the preset is sure to keep randomly changing on you.
|
||||
You might ask me, "why don't you just automatically lock the
|
||||
preset while the menu is up?" I will answer you, "because in
|
||||
the instant between exiting the menu and going to save the preset,
|
||||
the preset might then switch, and you'd lose your changes." Then
|
||||
you might ask me, "then why don't you just leave it locked
|
||||
whenever the user makes a change from the menu?" and I will say
|
||||
to you, "because I hate it when programs do things like that. You
|
||||
have an idea in your brain about the state of the Scroll Lock key,
|
||||
because you're the one setting that state. I want your mind to
|
||||
always be up-to-date." And you might then ask me: "how large is
|
||||
large?" And I will tell you: "thirty."
|
||||
|
||||
There are also some hotkeys that will allow you to change certain
|
||||
common parameters to the current preset. These are listed below.
|
||||
|
||||
MOTION
|
||||
i/I - zoom in/out
|
||||
[ / ] - push motion to the left/right (dx)
|
||||
{ / } - push motion up/down (dy)
|
||||
< / > - rotate left/right (rot)
|
||||
o/O - shrink/grow the amplitude of the warp effect
|
||||
|
||||
WAVEFORM
|
||||
W - cycle through waveforms
|
||||
j/J - scale waveform down/up
|
||||
e/E - make the waveform more transparent/more solid
|
||||
|
||||
BRIGHTNESS
|
||||
d/D - decrease, increase decay (fades image to black over time)
|
||||
g/G - decrease, increase gamma (brightness)
|
||||
|
||||
VIDEO ECHO effect
|
||||
q/Q - scale 2nd graphics layer down/up
|
||||
a/A - decrease/increase alpha of 2nd graphics layer
|
||||
F - flip 2nd graphics layer (cycles through 4 fixed orientations)
|
||||
|
||||
|
||||
|
||||
<A NAME="3">
|
||||
<B>3. Preset Authoring - Advanced</B>
|
||||
-----------------------
|
||||
|
||||
This section describes how to use the 'per-frame' and 'per-pixel'
|
||||
equations to develop unique new presets.
|
||||
|
||||
|
||||
<A NAME="3a">
|
||||
<B>a. PER-FRAME EQUATIONS</B>
|
||||
----------------------
|
||||
|
||||
When you hit 'm' to show the preset-editing menu, several items
|
||||
show up. If you explore the sub-menus, you'll see that
|
||||
all of the properties that make up the preset you're currently
|
||||
viewing are there. The values you can specify here (such as
|
||||
zoom amount, rotation amount, wave color, etc.) are all static
|
||||
values, meaning that they don't change in time. For example,
|
||||
take the 'zoom amount' option under the 'motion' submenu.
|
||||
If this value is 1.0, there is no zoom. If the value is 1.01,
|
||||
the image zooms in 1% every frame. If the value is 1.10, the
|
||||
image zooms in 10% every frame. If the value is 0.9, the image
|
||||
zooms out 10% every frame; and so on.
|
||||
|
||||
However, presets get far more interesting if you can take these
|
||||
parameters (such as the zoom amount) and animate them (make them
|
||||
change over time). For example, if you could take the 'zoom
|
||||
amount' parameter and make it oscillate (vary) between 0.9 and
|
||||
1.1 over time, the image would cyclically zoom in and out, in
|
||||
time.
|
||||
|
||||
You can do this - by writing 'per-frame' and 'per-pixel'
|
||||
equations. Let's start with 'per-frame' equations. These are
|
||||
executed once per frame. So, if you were to type the following
|
||||
equation in:
|
||||
|
||||
zoom = zoom + 0.1*sin(time);
|
||||
|
||||
...then the zoom amount would oscillate between 0.9 and 1.1
|
||||
over time. (Recall from your geometry classes that sin()
|
||||
returns a value between -1 and 1.) The equation says: "take
|
||||
the static value of 'zoom', then replace it with that value,
|
||||
plus some variation." This particular equation would oscillate
|
||||
(cycle) every 6.28 seconds, since the sin() function's
|
||||
period is 6.28 (PI*2) seconds. If you wanted it to make it
|
||||
cycle every 2 seconds, you could use:
|
||||
|
||||
zoom = zoom + 0.1*sin(time*3.14);
|
||||
|
||||
Now, let's say you wanted to make the color of the waveform
|
||||
(sound wave) that gets plotted on the screen vary through time.
|
||||
The color is defined by three values, one for each of the main
|
||||
color components (red, green, and blue), each in the range 0 to 1
|
||||
(0 is dark, 1 is full intensity). You could use something like this:
|
||||
|
||||
wave_r = wave_r + 0.5*sin(time*1.13);
|
||||
wave_g = wave_g + 0.5*sin(time*1.23);
|
||||
wave_b = wave_b + 0.5*sin(time*1.33);
|
||||
|
||||
It's nice to stagger the frequencies (1.13, 1.23, and 1.33) of
|
||||
the sine functions for the red, green, and blue color components
|
||||
of the wave so that they cycle at different rates, to avoid them
|
||||
always being all the same (which would create a greyscale wave).
|
||||
|
||||
Here is a full list of the variables available for writing per-frame
|
||||
equations:
|
||||
|
||||
NAME WRITABLE? RANGE DESCRIPTION
|
||||
---- --------- ----- -----------
|
||||
zoom yes >0 controls inward/outward motion. 0.9=zoom out 10% per frame, 1.0=no zoom, 1.1=zoom in 10%
|
||||
zoomexp yes >0 controls the curvature of the zoom; 1=normal
|
||||
rot yes controls the amount of rotation. 0=none, 0.1=slightly right, -0.1=slightly clockwise, 0.1=CCW
|
||||
warp yes >0 controls the magnitude of the warping; 0=none, 1=normal, 2=major warping...
|
||||
cx yes 0..1 controls where the center of rotation and stretching is, horizontally. 0=left, 0.5=center, 1=right
|
||||
cy yes 0..1 controls where the center of rotation and stretching is, vertically. 0=top, 0.5=center, 1=bottom
|
||||
dx yes controls amount of constant horizontal motion; -0.01 = move left 1% per frame, 0=none, 0.01 = move right 1%
|
||||
dy yes controls amount of constant vertical motion; -0.01 = move up 1% per frame, 0=none, 0.01 = move down 1%
|
||||
sx yes >0 controls amount of constant horizontal stretching; 0.99=shrink 1%, 1=normal, 1.01=stretch 1%
|
||||
sy yes >0 controls amount of constant vertical stretching; 0.99=shrink 1%, 1=normal, 1.01=stretch 1%
|
||||
wave_mode yes 0,1,2,3,4,5,6,7 controls which of the 8 types of waveform is drawn
|
||||
wave_x yes 0..1 position of the waveform: 0 = far left edge of screen, 0.5 = center, 1 = far right
|
||||
wave_y yes 0..1 position of the waveform: 0 = very bottom of screen, 0.5 = center, 1 = top
|
||||
wave_r yes 0..1 amount of red color in the wave (0..1),
|
||||
wave_g yes 0..1 amount of green color in the wave (0..1)
|
||||
wave_b yes 0..1 amount of blue color in the wave (0..1)
|
||||
wave_a yes 0..1 opacity of the wave (0..1) [0=transparent, 1=opaque]
|
||||
wave_mystery yes -1..1 what this parameter does is a mystery. (honestly, though, this value does different things for each waveform; for example, it could control angle at which the waveform was drawn.)
|
||||
wave_usedots yes 0/1 if 1, the waveform is drawn as dots (instead of lines)
|
||||
wave_thick yes 0/1 if 1, the waveform's lines (or dots) are drawn with double thickness
|
||||
wave_additive yes 0/1 if 1, the wave is drawn additively, saturating the image at white
|
||||
wave_brighten yes 0/1 if 1, all 3 r/g/b colors will be scaled up until at least one reaches 1.0
|
||||
ob_size yes 0..0.5 thickness of the outer border drawn at the edges of the screen every frame
|
||||
ob_r yes 0..1 amount of red color in the outer border
|
||||
ob_g yes 0..1 amount of green color in the outer border
|
||||
ob_b yes 0..1 amount of blue color in the outer border
|
||||
ob_a yes 0..1 opacity of the outer border (0=transparent, 1=opaque)
|
||||
ib_size yes 0..0.5 thickness of the inner border drawn at the edges of the screen every frame
|
||||
ib_r yes 0..1 amount of red color in the inner border
|
||||
ib_g yes 0..1 amount of green color in the inner border
|
||||
ib_b yes 0..1 amount of blue color in the inner border
|
||||
ib_a yes 0..1 opacity of the inner border (0=transparent, 1=opaque)
|
||||
mv_r yes 0..1 amount of red color in the motion vectors
|
||||
mv_g yes 0..1 amount of green color in the motion vectors
|
||||
mv_b yes 0..1 amount of blue color in the motion vectors
|
||||
mv_a yes 0..1 opacity of the motion vectors (0=transparent, 1=opaque)
|
||||
mv_x yes 0..64 the number of motion vectors in the X direction
|
||||
mv_y yes 0..48 the number of motion vectors in the Y direction
|
||||
mv_l yes 0..5 the length of the motion vectors (0=no trail, 1=normal, 2=double...)
|
||||
mv_dx yes -1..1 horizontal placement offset of the motion vectors
|
||||
mv_dy yes -1..1 vertical placement offset of the motion vectors
|
||||
decay yes 0..1 controls the eventual fade to black; 1=no fade, 0.9=strong fade, 0.98=recommended
|
||||
gamma yes >0 controls display brightness; 1=normal, 2=double, 3=triple, etc.
|
||||
echo_zoom yes >0 controls the size of the second graphics layer
|
||||
echo_alpha yes >0 controls the opacity of the second graphics layer; 0=transparent (off), 0.5=half-mix, 1=opaque
|
||||
echo_orient yes 0,1,2,3 selects an orientation for the second graphics layer. 0=normal, 1=flip on x, 2=flip on y, 3=flip on both
|
||||
darken_center yes 0/1 if 1, help keeps the image from getting too bright by continually dimming the center point
|
||||
wrap yes 0/1 sets whether or not screen elements can drift off of one side and onto the other
|
||||
invert yes 0/1 inverts the colors in the image
|
||||
brighten yes 0/1 brightens the darker parts of the image (nonlinear; square root filter)
|
||||
darken yes 0/1 darkens the brighter parts of the image (nonlinear; squaring filter)
|
||||
solarize yes 0/1 emphasizes mid-range colors
|
||||
monitor yes any set this value for debugging your preset code; if you hit the 'N' key,
|
||||
the value of 'monitor' will be posted in the upper-right corner of milkdrop.
|
||||
for example, setting "monitor = q3;" would let you keep an eye on q3's value.
|
||||
|
||||
time NO >0 retrieves the current time, in seconds, since MilkDrop started running
|
||||
fps NO >0 retrieves the current framerate, in frames per second.
|
||||
frame NO retrieves the number of frames of animation elapsed since the program started
|
||||
progress NO 0..1 progress through the current preset; if preset was just loaded, this is closer to 0; if preset is about to end, this is closer to 1.
|
||||
-note that if Scroll Lock is on, 'progress' will freeze!
|
||||
|
||||
bass NO >0 retrieves the current amount of bass. 1 is normal; below ~0.7 is quiet; above ~1.3 is loud bass
|
||||
mid NO >0 -same, but for mids (middle frequencies)
|
||||
treb NO >0 -same, but for treble (high) frequencies
|
||||
bass_att NO >0 retrieves an attenuated reading on the bass, meaning that it is damped in time and doesn't change so rapidly.
|
||||
mid_att NO >0 -same, but for mids (middle frequencies)
|
||||
treb_att NO >0 -same, but for treble (high) frequencies
|
||||
|
||||
meshx NO 8-128 tells you the user's mesh size in the X direction. always an integer value.
|
||||
meshy NO 6-96 tells you the user's mesh size in the Y direction. always an integer value.
|
||||
|
||||
q1 yes any }
|
||||
q2 yes any }
|
||||
q3 yes any }
|
||||
q4 yes any } Used to carry information between the per-frame code
|
||||
q5 yes any } and the per-pixel code; see below.
|
||||
q6 yes any }
|
||||
q7 yes any }
|
||||
q8 yes any }
|
||||
|
||||
|
||||
Some of the variables are read-only, meaning that you shouldn't change
|
||||
their values them through the equations. You can; it won't stop you;
|
||||
but the results are unpredictable.
|
||||
|
||||
You can also make up to 30 of your own variables. For example:
|
||||
|
||||
my_volume = (bass + mid + treb)/3;
|
||||
zoom = zoom + 0.1*(my_volume - 1);
|
||||
|
||||
This would make the zoom amount increase when the music is loud,
|
||||
and decrease when the music is quiet.
|
||||
|
||||
HOWEVER, custom variables do not carry over from per-frame equations
|
||||
to per-pixel equations; if you set a custom variable's value in the
|
||||
per-frame equations, and try to read it in the per-pixel equations,
|
||||
you will not get the correct value. Instead, you have to "bridge the
|
||||
gap" using 8 special variables: q1 through q8. This is usually only
|
||||
used when you want to precompute some custom values in the per-frame
|
||||
equations for later use in the per-pixel equations. For a good
|
||||
example of this, see the 'dynamic swirls' preset. See below for
|
||||
more information on q1-q8.
|
||||
|
||||
|
||||
|
||||
<A NAME="3b">
|
||||
<B>b. PER-PIXEL EQUATIONS</B>
|
||||
-----------------------
|
||||
|
||||
So far we've discussed only how to change parameters based on
|
||||
time. What if you wanted to also vary a parameter, such as the
|
||||
zoom amount, in different ways, for different locations on the
|
||||
screen? For example, normally, the result of the 'zoom' parameter
|
||||
is to just do a flat zoom. This doesn't look very realistic,
|
||||
because you don't see any perspective in the zoom. It would be
|
||||
better if we could give a unique zoom amount to each pixel on
|
||||
the screen; we could make the pixels far away from the center
|
||||
zoom more, and this would give it more perspective. In order
|
||||
to do this, we use "per-pixel" equations, instead of per-frame
|
||||
equations.
|
||||
|
||||
The code for this per-pixel equation is simple:
|
||||
|
||||
zoom = zoom + rad*0.1;
|
||||
|
||||
Where 'rad' is the radius of the pixel if it were cast into
|
||||
polar coordinates; from another perspective, 'rad' is the distance
|
||||
of the pixel from the center of the screen. 'rad is zero at the
|
||||
center, and 1 at the corners. So if we run the above code,
|
||||
the image will be zoomed into 10% more at the edges of the screen
|
||||
than at the center.
|
||||
|
||||
The per-pixel equations are really just like the per-frame equations,
|
||||
except for a variables. The following variables are available
|
||||
exclusively to per-pixel equations (and not to per-frame equations):
|
||||
|
||||
NAME WRITABLE? RANGE DESCRIPTION
|
||||
---- --------- ----- -----------
|
||||
x NO 0..1 retrieves the x-position of the current pixel. At the very left edge of the screen this would be 0; in the middle, 0.5; and at the right, 1.
|
||||
y NO 0..1 retrieves the y-position of the current pixel. At the very top edge of the screen this would be 0; in the middle, 0.5; and at the bottom, 1.
|
||||
rad NO 0..1 retrives the distance of the pixel from the center of the screen. At the center of the screen this will be zero, and at the corners, 1.
|
||||
(The middle of the edges will be 0.707 (half of the square root of 2).
|
||||
ang NO 0..6.28 retrieves the angle of the current pixel, with respect to the center of the screen.
|
||||
If the point is to the right of the center, this is zero; above it, it is PI/2 (1.57); to the left, it is PI (3.14); and below, it is 4.71 (PI*3/2).
|
||||
If it is just a dab below being directly to the right of the center of the screen, the value will approach 6.28 (PI*2).
|
||||
(note: this is simply the arctangent of y over x, precomputed for you.)
|
||||
|
||||
zoom yes >0 controls inward/outward motion. 0.9=zoom out 10% per frame, 1.0=no zoom, 1.1=zoom in 10%
|
||||
zoomexp yes >0 controls the curvature of the zoom; 1=normal
|
||||
rot yes controls the amount of rotation. 0=none, 0.1=slightly right, -0.1=slightly clockwise, 0.1=CCW
|
||||
warp yes >0 controls the magnitude of the warping; 0=none, 1=normal, 2=major warping...
|
||||
cx yes 0..1 controls where the center of rotation and stretching is, horizontally. 0=left, 0.5=center, 1=right
|
||||
cy yes 0..1 controls where the center of rotation and stretching is, vertically. 0=top, 0.5=center, 1=bottom
|
||||
dx yes controls amount of constant horizontal motion; -0.01 = move left 1% per frame, 0=none, 0.01 = move right 1%
|
||||
dy yes controls amount of constant vertical motion; -0.01 = move up 1% per frame, 0=none, 0.01 = move down 1%
|
||||
sx yes >0 controls amount of constant horizontal stretching; 0.99=shrink 1%, 1=normal, 1.01=stretch 1%
|
||||
sy yes >0 controls amount of constant vertical stretching; 0.99=shrink 1%, 1=normal, 1.01=stretch 1%
|
||||
|
||||
time NO >0 retrieves the current time, in seconds, since MilkDrop started running
|
||||
fps NO >0 retrieves the current framerate, in frames per second.
|
||||
frame NO retrieves the number of frames of animation elapsed since the program started
|
||||
progress NO 0..1 progress through the current preset; if preset was just loaded, this is closer to 0; if preset is about to end, this is closer to 1.
|
||||
-note that if Scroll Lock is on, 'progress' will freeze!
|
||||
|
||||
bass NO >0 retrieves the current amount of bass. 1 is normal; below ~0.7 is quiet; above ~1.3 is loud bass
|
||||
mid NO >0 -same, but for mids (middle frequencies)
|
||||
treb NO >0 -same, but for treble (high) frequencies
|
||||
bass_att NO >0 retrieves an attenuated reading on the bass, meaning that it is damped in time and doesn't change so rapidly.
|
||||
mid_att NO >0 -same, but for mids (middle frequencies)
|
||||
treb_att NO >0 -same, but for treble (high) frequencies
|
||||
|
||||
meshx NO 8-128 tells you the user's mesh size in the X direction. always an integer value.
|
||||
meshy NO 6-96 tells you the user's mesh size in the Y direction. always an integer value.
|
||||
|
||||
q1 yes any }
|
||||
q2 yes any }
|
||||
q3 yes any }
|
||||
q4 yes any } Used to carry information between the per-frame code
|
||||
q5 yes any } and the per-pixel code; see below.
|
||||
q6 yes any }
|
||||
q7 yes any }
|
||||
q8 yes any }
|
||||
|
||||
|
||||
The main reason for distinction between per-frame and per-pixel equations
|
||||
is simple: SPEED. If you have a per-pixel equation that doesn't make use
|
||||
of the x, y, rad, or ang variables, then there's no reason for it to be
|
||||
executed per-pixel; it could be executed once per frame, and the result
|
||||
would be the same. So, here's a maxim to write on the wall:
|
||||
|
||||
"If a per-pixel equation doesn't use at least one of the variables
|
||||
{ x, y, rad, ang }, then it should be actually be a per-frame
|
||||
equation."
|
||||
|
||||
You might be wondering how on earth all these formulas could be computed
|
||||
for every pixel on the screen, every frame, and still yield a high frame
|
||||
rate. Well, that's the magic of the hamster. And the fact that it really
|
||||
does the processing only at certain points on the screen, then interpolates
|
||||
the results across the space between the points. In the config panel,
|
||||
the "mesh size" option defines how many points (in X and Y) there are at
|
||||
which the per-pixel equations are actually computed. When you crank this
|
||||
option up, you start eating up CPU cycles rather quickly.
|
||||
|
||||
|
||||
|
||||
<A NAME="3c">
|
||||
<B>c. PRESET INITIALIZATION CODE AND q1-q8</B>
|
||||
-----------------------
|
||||
In MilkDrop 1.03 and later, you can write code that is executed only
|
||||
once, at the start of a preset. This code allows you to set the initial
|
||||
value of your own (user-defined) variables (such as 'my_variable'), as well
|
||||
as the q1..q8 variables. Any variable that is accessible in the per-frame
|
||||
equations is also accessible here, <EM>for reading</EM>; however, most of them will not
|
||||
be affected if you change them here, because they are overwritten by the base
|
||||
variable values of the preset at the start of each frame! (i.e. the values
|
||||
of the variables are reset to the values from the menus at the beginning of
|
||||
each frame.) In effect, most of these variables are treated as 'read-only'
|
||||
in the initialization code. If you do read (access) their values, you will
|
||||
get the base values - the ones baked into the preset (via the menu system).
|
||||
|
||||
The variables that are <EM>writable</EM> include only q1..q8, and
|
||||
<EM>any custom variables that you want to create & initialize for later use.</EM>
|
||||
|
||||
If you write to the values of q1..q8, these will become the new 'base values'
|
||||
to which q1..q8 are initialized at the start of each frame, for the per-frame
|
||||
code. So when you access (read) q1-q8 in the per-frame code, you'll get the
|
||||
values that were set at the end of the preset init code. You can then
|
||||
modify them (or not) in the per-frame code, and they will then be readable by
|
||||
the per-pixel code; but they will not persist to the next frame; they will be
|
||||
reset again, at the start of the next frame, to the values they had at the
|
||||
end of the preset init code. <B>See the <A HREF="q_and_t_vars.gif">q_and_t_vars.gif</A> image for a diagram
|
||||
of the flow of the values of the q1-q8 varibles.</B>
|
||||
|
||||
In the per-pixel code, the q1-q8 values start (for the first pixel in any frame)
|
||||
as the values they had at the end of the per-frame code. If you modify q1-q8
|
||||
in the per-pixel code, those modified values will carry over from pixel to
|
||||
pixel. Next frame, they will be reset to whatever value they had at the end
|
||||
of the [next frame's execution of the] per-frame code. (It's all in the diagram.)
|
||||
|
||||
If you declare & assign values to your own new variables here, however, these
|
||||
values are 'sticky' like q1-q8; they can be modified by the per-frame code,
|
||||
and they will retain their (modified) values from frame to frame.
|
||||
|
||||
One final note: when you edit the preset init code and apply it (by hitting
|
||||
CTRL+ENTER), the init code will re-execute immediately. However, when you
|
||||
edit the regular per-frame/per-pixel code and hit CTRL+ENTER, the preset init
|
||||
code will NOT be re-executed; the results of the last execution will persist.
|
||||
If you change per-frame/per-pixel code and want to re-execute the initialization
|
||||
code (i.e. to randomize it or reset the preset), you'll have to save it and re-
|
||||
load it.
|
||||
|
||||
|
||||
|
||||
<A NAME="3d">
|
||||
<B>d. CUSTOM SHAPES AND WAVES</B>
|
||||
----------------------
|
||||
As of MilkDrop 1.04, two new features are available: custom shapes, and custom
|
||||
waves. A preset can have up to 4 of each.
|
||||
|
||||
With custom shapes, you can draw an n-sided shape (with 3-100 sides) anywhere
|
||||
on the screen, at any angle and size, in any color, and at any opacity. You
|
||||
even have the option to map the previous frame's image onto the shape, which
|
||||
makes for some incredible possibilities (such as realtime hardware fractals -
|
||||
see the 'Geiss - Feedback' preset). You can also write per-frame code to
|
||||
control all of these things about the shape(s). This way, they can react to
|
||||
the audio or change over time - whatever you can imagine.
|
||||
|
||||
With custom waves, you can draw the waveform (or the frequency spectrum)
|
||||
wherever, whenever, and however you want; a great addition since MilkDrop
|
||||
1.03, where only the built-in waveforms were possible. With custom waves
|
||||
you can also write per-frame code to control the waves, and per-point code
|
||||
to place every point (or line segment) on the wave exactly where you want,
|
||||
and in exactly the color you want, and so on.
|
||||
|
||||
Remember those q1-q8 variables that were committed at the end of the preset
|
||||
initialization code, then reset (to those values) at the beginning of each
|
||||
frame, and then (potentially) modified in the preset per-frame code? Those
|
||||
(potentially modified) values of q1-q8 - as they were at the end of the
|
||||
preset's per-frame code, each frame - are piped into the custom wave & custom
|
||||
shape per-frame code. So if you read 'q3' in the custom wave per-frame
|
||||
code, what you're really reading is the value of 'q3' as it was left at the
|
||||
end of this frame's per-frame code. Again, see the <A HREF="q_and_t_vars.gif">q_and_t_vars.gif</A> image
|
||||
for a diagram of the flow of the values of the q1-q8 varibles.
|
||||
|
||||
For custom waves, you can modify q1-q8 and that value will get passed on
|
||||
to the per-point code. If you then modify q1-q8 in the per-point code,
|
||||
the modified values will pass on to the next point, much like the per-pixel
|
||||
code for the preset.
|
||||
|
||||
There are, however, 8 additional variables available for custom waves
|
||||
and shapes: <B>t1-t8</B>. These are very similar to q1-q8, but they exist only
|
||||
for custom waves & shapes. Recall that q1-q8 exist so that you can carry
|
||||
custom data (values) from the preset init code and per-frame code, to the
|
||||
preset's per-pixel code (which uses a different pool of variables).
|
||||
Likewise, t1-t8 exist so that you can pass custom values from the custom
|
||||
wave/shape init code, on to the custom wave/shape per-frame code, and
|
||||
then (in the case of custom waves) on to the per-point code. q1-q8 are
|
||||
also used to bridge another gap: to carry values from the preset init/per-
|
||||
frame code, to the custom wave/shape code. Again, see the diagram; it's
|
||||
probably easier to understand than all of this explanation.
|
||||
|
||||
|
||||
CUSTOM SHAPE PER-FRAME VARIABLES
|
||||
----------------------
|
||||
NAME WRITABLE? RANGE DESCRIPTION
|
||||
---- --------- ----- -----------
|
||||
sides yes 3-100 the default number of sides that make up the polygonal shape
|
||||
thick yes 0/1 if ON, the border will be overdrawn 4X to make it thicker, bolder, and more visible
|
||||
additive yes 0/1 if ON, the shape will add color to sature the image toward white; otherwise, it will replace what's there.
|
||||
x yes 0..1 default x position of the shape (0..1; 0=left side, 1=right side)
|
||||
y yes 0..1 default y position of the shape (0..1; 0=bottom, 1=top of screen)
|
||||
rad yes 0+ default radius of the shape (0+)
|
||||
ang yes 0..6.28 default rotation angle of the shape (0...2*pi)
|
||||
textured yes 0/1 if ON, the shape will be textured with the image from the previous frame
|
||||
tex_zoom yes >0 the portion of the previous frame's image to use with the shape
|
||||
tex_ang yes 0..6.28 the angle at which to rotate the previous frame's image before applying it to the shape
|
||||
r yes 0..1 default amount of red color toward the center of the shape (0..1)
|
||||
g yes 0..1 default amount of green color toward the center of the shape (0..1)
|
||||
b yes 0..1 default amount of blue color toward the center of the shape (0..1)
|
||||
a yes 0..1 default opacity of the center of the shape; 0=transparent, 1=opaque
|
||||
r2 yes 0..1 default amount of red color toward the outer edge of the shape (0..1)
|
||||
g2 yes 0..1 default amount of green color toward the outer edge of the shape (0..1)
|
||||
b2 yes 0..1 default amount of blue color toward the outer edge of the shape (0..1)
|
||||
a2 yes 0..1 default opacity of the outer edge of the shape; 0=transparent, 1=opaque
|
||||
border_r yes 0..1 default amount of red color in the shape's border (0..1)
|
||||
border_g yes 0..1 default amount of green color in the shape's border (0..1)
|
||||
border_b yes 0..1 default amount of blue color in the shape's border (0..1)
|
||||
border_a yes 0..1 default opacity of the shape's border; 0=transparent, 1=opaque
|
||||
|
||||
time NO >0 retrieves the current time, in seconds, since MilkDrop started running
|
||||
fps NO >0 retrieves the current framerate, in frames per second.
|
||||
frame NO retrieves the number of frames of animation elapsed since the program started
|
||||
progress NO 0..1 progress through the current preset; if preset was just loaded, this is closer to 0; if preset is about to end, this is closer to 1.
|
||||
-note that if Scroll Lock is on, 'progress' will freeze!
|
||||
|
||||
bass NO >0 retrieves the current amount of bass. 1 is normal; below ~0.7 is quiet; above ~1.3 is loud bass
|
||||
mid NO >0 -same, but for mids (middle frequencies)
|
||||
treb NO >0 -same, but for treble (high) frequencies
|
||||
bass_att NO >0 retrieves an attenuated reading on the bass, meaning that it is damped in time and doesn't change so rapidly.
|
||||
mid_att NO >0 -same, but for mids (middle frequencies)
|
||||
treb_att NO >0 -same, but for treble (high) frequencies
|
||||
|
||||
q1 yes any }
|
||||
q2 yes any }
|
||||
q3 yes any } Used to carry information
|
||||
q4 yes any } from the preset per-frame code
|
||||
q5 yes any } to the custom shape/wave per-frame code.
|
||||
q6 yes any } see <A HREF="q_and_t_vars.gif">q_and_t_vars.gif</A>
|
||||
q7 yes any }
|
||||
q8 yes any }
|
||||
|
||||
t1 yes any }
|
||||
t2 yes any }
|
||||
t3 yes any } Used to carry information
|
||||
t4 yes any } from the custom shape init code
|
||||
t5 yes any } to the custom shape per-frame code.
|
||||
t6 yes any } see <A HREF="q_and_t_vars.gif">q_and_t_vars.gif</A>
|
||||
t7 yes any }
|
||||
t8 yes any }
|
||||
|
||||
|
||||
CUSTOM WAVE PER-FRAME VARIABLES
|
||||
---------------------
|
||||
NAME WRITABLE? RANGE DESCRIPTION
|
||||
---- --------- ----- -----------
|
||||
r yes 0..1 base amount of red color in the wave (0..1)
|
||||
g yes 0..1 base amount of green color in the wave (0..1)
|
||||
b yes 0..1 base amount of blue color in the wave (0..1)
|
||||
a yes 0..1 base opacity of the waveform; 0=transparent, 1=opaque
|
||||
|
||||
time NO >0 retrieves the current time, in seconds, since MilkDrop started running
|
||||
fps NO >0 retrieves the current framerate, in frames per second.
|
||||
frame NO retrieves the number of frames of animation elapsed since the program started
|
||||
progress NO 0..1 progress through the current preset; if preset was just loaded, this is closer to 0; if preset is about to end, this is closer to 1.
|
||||
-note that if Scroll Lock is on, 'progress' will freeze!
|
||||
|
||||
bass NO >0 retrieves the current amount of bass. 1 is normal; below ~0.7 is quiet; above ~1.3 is loud bass
|
||||
mid NO >0 -same, but for mids (middle frequencies)
|
||||
treb NO >0 -same, but for treble (high) frequencies
|
||||
bass_att NO >0 retrieves an attenuated reading on the bass, meaning that it is damped in time and doesn't change so rapidly.
|
||||
mid_att NO >0 -same, but for mids (middle frequencies)
|
||||
treb_att NO >0 -same, but for treble (high) frequencies
|
||||
|
||||
q1 yes any }
|
||||
q2 yes any }
|
||||
q3 yes any } Used to carry information
|
||||
q4 yes any } from the preset per-frame code
|
||||
q5 yes any } to the custom shape/wave per-frame code.
|
||||
q6 yes any } see <A HREF="q_and_t_vars.gif">q_and_t_vars.gif</A>
|
||||
q7 yes any }
|
||||
q8 yes any }
|
||||
|
||||
t1 yes any }
|
||||
t2 yes any }
|
||||
t3 yes any } Used to carry information
|
||||
t4 yes any } from the custom wave init code,
|
||||
t5 yes any } to the custom wave per-frame code,
|
||||
t6 yes any } and on to the custom wave per-point code.
|
||||
t7 yes any } see <A HREF="q_and_t_vars.gif">q_and_t_vars.gif</A>
|
||||
t8 yes any }
|
||||
|
||||
|
||||
CUSTOM WAVE PER-POINT VARIABLES
|
||||
---------------------
|
||||
NAME WRITABLE? RANGE DESCRIPTION
|
||||
---- --------- ----- -----------
|
||||
x yes 0..1 the x position of this point that makes up the wave (0=left, 1=right)
|
||||
y yes 0..1 the y position of this point that makes up the wave (0=bottom, 1=top)
|
||||
sample no 0..1 how far along we are, through the samples that make up the waveform: 0=first sample, 0.5 = half-way through; 1=last sample.
|
||||
value1 no any the value of the Left audio channel sample at this point in the waveform (or freq. spectrum).
|
||||
value2 no any the value of the Right audio channel sample at this point in the waveform (or freq. spectrum).
|
||||
r yes 0..1 amount of red color in this point of the wave (0..1)
|
||||
g yes 0..1 amount of green color in this point of the wave (0..1)
|
||||
b yes 0..1 amount of blue color in this point of the wave (0..1)
|
||||
a yes 0..1 opacity of this point of the waveform; 0=transparent, 1=opaque
|
||||
|
||||
time NO >0 retrieves the current time, in seconds, since MilkDrop started running
|
||||
fps NO >0 retrieves the current framerate, in frames per second.
|
||||
frame NO retrieves the number of frames of animation elapsed since the program started
|
||||
progress NO 0..1 progress through the current preset; if preset was just loaded, this is closer to 0; if preset is about to end, this is closer to 1.
|
||||
-note that if Scroll Lock is on, 'progress' will freeze!
|
||||
|
||||
bass NO >0 retrieves the current amount of bass. 1 is normal; below ~0.7 is quiet; above ~1.3 is loud bass
|
||||
mid NO >0 -same, but for mids (middle frequencies)
|
||||
treb NO >0 -same, but for treble (high) frequencies
|
||||
bass_att NO >0 retrieves an attenuated reading on the bass, meaning that it is damped in time and doesn't change so rapidly.
|
||||
mid_att NO >0 -same, but for mids (middle frequencies)
|
||||
treb_att NO >0 -same, but for treble (high) frequencies
|
||||
|
||||
q1 yes any }
|
||||
q2 yes any }
|
||||
q3 yes any } Used to carry information
|
||||
q4 yes any } from the preset per-frame code
|
||||
q5 yes any } to the custom wave per-frame code
|
||||
q6 yes any } and on to the custom wave per-point code.
|
||||
q7 yes any } see <A HREF="q_and_t_vars.gif">q_and_t_vars.gif</A>
|
||||
q8 yes any }
|
||||
|
||||
t1 yes any }
|
||||
t2 yes any }
|
||||
t3 yes any } Used to carry information
|
||||
t4 yes any } from the custom wave init code,
|
||||
t5 yes any } to the custom wave per-frame code,
|
||||
t6 yes any } and on to the custom wave per-point code.
|
||||
t7 yes any } see <A HREF="q_and_t_vars.gif">q_and_t_vars.gif</A>
|
||||
t8 yes any }
|
||||
|
||||
|
||||
|
||||
<A NAME="3e">
|
||||
<B>e. QUALITY ASSURANCE</B>
|
||||
----------------------
|
||||
In order to make sure the presets you create work well on other systems,
|
||||
keep the following in mind:
|
||||
|
||||
1. Design your presets using the default mesh size (32x24) option
|
||||
from the config panel, or at least check, before you distribute them,
|
||||
to make sure they look correct at the default mesh size. If your
|
||||
mesh is too coarse (small), then a viewer with the default mesh size
|
||||
might see unexpected "bonus" effects that you might not have intended,
|
||||
and might mess up your preset. If your mesh is too fine, then a
|
||||
viewer with the default might not see all the detail you intended,
|
||||
and it might look bad.
|
||||
|
||||
2. Keep your presets fast. There's nothing to spoil the mood like
|
||||
a preset popping up that chokes at 10 fps. Since division is 11
|
||||
times slower than multiplication (or addition/subtraction), if you
|
||||
divide a bunch of values by one other value, pre-divide that value
|
||||
("inv = 1/myval;") and then multiply those other values by that
|
||||
inverse. Also, never put computations in the per-pixel code that
|
||||
are the same for every pixel; move these into the per-frame code,
|
||||
and carry the results to the per-pixel code using the q1-q8 variables.
|
||||
Remember that maxim: "If a per-pixel equation doesn't use at least
|
||||
one of the variables { x, y, rad, ang }, then it should be actually
|
||||
be a per-frame equation."
|
||||
|
||||
2. Try to design your presets in a 32-bit video mode, so that its
|
||||
brightness levels are standard. The thing to really watch out
|
||||
for is designing your presets in 16-bit color when the "fix pink/
|
||||
white color saturation artifact" checkbox is checked. This
|
||||
checkbox keeps the image extra dark to avoid color saturation,
|
||||
which is only necessary on some cards, in 16-bit color. If this
|
||||
is the case for you, and you write a preset, then when you run
|
||||
it on another machine, it might appear insanely bright.
|
||||
|
||||
3. Don't underestimate the power of the 'dx' and 'dy' parameters. Some
|
||||
of the best presets a based on using these. If you strip everything
|
||||
out of a preset so that there's no motion at all, then you can use the
|
||||
dx and dy parameters to have precise manual control over the motion.
|
||||
Basically, all the other effects (zoom, warp, rot, etc.) are just
|
||||
complicated abstractions; they could all be simulated by using only
|
||||
{ x, y, rad, ang } and { dx, dy }.
|
||||
|
||||
4. If you use the 'progress' variable in a preset, make sure you
|
||||
try the preset out with several values for 'Time Between Auto
|
||||
Preset Changes'. The biggest thing to avoid is using something
|
||||
like sin(progress), since the rate at which 'progress' increases
|
||||
can vary drastically from system to system, dependong on the user's
|
||||
setting for 'Time Between Auto Preset Changes'.
|
||||
|
||||
|
||||
|
||||
<A NAME="3f">
|
||||
<B>f. DEBUGGING</B>
|
||||
-----------------------
|
||||
One feature that preset authors should definitely be aware of is the
|
||||
variable monitoring feature, which lets you monitor (watch) the value
|
||||
of any per-frame variable you like. First, hit the 'N' key to show
|
||||
the monitor value, which will probably display zero. Then all you
|
||||
have to do is add a line like this to the per-frame equations:
|
||||
|
||||
monitor = x;
|
||||
|
||||
where 'x' is the variable or expression you want to monitor. Once you
|
||||
hit CTRL+ENTER to accept the changes, you should see the value of the
|
||||
per-frame variable or expression in the upper-right corner of the
|
||||
screen!
|
||||
|
||||
Once again, note that it only works for *per-frame* equations, and NOT
|
||||
for per-pixel equations.
|
||||
|
||||
|
||||
|
||||
<A NAME="3g">
|
||||
<B>g. FUNCTION REFERENCE</B>
|
||||
-----------------------
|
||||
Following is a list of the functions supported by the expression evaluator.
|
||||
The list was blatently ripped from the help box of Justin Frankels' AVS
|
||||
plug-in, since MilkDrop uses the expression evaluator that he wrote.
|
||||
|
||||
Format your expressions using a semicolon (;) to delimit between statements.
|
||||
Use parenthesis ['(' and ')'] to denote precedence if you are unsure.
|
||||
The following operators are available:
|
||||
= : assign
|
||||
+,-,/,* : plus, minus, divide, multiply
|
||||
| : convert to integer, and do bitwise or
|
||||
& : convert to integer, and do bitwise and
|
||||
% : convert to integer, and get remainder
|
||||
The following functions are available:
|
||||
int(var) : returns the integer value of 'var' (rounds toward zero)
|
||||
abs(var) : returns the absolute value of var
|
||||
sin(var) : returns the sine of the angle var (expressed in radians)
|
||||
cos(var) : returns the cosine of the angle var
|
||||
tan(var) : returns the tangent of the angle var
|
||||
asin(var) : returns the arcsine of var
|
||||
acos(var) : returns the arccosine of var
|
||||
atan(var) : returns the arctangent of var
|
||||
sqr(var) : returns the square of var
|
||||
sqrt(var) : returns the square root of var
|
||||
pow(var,var2) : returns var to the power of var2
|
||||
log(var) : returns the log base e of var
|
||||
log10(var) : returns the log base 10 of var
|
||||
sign(var) : returns the sign of var or 0
|
||||
min(var,var2) : returns the smalest value
|
||||
max(var,var2) : returns the greatest value
|
||||
sigmoid(var,var2) : returns sigmoid function value of x=var (var2=constraint)
|
||||
rand(var) : returns a random integer modulo 'var'; e.g. rand(4) will return 0, 1, 2, or 3.
|
||||
bor(var,var2) : boolean or, returns 1 if var or var2 is != 0
|
||||
bnot(var) : boolean not, returns 1 if var == 0 or 0 if var != 0
|
||||
if(cond,vartrue,varfalse) : if condition is nonzero, returns valtrue, otherwise returns valfalse
|
||||
equal(var,var2) : returns 1 if var = var2, else 0
|
||||
above(var,var2) : returns 1 if var > var2, else 0
|
||||
below(var,var2) : returns 1 if var < var2, else 0
|
||||
|
||||
|
||||
|
||||
|
||||
<A HREF="#milkdrop_preset_authoring_top">return to top</A>
|
||||
<A HREF="milkdrop.html">return to milkdrop.html</A>
|
||||
</PRE>
|
||||
</HTML>
|
||||
Reference in New Issue
Block a user