milkdrop_preset_authoring.html 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. <HTML>
  2. <A NAME="milkdrop_preset_authoring_top">
  3. <PRE>
  4. <B>MILKDROP preset authoring guide</B>
  5. <A HREF="milkdrop.html">return to milkdrop.html</A>
  6. * * *
  7. Note that there is another, quite comprehensive, Preset Authoring Guide
  8. available on the web at <A HREF="http://www.milkdrop.co.uk/">http://www.milkdrop.co.uk/</A>, which is continually
  9. updated and expanded through the hard work of a few dedicated preset
  10. authors. Whereas this guide (the one you are currently viewing) gives the bare
  11. technical specifications for writing your own presets, the guide at milkdrop.co.uk
  12. 'starts at the beginning' and walks you through all of the mathematics and subtleties
  13. of 'rolling your own', explaining things in great detail. The guide at milkdrop.co.uk
  14. is very highly recommended to anyone who wishes to learn more about creating their
  15. own presets.
  16. * * *
  17. <B>Section Listing</B>
  18. -----------------------
  19. 1. <A HREF="#1">about presets</A>
  20. 2. <A HREF="#2">preset authoring - basic</A>
  21. 3. <A HREF="#3">preset authoring - advanced</A>
  22. a. <A HREF="#3a">per-frame equations</A>
  23. b. <A HREF="#3b">per-pixel equations</A>
  24. c. <A HREF="#3c">preset initialization code and q1-q8</A>
  25. d. <A HREF="#3d">custom shapes & waves</A>
  26. e. <A HREF="#3e">quality assurance</A>
  27. f. <A HREF="#3f">debugging</A>
  28. g. <A HREF="#3g">function reference</A>
  29. <A NAME="1">
  30. <B>1. About Presets</B>
  31. -----------------------
  32. A 'preset' is a collection of parameters that tell MilkDrop how to
  33. draw the wave, how to warp the image around, and so on. MilkDrop
  34. ships with around ~100 built-in presets, each one having a distinct
  35. look and feel to it.
  36. Using MilkDrop's built-in "preset-editing menu", you can edit presets
  37. on the fly, from within the program. You can make slight adjustments
  38. to existing presets, then save over them; or you can change lots of
  39. things, so the preset doesn't look anything like the original, and
  40. then save it under a new name. You can even write insane new
  41. mathematical equations, of your own imagination, into your preset
  42. files and come up with things that MilkDrop has never done before!
  43. Each preset is saved as a file with the ".milk" extension, so you can
  44. easily send them to your friends or post them on the web. You can also
  45. go to <A HREF="http://www.nullsoft.com/free/milkdrop">http://www.nullsoft.com/free/milkdrop</A> and then jump to the
  46. "preset sharing forum" to see what other people have come up with,
  47. or post your own cool, new presets.
  48. <A NAME="2">
  49. <B>2. Preset Authoring - Basic</B>
  50. -----------------------
  51. You can edit the properties of the current preset by hitting 'M',
  52. which brings up the "preset-editing menu". From this menu you
  53. can use the up and down arrow keys to select an item. Press
  54. the RIGHT arrow key to move forward through the menu and select
  55. the item (note: you can also hit SPACE or RETURN to do this);
  56. ***press the LEFT arrow key to go back to the previous menu.***
  57. Pressing 'M' while the menu is already showing will hide the menu;
  58. pressing ESCAPE will do the same thing. Press 'M' again to bring
  59. the menu back.
  60. Once you've reached an item on the menu whose value can be edited,
  61. use the UP and DOWN arrow keys to increase or decrease its value,
  62. respectively. Changes will register immediately. Use PAGE UP and
  63. PAGE DOWN to increase the value more quickly. Hold down SHIFT
  64. and use the UP/DOWN arrow keys to change the value very slowly.
  65. Hit RETURN To keep the new value, or ESC to abort the change.
  66. If the item you're editing is a text string, you can use the
  67. arrow keys to move around. The Insert key can be used to toggle
  68. between insert and overtype modes. You can hold shift and use
  69. the arrow keys (home, end, left, right) to make a selection,
  70. which will be identified by brackets []. You can then use CTRL-C
  71. or CTRL-X to copy or cut text. CTRL-P pastes. When finished
  72. editing, hit RETURN To keep the new string, or ESC to abort the
  73. change.
  74. You'll want to get into the habit of using SCROLL LOCK whenever
  75. you're making changes to a preset that you intend to save;
  76. otherwise, the preset is sure to keep randomly changing on you.
  77. You might ask me, "why don't you just automatically lock the
  78. preset while the menu is up?" I will answer you, "because in
  79. the instant between exiting the menu and going to save the preset,
  80. the preset might then switch, and you'd lose your changes." Then
  81. you might ask me, "then why don't you just leave it locked
  82. whenever the user makes a change from the menu?" and I will say
  83. to you, "because I hate it when programs do things like that. You
  84. have an idea in your brain about the state of the Scroll Lock key,
  85. because you're the one setting that state. I want your mind to
  86. always be up-to-date." And you might then ask me: "how large is
  87. large?" And I will tell you: "thirty."
  88. There are also some hotkeys that will allow you to change certain
  89. common parameters to the current preset. These are listed below.
  90. MOTION
  91. i/I - zoom in/out
  92. [ / ] - push motion to the left/right (dx)
  93. { / } - push motion up/down (dy)
  94. < / > - rotate left/right (rot)
  95. o/O - shrink/grow the amplitude of the warp effect
  96. WAVEFORM
  97. W - cycle through waveforms
  98. j/J - scale waveform down/up
  99. e/E - make the waveform more transparent/more solid
  100. BRIGHTNESS
  101. d/D - decrease, increase decay (fades image to black over time)
  102. g/G - decrease, increase gamma (brightness)
  103. VIDEO ECHO effect
  104. q/Q - scale 2nd graphics layer down/up
  105. a/A - decrease/increase alpha of 2nd graphics layer
  106. F - flip 2nd graphics layer (cycles through 4 fixed orientations)
  107. <A NAME="3">
  108. <B>3. Preset Authoring - Advanced</B>
  109. -----------------------
  110. This section describes how to use the 'per-frame' and 'per-pixel'
  111. equations to develop unique new presets.
  112. <A NAME="3a">
  113. <B>a. PER-FRAME EQUATIONS</B>
  114. ----------------------
  115. When you hit 'm' to show the preset-editing menu, several items
  116. show up. If you explore the sub-menus, you'll see that
  117. all of the properties that make up the preset you're currently
  118. viewing are there. The values you can specify here (such as
  119. zoom amount, rotation amount, wave color, etc.) are all static
  120. values, meaning that they don't change in time. For example,
  121. take the 'zoom amount' option under the 'motion' submenu.
  122. If this value is 1.0, there is no zoom. If the value is 1.01,
  123. the image zooms in 1% every frame. If the value is 1.10, the
  124. image zooms in 10% every frame. If the value is 0.9, the image
  125. zooms out 10% every frame; and so on.
  126. However, presets get far more interesting if you can take these
  127. parameters (such as the zoom amount) and animate them (make them
  128. change over time). For example, if you could take the 'zoom
  129. amount' parameter and make it oscillate (vary) between 0.9 and
  130. 1.1 over time, the image would cyclically zoom in and out, in
  131. time.
  132. You can do this - by writing 'per-frame' and 'per-pixel'
  133. equations. Let's start with 'per-frame' equations. These are
  134. executed once per frame. So, if you were to type the following
  135. equation in:
  136. zoom = zoom + 0.1*sin(time);
  137. ...then the zoom amount would oscillate between 0.9 and 1.1
  138. over time. (Recall from your geometry classes that sin()
  139. returns a value between -1 and 1.) The equation says: "take
  140. the static value of 'zoom', then replace it with that value,
  141. plus some variation." This particular equation would oscillate
  142. (cycle) every 6.28 seconds, since the sin() function's
  143. period is 6.28 (PI*2) seconds. If you wanted it to make it
  144. cycle every 2 seconds, you could use:
  145. zoom = zoom + 0.1*sin(time*3.14);
  146. Now, let's say you wanted to make the color of the waveform
  147. (sound wave) that gets plotted on the screen vary through time.
  148. The color is defined by three values, one for each of the main
  149. color components (red, green, and blue), each in the range 0 to 1
  150. (0 is dark, 1 is full intensity). You could use something like this:
  151. wave_r = wave_r + 0.5*sin(time*1.13);
  152. wave_g = wave_g + 0.5*sin(time*1.23);
  153. wave_b = wave_b + 0.5*sin(time*1.33);
  154. It's nice to stagger the frequencies (1.13, 1.23, and 1.33) of
  155. the sine functions for the red, green, and blue color components
  156. of the wave so that they cycle at different rates, to avoid them
  157. always being all the same (which would create a greyscale wave).
  158. Here is a full list of the variables available for writing per-frame
  159. equations:
  160. NAME WRITABLE? RANGE DESCRIPTION
  161. ---- --------- ----- -----------
  162. zoom yes >0 controls inward/outward motion. 0.9=zoom out 10% per frame, 1.0=no zoom, 1.1=zoom in 10%
  163. zoomexp yes >0 controls the curvature of the zoom; 1=normal
  164. rot yes controls the amount of rotation. 0=none, 0.1=slightly right, -0.1=slightly clockwise, 0.1=CCW
  165. warp yes >0 controls the magnitude of the warping; 0=none, 1=normal, 2=major warping...
  166. cx yes 0..1 controls where the center of rotation and stretching is, horizontally. 0=left, 0.5=center, 1=right
  167. cy yes 0..1 controls where the center of rotation and stretching is, vertically. 0=top, 0.5=center, 1=bottom
  168. dx yes controls amount of constant horizontal motion; -0.01 = move left 1% per frame, 0=none, 0.01 = move right 1%
  169. dy yes controls amount of constant vertical motion; -0.01 = move up 1% per frame, 0=none, 0.01 = move down 1%
  170. sx yes >0 controls amount of constant horizontal stretching; 0.99=shrink 1%, 1=normal, 1.01=stretch 1%
  171. sy yes >0 controls amount of constant vertical stretching; 0.99=shrink 1%, 1=normal, 1.01=stretch 1%
  172. wave_mode yes 0,1,2,3,4,5,6,7 controls which of the 8 types of waveform is drawn
  173. wave_x yes 0..1 position of the waveform: 0 = far left edge of screen, 0.5 = center, 1 = far right
  174. wave_y yes 0..1 position of the waveform: 0 = very bottom of screen, 0.5 = center, 1 = top
  175. wave_r yes 0..1 amount of red color in the wave (0..1),
  176. wave_g yes 0..1 amount of green color in the wave (0..1)
  177. wave_b yes 0..1 amount of blue color in the wave (0..1)
  178. wave_a yes 0..1 opacity of the wave (0..1) [0=transparent, 1=opaque]
  179. 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.)
  180. wave_usedots yes 0/1 if 1, the waveform is drawn as dots (instead of lines)
  181. wave_thick yes 0/1 if 1, the waveform's lines (or dots) are drawn with double thickness
  182. wave_additive yes 0/1 if 1, the wave is drawn additively, saturating the image at white
  183. wave_brighten yes 0/1 if 1, all 3 r/g/b colors will be scaled up until at least one reaches 1.0
  184. ob_size yes 0..0.5 thickness of the outer border drawn at the edges of the screen every frame
  185. ob_r yes 0..1 amount of red color in the outer border
  186. ob_g yes 0..1 amount of green color in the outer border
  187. ob_b yes 0..1 amount of blue color in the outer border
  188. ob_a yes 0..1 opacity of the outer border (0=transparent, 1=opaque)
  189. ib_size yes 0..0.5 thickness of the inner border drawn at the edges of the screen every frame
  190. ib_r yes 0..1 amount of red color in the inner border
  191. ib_g yes 0..1 amount of green color in the inner border
  192. ib_b yes 0..1 amount of blue color in the inner border
  193. ib_a yes 0..1 opacity of the inner border (0=transparent, 1=opaque)
  194. mv_r yes 0..1 amount of red color in the motion vectors
  195. mv_g yes 0..1 amount of green color in the motion vectors
  196. mv_b yes 0..1 amount of blue color in the motion vectors
  197. mv_a yes 0..1 opacity of the motion vectors (0=transparent, 1=opaque)
  198. mv_x yes 0..64 the number of motion vectors in the X direction
  199. mv_y yes 0..48 the number of motion vectors in the Y direction
  200. mv_l yes 0..5 the length of the motion vectors (0=no trail, 1=normal, 2=double...)
  201. mv_dx yes -1..1 horizontal placement offset of the motion vectors
  202. mv_dy yes -1..1 vertical placement offset of the motion vectors
  203. decay yes 0..1 controls the eventual fade to black; 1=no fade, 0.9=strong fade, 0.98=recommended
  204. gamma yes >0 controls display brightness; 1=normal, 2=double, 3=triple, etc.
  205. echo_zoom yes >0 controls the size of the second graphics layer
  206. echo_alpha yes >0 controls the opacity of the second graphics layer; 0=transparent (off), 0.5=half-mix, 1=opaque
  207. 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
  208. darken_center yes 0/1 if 1, help keeps the image from getting too bright by continually dimming the center point
  209. wrap yes 0/1 sets whether or not screen elements can drift off of one side and onto the other
  210. invert yes 0/1 inverts the colors in the image
  211. brighten yes 0/1 brightens the darker parts of the image (nonlinear; square root filter)
  212. darken yes 0/1 darkens the brighter parts of the image (nonlinear; squaring filter)
  213. solarize yes 0/1 emphasizes mid-range colors
  214. monitor yes any set this value for debugging your preset code; if you hit the 'N' key,
  215. the value of 'monitor' will be posted in the upper-right corner of milkdrop.
  216. for example, setting "monitor = q3;" would let you keep an eye on q3's value.
  217. time NO >0 retrieves the current time, in seconds, since MilkDrop started running
  218. fps NO >0 retrieves the current framerate, in frames per second.
  219. frame NO retrieves the number of frames of animation elapsed since the program started
  220. 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.
  221. -note that if Scroll Lock is on, 'progress' will freeze!
  222. bass NO >0 retrieves the current amount of bass. 1 is normal; below ~0.7 is quiet; above ~1.3 is loud bass
  223. mid NO >0 -same, but for mids (middle frequencies)
  224. treb NO >0 -same, but for treble (high) frequencies
  225. bass_att NO >0 retrieves an attenuated reading on the bass, meaning that it is damped in time and doesn't change so rapidly.
  226. mid_att NO >0 -same, but for mids (middle frequencies)
  227. treb_att NO >0 -same, but for treble (high) frequencies
  228. meshx NO 8-128 tells you the user's mesh size in the X direction. always an integer value.
  229. meshy NO 6-96 tells you the user's mesh size in the Y direction. always an integer value.
  230. q1 yes any }
  231. q2 yes any }
  232. q3 yes any }
  233. q4 yes any } Used to carry information between the per-frame code
  234. q5 yes any } and the per-pixel code; see below.
  235. q6 yes any }
  236. q7 yes any }
  237. q8 yes any }
  238. Some of the variables are read-only, meaning that you shouldn't change
  239. their values them through the equations. You can; it won't stop you;
  240. but the results are unpredictable.
  241. You can also make up to 30 of your own variables. For example:
  242. my_volume = (bass + mid + treb)/3;
  243. zoom = zoom + 0.1*(my_volume - 1);
  244. This would make the zoom amount increase when the music is loud,
  245. and decrease when the music is quiet.
  246. HOWEVER, custom variables do not carry over from per-frame equations
  247. to per-pixel equations; if you set a custom variable's value in the
  248. per-frame equations, and try to read it in the per-pixel equations,
  249. you will not get the correct value. Instead, you have to "bridge the
  250. gap" using 8 special variables: q1 through q8. This is usually only
  251. used when you want to precompute some custom values in the per-frame
  252. equations for later use in the per-pixel equations. For a good
  253. example of this, see the 'dynamic swirls' preset. See below for
  254. more information on q1-q8.
  255. <A NAME="3b">
  256. <B>b. PER-PIXEL EQUATIONS</B>
  257. -----------------------
  258. So far we've discussed only how to change parameters based on
  259. time. What if you wanted to also vary a parameter, such as the
  260. zoom amount, in different ways, for different locations on the
  261. screen? For example, normally, the result of the 'zoom' parameter
  262. is to just do a flat zoom. This doesn't look very realistic,
  263. because you don't see any perspective in the zoom. It would be
  264. better if we could give a unique zoom amount to each pixel on
  265. the screen; we could make the pixels far away from the center
  266. zoom more, and this would give it more perspective. In order
  267. to do this, we use "per-pixel" equations, instead of per-frame
  268. equations.
  269. The code for this per-pixel equation is simple:
  270. zoom = zoom + rad*0.1;
  271. Where 'rad' is the radius of the pixel if it were cast into
  272. polar coordinates; from another perspective, 'rad' is the distance
  273. of the pixel from the center of the screen. 'rad is zero at the
  274. center, and 1 at the corners. So if we run the above code,
  275. the image will be zoomed into 10% more at the edges of the screen
  276. than at the center.
  277. The per-pixel equations are really just like the per-frame equations,
  278. except for a variables. The following variables are available
  279. exclusively to per-pixel equations (and not to per-frame equations):
  280. NAME WRITABLE? RANGE DESCRIPTION
  281. ---- --------- ----- -----------
  282. 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.
  283. 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.
  284. 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.
  285. (The middle of the edges will be 0.707 (half of the square root of 2).
  286. ang NO 0..6.28 retrieves the angle of the current pixel, with respect to the center of the screen.
  287. 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).
  288. 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).
  289. (note: this is simply the arctangent of y over x, precomputed for you.)
  290. zoom yes >0 controls inward/outward motion. 0.9=zoom out 10% per frame, 1.0=no zoom, 1.1=zoom in 10%
  291. zoomexp yes >0 controls the curvature of the zoom; 1=normal
  292. rot yes controls the amount of rotation. 0=none, 0.1=slightly right, -0.1=slightly clockwise, 0.1=CCW
  293. warp yes >0 controls the magnitude of the warping; 0=none, 1=normal, 2=major warping...
  294. cx yes 0..1 controls where the center of rotation and stretching is, horizontally. 0=left, 0.5=center, 1=right
  295. cy yes 0..1 controls where the center of rotation and stretching is, vertically. 0=top, 0.5=center, 1=bottom
  296. dx yes controls amount of constant horizontal motion; -0.01 = move left 1% per frame, 0=none, 0.01 = move right 1%
  297. dy yes controls amount of constant vertical motion; -0.01 = move up 1% per frame, 0=none, 0.01 = move down 1%
  298. sx yes >0 controls amount of constant horizontal stretching; 0.99=shrink 1%, 1=normal, 1.01=stretch 1%
  299. sy yes >0 controls amount of constant vertical stretching; 0.99=shrink 1%, 1=normal, 1.01=stretch 1%
  300. time NO >0 retrieves the current time, in seconds, since MilkDrop started running
  301. fps NO >0 retrieves the current framerate, in frames per second.
  302. frame NO retrieves the number of frames of animation elapsed since the program started
  303. 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.
  304. -note that if Scroll Lock is on, 'progress' will freeze!
  305. bass NO >0 retrieves the current amount of bass. 1 is normal; below ~0.7 is quiet; above ~1.3 is loud bass
  306. mid NO >0 -same, but for mids (middle frequencies)
  307. treb NO >0 -same, but for treble (high) frequencies
  308. bass_att NO >0 retrieves an attenuated reading on the bass, meaning that it is damped in time and doesn't change so rapidly.
  309. mid_att NO >0 -same, but for mids (middle frequencies)
  310. treb_att NO >0 -same, but for treble (high) frequencies
  311. meshx NO 8-128 tells you the user's mesh size in the X direction. always an integer value.
  312. meshy NO 6-96 tells you the user's mesh size in the Y direction. always an integer value.
  313. q1 yes any }
  314. q2 yes any }
  315. q3 yes any }
  316. q4 yes any } Used to carry information between the per-frame code
  317. q5 yes any } and the per-pixel code; see below.
  318. q6 yes any }
  319. q7 yes any }
  320. q8 yes any }
  321. The main reason for distinction between per-frame and per-pixel equations
  322. is simple: SPEED. If you have a per-pixel equation that doesn't make use
  323. of the x, y, rad, or ang variables, then there's no reason for it to be
  324. executed per-pixel; it could be executed once per frame, and the result
  325. would be the same. So, here's a maxim to write on the wall:
  326. "If a per-pixel equation doesn't use at least one of the variables
  327. { x, y, rad, ang }, then it should be actually be a per-frame
  328. equation."
  329. You might be wondering how on earth all these formulas could be computed
  330. for every pixel on the screen, every frame, and still yield a high frame
  331. rate. Well, that's the magic of the hamster. And the fact that it really
  332. does the processing only at certain points on the screen, then interpolates
  333. the results across the space between the points. In the config panel,
  334. the "mesh size" option defines how many points (in X and Y) there are at
  335. which the per-pixel equations are actually computed. When you crank this
  336. option up, you start eating up CPU cycles rather quickly.
  337. <A NAME="3c">
  338. <B>c. PRESET INITIALIZATION CODE AND q1-q8</B>
  339. -----------------------
  340. In MilkDrop 1.03 and later, you can write code that is executed only
  341. once, at the start of a preset. This code allows you to set the initial
  342. value of your own (user-defined) variables (such as 'my_variable'), as well
  343. as the q1..q8 variables. Any variable that is accessible in the per-frame
  344. equations is also accessible here, <EM>for reading</EM>; however, most of them will not
  345. be affected if you change them here, because they are overwritten by the base
  346. variable values of the preset at the start of each frame! (i.e. the values
  347. of the variables are reset to the values from the menus at the beginning of
  348. each frame.) In effect, most of these variables are treated as 'read-only'
  349. in the initialization code. If you do read (access) their values, you will
  350. get the base values - the ones baked into the preset (via the menu system).
  351. The variables that are <EM>writable</EM> include only q1..q8, and
  352. <EM>any custom variables that you want to create & initialize for later use.</EM>
  353. If you write to the values of q1..q8, these will become the new 'base values'
  354. to which q1..q8 are initialized at the start of each frame, for the per-frame
  355. code. So when you access (read) q1-q8 in the per-frame code, you'll get the
  356. values that were set at the end of the preset init code. You can then
  357. modify them (or not) in the per-frame code, and they will then be readable by
  358. the per-pixel code; but they will not persist to the next frame; they will be
  359. reset again, at the start of the next frame, to the values they had at the
  360. 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
  361. of the flow of the values of the q1-q8 varibles.</B>
  362. In the per-pixel code, the q1-q8 values start (for the first pixel in any frame)
  363. as the values they had at the end of the per-frame code. If you modify q1-q8
  364. in the per-pixel code, those modified values will carry over from pixel to
  365. pixel. Next frame, they will be reset to whatever value they had at the end
  366. of the [next frame's execution of the] per-frame code. (It's all in the diagram.)
  367. If you declare & assign values to your own new variables here, however, these
  368. values are 'sticky' like q1-q8; they can be modified by the per-frame code,
  369. and they will retain their (modified) values from frame to frame.
  370. One final note: when you edit the preset init code and apply it (by hitting
  371. CTRL+ENTER), the init code will re-execute immediately. However, when you
  372. edit the regular per-frame/per-pixel code and hit CTRL+ENTER, the preset init
  373. code will NOT be re-executed; the results of the last execution will persist.
  374. If you change per-frame/per-pixel code and want to re-execute the initialization
  375. code (i.e. to randomize it or reset the preset), you'll have to save it and re-
  376. load it.
  377. <A NAME="3d">
  378. <B>d. CUSTOM SHAPES AND WAVES</B>
  379. ----------------------
  380. As of MilkDrop 1.04, two new features are available: custom shapes, and custom
  381. waves. A preset can have up to 4 of each.
  382. With custom shapes, you can draw an n-sided shape (with 3-100 sides) anywhere
  383. on the screen, at any angle and size, in any color, and at any opacity. You
  384. even have the option to map the previous frame's image onto the shape, which
  385. makes for some incredible possibilities (such as realtime hardware fractals -
  386. see the 'Geiss - Feedback' preset). You can also write per-frame code to
  387. control all of these things about the shape(s). This way, they can react to
  388. the audio or change over time - whatever you can imagine.
  389. With custom waves, you can draw the waveform (or the frequency spectrum)
  390. wherever, whenever, and however you want; a great addition since MilkDrop
  391. 1.03, where only the built-in waveforms were possible. With custom waves
  392. you can also write per-frame code to control the waves, and per-point code
  393. to place every point (or line segment) on the wave exactly where you want,
  394. and in exactly the color you want, and so on.
  395. Remember those q1-q8 variables that were committed at the end of the preset
  396. initialization code, then reset (to those values) at the beginning of each
  397. frame, and then (potentially) modified in the preset per-frame code? Those
  398. (potentially modified) values of q1-q8 - as they were at the end of the
  399. preset's per-frame code, each frame - are piped into the custom wave & custom
  400. shape per-frame code. So if you read 'q3' in the custom wave per-frame
  401. code, what you're really reading is the value of 'q3' as it was left at the
  402. 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
  403. for a diagram of the flow of the values of the q1-q8 varibles.
  404. For custom waves, you can modify q1-q8 and that value will get passed on
  405. to the per-point code. If you then modify q1-q8 in the per-point code,
  406. the modified values will pass on to the next point, much like the per-pixel
  407. code for the preset.
  408. There are, however, 8 additional variables available for custom waves
  409. and shapes: <B>t1-t8</B>. These are very similar to q1-q8, but they exist only
  410. for custom waves & shapes. Recall that q1-q8 exist so that you can carry
  411. custom data (values) from the preset init code and per-frame code, to the
  412. preset's per-pixel code (which uses a different pool of variables).
  413. Likewise, t1-t8 exist so that you can pass custom values from the custom
  414. wave/shape init code, on to the custom wave/shape per-frame code, and
  415. then (in the case of custom waves) on to the per-point code. q1-q8 are
  416. also used to bridge another gap: to carry values from the preset init/per-
  417. frame code, to the custom wave/shape code. Again, see the diagram; it's
  418. probably easier to understand than all of this explanation.
  419. CUSTOM SHAPE PER-FRAME VARIABLES
  420. ----------------------
  421. NAME WRITABLE? RANGE DESCRIPTION
  422. ---- --------- ----- -----------
  423. sides yes 3-100 the default number of sides that make up the polygonal shape
  424. thick yes 0/1 if ON, the border will be overdrawn 4X to make it thicker, bolder, and more visible
  425. additive yes 0/1 if ON, the shape will add color to sature the image toward white; otherwise, it will replace what's there.
  426. x yes 0..1 default x position of the shape (0..1; 0=left side, 1=right side)
  427. y yes 0..1 default y position of the shape (0..1; 0=bottom, 1=top of screen)
  428. rad yes 0+ default radius of the shape (0+)
  429. ang yes 0..6.28 default rotation angle of the shape (0...2*pi)
  430. textured yes 0/1 if ON, the shape will be textured with the image from the previous frame
  431. tex_zoom yes >0 the portion of the previous frame's image to use with the shape
  432. tex_ang yes 0..6.28 the angle at which to rotate the previous frame's image before applying it to the shape
  433. r yes 0..1 default amount of red color toward the center of the shape (0..1)
  434. g yes 0..1 default amount of green color toward the center of the shape (0..1)
  435. b yes 0..1 default amount of blue color toward the center of the shape (0..1)
  436. a yes 0..1 default opacity of the center of the shape; 0=transparent, 1=opaque
  437. r2 yes 0..1 default amount of red color toward the outer edge of the shape (0..1)
  438. g2 yes 0..1 default amount of green color toward the outer edge of the shape (0..1)
  439. b2 yes 0..1 default amount of blue color toward the outer edge of the shape (0..1)
  440. a2 yes 0..1 default opacity of the outer edge of the shape; 0=transparent, 1=opaque
  441. border_r yes 0..1 default amount of red color in the shape's border (0..1)
  442. border_g yes 0..1 default amount of green color in the shape's border (0..1)
  443. border_b yes 0..1 default amount of blue color in the shape's border (0..1)
  444. border_a yes 0..1 default opacity of the shape's border; 0=transparent, 1=opaque
  445. time NO >0 retrieves the current time, in seconds, since MilkDrop started running
  446. fps NO >0 retrieves the current framerate, in frames per second.
  447. frame NO retrieves the number of frames of animation elapsed since the program started
  448. 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.
  449. -note that if Scroll Lock is on, 'progress' will freeze!
  450. bass NO >0 retrieves the current amount of bass. 1 is normal; below ~0.7 is quiet; above ~1.3 is loud bass
  451. mid NO >0 -same, but for mids (middle frequencies)
  452. treb NO >0 -same, but for treble (high) frequencies
  453. bass_att NO >0 retrieves an attenuated reading on the bass, meaning that it is damped in time and doesn't change so rapidly.
  454. mid_att NO >0 -same, but for mids (middle frequencies)
  455. treb_att NO >0 -same, but for treble (high) frequencies
  456. q1 yes any }
  457. q2 yes any }
  458. q3 yes any } Used to carry information
  459. q4 yes any } from the preset per-frame code
  460. q5 yes any } to the custom shape/wave per-frame code.
  461. q6 yes any } see <A HREF="q_and_t_vars.gif">q_and_t_vars.gif</A>
  462. q7 yes any }
  463. q8 yes any }
  464. t1 yes any }
  465. t2 yes any }
  466. t3 yes any } Used to carry information
  467. t4 yes any } from the custom shape init code
  468. t5 yes any } to the custom shape per-frame code.
  469. t6 yes any } see <A HREF="q_and_t_vars.gif">q_and_t_vars.gif</A>
  470. t7 yes any }
  471. t8 yes any }
  472. CUSTOM WAVE PER-FRAME VARIABLES
  473. ---------------------
  474. NAME WRITABLE? RANGE DESCRIPTION
  475. ---- --------- ----- -----------
  476. r yes 0..1 base amount of red color in the wave (0..1)
  477. g yes 0..1 base amount of green color in the wave (0..1)
  478. b yes 0..1 base amount of blue color in the wave (0..1)
  479. a yes 0..1 base opacity of the waveform; 0=transparent, 1=opaque
  480. time NO >0 retrieves the current time, in seconds, since MilkDrop started running
  481. fps NO >0 retrieves the current framerate, in frames per second.
  482. frame NO retrieves the number of frames of animation elapsed since the program started
  483. 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.
  484. -note that if Scroll Lock is on, 'progress' will freeze!
  485. bass NO >0 retrieves the current amount of bass. 1 is normal; below ~0.7 is quiet; above ~1.3 is loud bass
  486. mid NO >0 -same, but for mids (middle frequencies)
  487. treb NO >0 -same, but for treble (high) frequencies
  488. bass_att NO >0 retrieves an attenuated reading on the bass, meaning that it is damped in time and doesn't change so rapidly.
  489. mid_att NO >0 -same, but for mids (middle frequencies)
  490. treb_att NO >0 -same, but for treble (high) frequencies
  491. q1 yes any }
  492. q2 yes any }
  493. q3 yes any } Used to carry information
  494. q4 yes any } from the preset per-frame code
  495. q5 yes any } to the custom shape/wave per-frame code.
  496. q6 yes any } see <A HREF="q_and_t_vars.gif">q_and_t_vars.gif</A>
  497. q7 yes any }
  498. q8 yes any }
  499. t1 yes any }
  500. t2 yes any }
  501. t3 yes any } Used to carry information
  502. t4 yes any } from the custom wave init code,
  503. t5 yes any } to the custom wave per-frame code,
  504. t6 yes any } and on to the custom wave per-point code.
  505. t7 yes any } see <A HREF="q_and_t_vars.gif">q_and_t_vars.gif</A>
  506. t8 yes any }
  507. CUSTOM WAVE PER-POINT VARIABLES
  508. ---------------------
  509. NAME WRITABLE? RANGE DESCRIPTION
  510. ---- --------- ----- -----------
  511. x yes 0..1 the x position of this point that makes up the wave (0=left, 1=right)
  512. y yes 0..1 the y position of this point that makes up the wave (0=bottom, 1=top)
  513. 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.
  514. value1 no any the value of the Left audio channel sample at this point in the waveform (or freq. spectrum).
  515. value2 no any the value of the Right audio channel sample at this point in the waveform (or freq. spectrum).
  516. r yes 0..1 amount of red color in this point of the wave (0..1)
  517. g yes 0..1 amount of green color in this point of the wave (0..1)
  518. b yes 0..1 amount of blue color in this point of the wave (0..1)
  519. a yes 0..1 opacity of this point of the waveform; 0=transparent, 1=opaque
  520. time NO >0 retrieves the current time, in seconds, since MilkDrop started running
  521. fps NO >0 retrieves the current framerate, in frames per second.
  522. frame NO retrieves the number of frames of animation elapsed since the program started
  523. 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.
  524. -note that if Scroll Lock is on, 'progress' will freeze!
  525. bass NO >0 retrieves the current amount of bass. 1 is normal; below ~0.7 is quiet; above ~1.3 is loud bass
  526. mid NO >0 -same, but for mids (middle frequencies)
  527. treb NO >0 -same, but for treble (high) frequencies
  528. bass_att NO >0 retrieves an attenuated reading on the bass, meaning that it is damped in time and doesn't change so rapidly.
  529. mid_att NO >0 -same, but for mids (middle frequencies)
  530. treb_att NO >0 -same, but for treble (high) frequencies
  531. q1 yes any }
  532. q2 yes any }
  533. q3 yes any } Used to carry information
  534. q4 yes any } from the preset per-frame code
  535. q5 yes any } to the custom wave per-frame code
  536. q6 yes any } and on to the custom wave per-point code.
  537. q7 yes any } see <A HREF="q_and_t_vars.gif">q_and_t_vars.gif</A>
  538. q8 yes any }
  539. t1 yes any }
  540. t2 yes any }
  541. t3 yes any } Used to carry information
  542. t4 yes any } from the custom wave init code,
  543. t5 yes any } to the custom wave per-frame code,
  544. t6 yes any } and on to the custom wave per-point code.
  545. t7 yes any } see <A HREF="q_and_t_vars.gif">q_and_t_vars.gif</A>
  546. t8 yes any }
  547. <A NAME="3e">
  548. <B>e. QUALITY ASSURANCE</B>
  549. ----------------------
  550. In order to make sure the presets you create work well on other systems,
  551. keep the following in mind:
  552. 1. Design your presets using the default mesh size (32x24) option
  553. from the config panel, or at least check, before you distribute them,
  554. to make sure they look correct at the default mesh size. If your
  555. mesh is too coarse (small), then a viewer with the default mesh size
  556. might see unexpected "bonus" effects that you might not have intended,
  557. and might mess up your preset. If your mesh is too fine, then a
  558. viewer with the default might not see all the detail you intended,
  559. and it might look bad.
  560. 2. Keep your presets fast. There's nothing to spoil the mood like
  561. a preset popping up that chokes at 10 fps. Since division is 11
  562. times slower than multiplication (or addition/subtraction), if you
  563. divide a bunch of values by one other value, pre-divide that value
  564. ("inv = 1/myval;") and then multiply those other values by that
  565. inverse. Also, never put computations in the per-pixel code that
  566. are the same for every pixel; move these into the per-frame code,
  567. and carry the results to the per-pixel code using the q1-q8 variables.
  568. Remember that maxim: "If a per-pixel equation doesn't use at least
  569. one of the variables { x, y, rad, ang }, then it should be actually
  570. be a per-frame equation."
  571. 2. Try to design your presets in a 32-bit video mode, so that its
  572. brightness levels are standard. The thing to really watch out
  573. for is designing your presets in 16-bit color when the "fix pink/
  574. white color saturation artifact" checkbox is checked. This
  575. checkbox keeps the image extra dark to avoid color saturation,
  576. which is only necessary on some cards, in 16-bit color. If this
  577. is the case for you, and you write a preset, then when you run
  578. it on another machine, it might appear insanely bright.
  579. 3. Don't underestimate the power of the 'dx' and 'dy' parameters. Some
  580. of the best presets a based on using these. If you strip everything
  581. out of a preset so that there's no motion at all, then you can use the
  582. dx and dy parameters to have precise manual control over the motion.
  583. Basically, all the other effects (zoom, warp, rot, etc.) are just
  584. complicated abstractions; they could all be simulated by using only
  585. { x, y, rad, ang } and { dx, dy }.
  586. 4. If you use the 'progress' variable in a preset, make sure you
  587. try the preset out with several values for 'Time Between Auto
  588. Preset Changes'. The biggest thing to avoid is using something
  589. like sin(progress), since the rate at which 'progress' increases
  590. can vary drastically from system to system, dependong on the user's
  591. setting for 'Time Between Auto Preset Changes'.
  592. <A NAME="3f">
  593. <B>f. DEBUGGING</B>
  594. -----------------------
  595. One feature that preset authors should definitely be aware of is the
  596. variable monitoring feature, which lets you monitor (watch) the value
  597. of any per-frame variable you like. First, hit the 'N' key to show
  598. the monitor value, which will probably display zero. Then all you
  599. have to do is add a line like this to the per-frame equations:
  600. monitor = x;
  601. where 'x' is the variable or expression you want to monitor. Once you
  602. hit CTRL+ENTER to accept the changes, you should see the value of the
  603. per-frame variable or expression in the upper-right corner of the
  604. screen!
  605. Once again, note that it only works for *per-frame* equations, and NOT
  606. for per-pixel equations.
  607. <A NAME="3g">
  608. <B>g. FUNCTION REFERENCE</B>
  609. -----------------------
  610. Following is a list of the functions supported by the expression evaluator.
  611. The list was blatently ripped from the help box of Justin Frankels' AVS
  612. plug-in, since MilkDrop uses the expression evaluator that he wrote.
  613. Format your expressions using a semicolon (;) to delimit between statements.
  614. Use parenthesis ['(' and ')'] to denote precedence if you are unsure.
  615. The following operators are available:
  616. = : assign
  617. +,-,/,* : plus, minus, divide, multiply
  618. | : convert to integer, and do bitwise or
  619. & : convert to integer, and do bitwise and
  620. % : convert to integer, and get remainder
  621. The following functions are available:
  622. int(var) : returns the integer value of 'var' (rounds toward zero)
  623. abs(var) : returns the absolute value of var
  624. sin(var) : returns the sine of the angle var (expressed in radians)
  625. cos(var) : returns the cosine of the angle var
  626. tan(var) : returns the tangent of the angle var
  627. asin(var) : returns the arcsine of var
  628. acos(var) : returns the arccosine of var
  629. atan(var) : returns the arctangent of var
  630. sqr(var) : returns the square of var
  631. sqrt(var) : returns the square root of var
  632. pow(var,var2) : returns var to the power of var2
  633. log(var) : returns the log base e of var
  634. log10(var) : returns the log base 10 of var
  635. sign(var) : returns the sign of var or 0
  636. min(var,var2) : returns the smalest value
  637. max(var,var2) : returns the greatest value
  638. sigmoid(var,var2) : returns sigmoid function value of x=var (var2=constraint)
  639. rand(var) : returns a random integer modulo 'var'; e.g. rand(4) will return 0, 1, 2, or 3.
  640. bor(var,var2) : boolean or, returns 1 if var or var2 is != 0
  641. bnot(var) : boolean not, returns 1 if var == 0 or 0 if var != 0
  642. if(cond,vartrue,varfalse) : if condition is nonzero, returns valtrue, otherwise returns valfalse
  643. equal(var,var2) : returns 1 if var = var2, else 0
  644. above(var,var2) : returns 1 if var > var2, else 0
  645. below(var,var2) : returns 1 if var < var2, else 0
  646. <A HREF="#milkdrop_preset_authoring_top">return to top</A>
  647. <A HREF="milkdrop.html">return to milkdrop.html</A>
  648. </PRE>
  649. </HTML>