123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772 |
- <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>
|