milkdrop_preset_authoring.html 110 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990
  1. <HTML>
  2. <HEAD>
  3. <TITLE>MilkDrop Preset Authoring Guide</TITLE>
  4. </HEAD>
  5. <BODY>
  6. <A NAME="milkdrop_preset_authoring_top">
  7. <PRE>
  8. <B>MILKDROP preset authoring guide</B>
  9. <A HREF="milkdrop.html">return to milkdrop.html</A>
  10. * * *
  11. Note that there is another, quite comprehensive, Preset Authoring Guide
  12. available on the web at <A HREF="http://www.milkdrop.co.uk/">http://www.milkdrop.co.uk/</A>, which is continually
  13. updated and expanded through the hard work of a few dedicated preset
  14. authors. Whereas this guide (the one you are currently viewing) gives the bare
  15. technical specifications for writing your own presets, the guide at milkdrop.co.uk
  16. 'starts at the beginning' and walks you through all of the mathematics and subtleties
  17. of 'rolling your own', explaining things in great detail. The guide at milkdrop.co.uk
  18. is very highly recommended to anyone who wishes to learn more about creating their
  19. own presets.
  20. * * *
  21. <B>Section Listing</B>
  22. -----------------------
  23. 1. <A HREF="#1">about presets</A>
  24. 2. <A HREF="#2">preset authoring - basic</A>
  25. 3. <A HREF="#3">preset authoring - advanced</A>
  26. a. <A HREF="#3a">per-frame equations</A>
  27. b. <A HREF="#3b">per-vertex equations</A>
  28. c. <A HREF="#3c">variable pools, declaring your own variables, persistence of values</A>
  29. d. <A HREF="#3d">preset init code; carrying values between variable pools, using q1-q32</A>
  30. e. <A HREF="#3e">custom shapes & waves</A>
  31. f. <A HREF="#3f">pixel shaders</A>
  32. <A HREF="#3f1">conceptual overview</A>
  33. <A HREF="#3f2">the WARP shader</A>
  34. <A HREF="#3f3">the COMPOSITE shader</A>
  35. <A HREF="#3f4">pixel shader reference</A>
  36. <A HREF="#3f5">intrinsic instructions</A>
  37. <A HREF="#3f6">per-vertex shader inputs</A>
  38. <A HREF="#3f7">per-frame shader inputs</A>
  39. <A HREF="#3f8">texture sampling</A>
  40. <A HREF="#3f9">milkdrop's built-in textures - main, blur, and noise</A>
  41. <A HREF="#3f9b">blur1, blur2, blur3</A>
  42. <A HREF="#3f9c">noise textures</A>
  43. <A HREF="#3f9d">reading textures from disk</A>
  44. <A HREF="#3f9e">random texture selection</A>
  45. <A HREF="#3f10">misc. cool shader tricks</A>
  46. <A HREF="#3f11">quality assurance for shaders</A>
  47. g. <A HREF="#3r">quality assurance</A>
  48. h. <A HREF="#3s">debugging</A>
  49. i. <A HREF="#3t">function reference</A> (for expressions, not shaders)
  50. <A NAME="1">
  51. <B>1. About Presets</B>
  52. -----------------------
  53. When you watch MilkDrop, you are watching a series of Presets. Each
  54. one has its own look and feel, draws the sound waves in a particular
  55. way, and has certain motions to it. After some time, you will see
  56. a short blend transition, and then you will be watching a new preset.
  57. A single 'preset' is a collection of parameters that tell MilkDrop how
  58. to draw the wave, how to warp the image around, and so on. MilkDrop
  59. ships with over 100 built-in presets, each one having a distinct
  60. look and feel to it.
  61. Using MilkDrop's built-in "preset-editing menu" (the M key), you can
  62. edit presets on the fly, on-screen, from within the program. You can
  63. make slight adjustments to existing presets, then save over them;
  64. or you can change lots of things, so the preset doesn't look anything
  65. like the original, and then save it under a new name. You can even
  66. write insane new mathematical equations, of your own imagination,
  67. into your preset files and come up with things that MilkDrop has never
  68. done before!
  69. Each preset is saved as a file with the ".milk" extension, so you can
  70. easily send them to your friends or post them on the web. You can also
  71. go to <A HREF="http://www.nullsoft.com/free/milkdrop">http://www.nullsoft.com/free/milkdrop</A> and then jump to the
  72. "preset sharing forum" to see what other people have come up with,
  73. or post your own cool, new presets. <A HREF="http://www.milkdrop.co.uk/">milkdrop.co.uk/</A> is another great
  74. place to download collections of presets made by others like yourself.
  75. <A NAME="2">
  76. <B>2. Preset Authoring - Basic</B>
  77. -----------------------
  78. You can edit the properties of the current preset by hitting 'M',
  79. which brings up the "preset-editing menu". From this menu you
  80. can use the up and down arrow keys to select an item. Press
  81. the RIGHT arrow key to move forward through the menu and select
  82. the item (note: you can also hit SPACE or RETURN to do this);
  83. ***press the LEFT arrow key to go back to the previous menu.***
  84. Pressing 'M' while the menu is already showing will hide the menu;
  85. pressing ESCAPE will do the same thing. Press 'M' again to bring
  86. the menu back.
  87. Once you've reached an item on the menu whose value can be edited,
  88. use the UP and DOWN arrow keys to increase or decrease its value,
  89. respectively. Changes will register immediately. Use PAGE UP and
  90. PAGE DOWN to increase the value more quickly. Hold down SHIFT
  91. and use the UP/DOWN arrow keys to change the value very slowly.
  92. Hit RETURN To keep the new value, or ESC to abort the change.
  93. If the item you're editing is a text string, you can use the
  94. arrow keys to move around. The Insert key can be used to toggle
  95. between insert and overtype modes. You can hold shift and use
  96. the arrow keys (home, end, left, right) to make a selection,
  97. which will be identified by brackets []. You can then use CTRL-C
  98. or CTRL-X to copy or cut text. CTRL-P pastes. When finished
  99. editing, hit RETURN To keep the new string, or ESC to abort the
  100. change.
  101. You'll want to get into the habit of using SCROLL LOCK whenever
  102. you're making changes to a preset that you intend to save;
  103. otherwise, MilkDrop is sure to move you along to a new (random)
  104. preset, over time. When the menus are showing, the preset is
  105. automatically temporarily locked, but BE CAREFUL - if you're not
  106. also using SCROLL LOCK, then 0.1 seconds after you hide the menu
  107. to take a look at your new masterpiece, MilkDrop might load a
  108. random new preset on you, and you'd lose your changes! And you
  109. might then ask me: "how large is large?" And I will tell you:
  110. "thirty."
  111. There are also some hotkeys that will allow you to change certain
  112. common parameters to the current preset. These are listed below.
  113. MOTION
  114. i/I - zoom in/out
  115. [ / ] - push motion to the left/right (dx)
  116. { / } - push motion up/down (dy)
  117. < / > - rotate left/right (rot)
  118. o/O - shrink/grow the amplitude of the warp effect
  119. WAVEFORM
  120. W - cycle through waveforms
  121. j/J - scale waveform down/up
  122. e/E - make the waveform more transparent/more solid
  123. BRIGHTNESS **
  124. g/G - decrease, increase gamma (brightness) **
  125. VIDEO ECHO effect **
  126. q/Q - scale 2nd graphics layer down/up **
  127. F - flip 2nd graphics layer (cycles through 4 fixed orientations) **
  128. ** these keys only have an effect if you are running a
  129. MilkDrop 1-era preset. In MilkDrop 2-era presets,
  130. these values are embedded in the shader, so you need
  131. to go into the composite shader and tweak the code.
  132. <A NAME="3">
  133. <B>3. Preset Authoring - Advanced</B>
  134. -----------------------
  135. This section describes how to use the 'per-frame' and 'per-vertex'
  136. equations to develop unique new presets.
  137. <A NAME="3a">
  138. <B>a. PER-FRAME EQUATIONS</B>
  139. ----------------------
  140. When you hit 'm' to show the preset-editing menu, several items
  141. show up. If you explore the sub-menus, you'll see that
  142. all of the properties that make up the preset you're currently
  143. viewing are there. The values you can specify here (such as
  144. zoom amount, rotation amount, wave color, etc.) are all static
  145. values, meaning that they don't change in time. For example,
  146. take the 'zoom amount' option under the 'motion' submenu.
  147. If this value is 1.0, there is no zoom. If the value is 1.01,
  148. the image zooms in 1% every frame. If the value is 1.10, the
  149. image zooms in 10% every frame. If the value is 0.9, the image
  150. zooms out 10% every frame; and so on.
  151. However, presets get far more interesting if you can take these
  152. parameters (such as the zoom amount) and animate them (make them
  153. change over time). For example, if you could take the 'zoom
  154. amount' parameter and make it oscillate (vary) between 0.9 and
  155. 1.1 over time, the image would cyclically zoom in and out, in
  156. time.
  157. You can do this - by writing 'per-frame' and 'per-vertex'
  158. equations. Let's start with 'per-frame' equations. These are
  159. executed once per frame. So, if you were to type the following
  160. equation in:
  161. zoom = zoom + 0.1*sin(time);
  162. ...then the zoom amount would oscillate between 0.9 and 1.1
  163. over time. (Recall from your geometry classes that sin()
  164. returns a value between -1 and 1.) The equation says: "take
  165. the static value of 'zoom', then replace it with that value,
  166. plus some variation." This particular equation would oscillate
  167. (cycle) every 6.28 seconds, since the sin() function's
  168. period is 6.28 (PI*2) seconds. If you wanted it to make it
  169. cycle every 2 seconds, you could use:
  170. zoom = zoom + 0.1*sin(time*3.14);
  171. Now, let's say you wanted to make the color of the waveform
  172. (sound wave) that gets plotted on the screen vary through time.
  173. The color is defined by three values, one for each of the main
  174. color components (red, green, and blue), each in the range 0 to 1
  175. (0 is dark, 1 is full intensity). You could use something like this:
  176. wave_r = wave_r + 0.5*sin(time*1.13);
  177. wave_g = wave_g + 0.5*sin(time*1.23);
  178. wave_b = wave_b + 0.5*sin(time*1.33);
  179. It's nice to stagger the frequencies (1.13, 1.23, and 1.33) of
  180. the sine functions for the red, green, and blue color components
  181. of the wave so that they cycle at different rates, to avoid them
  182. always being all the same (which would create a greyscale wave).
  183. Here is a full list of the variables available for writing per-frame
  184. equations:
  185. NAME WRITABLE? RANGE DESCRIPTION
  186. ---- --------- ----- -----------
  187. zoom yes >0 controls inward/outward motion. 0.9=zoom out 10% per frame, 1.0=no zoom, 1.1=zoom in 10%
  188. zoomexp yes >0 controls the curvature of the zoom; 1=normal
  189. rot yes controls the amount of rotation. 0=none, 0.1=slightly right, -0.1=slightly clockwise, 0.1=CCW
  190. warp yes >0 controls the magnitude of the warping; 0=none, 1=normal, 2=major warping...
  191. cx yes 0..1 controls where the center of rotation and stretching is, horizontally. 0=left, 0.5=center, 1=right
  192. cy yes 0..1 controls where the center of rotation and stretching is, vertically. 0=top, 0.5=center, 1=bottom
  193. dx yes controls amount of constant horizontal motion; -0.01 = move left 1% per frame, 0=none, 0.01 = move right 1%
  194. dy yes controls amount of constant vertical motion; -0.01 = move up 1% per frame, 0=none, 0.01 = move down 1%
  195. sx yes >0 controls amount of constant horizontal stretching; 0.99=shrink 1%, 1=normal, 1.01=stretch 1%
  196. sy yes >0 controls amount of constant vertical stretching; 0.99=shrink 1%, 1=normal, 1.01=stretch 1%
  197. wave_mode yes 0,1,2,3,4,5,6,7 controls which of the 8 types of waveform is drawn
  198. wave_x yes 0..1 position of the waveform: 0 = far left edge of screen, 0.5 = center, 1 = far right
  199. wave_y yes 0..1 position of the waveform: 0 = very bottom of screen, 0.5 = center, 1 = top
  200. wave_r yes 0..1 amount of red color in the wave (0..1),
  201. wave_g yes 0..1 amount of green color in the wave (0..1)
  202. wave_b yes 0..1 amount of blue color in the wave (0..1)
  203. wave_a yes 0..1 opacity of the wave (0..1) [0=transparent, 1=opaque]
  204. 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.)
  205. wave_usedots yes 0/1 if 1, the waveform is drawn as dots (instead of lines)
  206. wave_thick yes 0/1 if 1, the waveform's lines (or dots) are drawn with double thickness
  207. wave_additive yes 0/1 if 1, the wave is drawn additively, saturating the image at white
  208. wave_brighten yes 0/1 if 1, all 3 r/g/b colors will be scaled up until at least one reaches 1.0
  209. ob_size yes 0..0.5 thickness of the outer border drawn at the edges of the screen every frame
  210. ob_r yes 0..1 amount of red color in the outer border
  211. ob_g yes 0..1 amount of green color in the outer border
  212. ob_b yes 0..1 amount of blue color in the outer border
  213. ob_a yes 0..1 opacity of the outer border (0=transparent, 1=opaque)
  214. ib_size yes 0..0.5 thickness of the inner border drawn at the edges of the screen every frame
  215. ib_r yes 0..1 amount of red color in the inner border
  216. ib_g yes 0..1 amount of green color in the inner border
  217. ib_b yes 0..1 amount of blue color in the inner border
  218. ib_a yes 0..1 opacity of the inner border (0=transparent, 1=opaque)
  219. mv_r yes 0..1 amount of red color in the motion vectors
  220. mv_g yes 0..1 amount of green color in the motion vectors
  221. mv_b yes 0..1 amount of blue color in the motion vectors
  222. mv_a yes 0..1 opacity of the motion vectors (0=transparent, 1=opaque)
  223. mv_x yes 0..64 the number of motion vectors in the X direction
  224. mv_y yes 0..48 the number of motion vectors in the Y direction
  225. mv_l yes 0..5 the length of the motion vectors (0=no trail, 1=normal, 2=double...)
  226. mv_dx yes -1..1 horizontal placement offset of the motion vectors
  227. mv_dy yes -1..1 vertical placement offset of the motion vectors
  228. decay yes 0..1 controls the eventual fade to black; 1=no fade, 0.9=strong fade, 0.98=recommended
  229. gamma yes >0 controls display brightness; 1=normal, 2=double, 3=triple, etc.
  230. echo_zoom yes >0 controls the size of the second graphics layer
  231. echo_alpha yes >0 controls the opacity of the second graphics layer; 0=transparent (off), 0.5=half-mix, 1=opaque
  232. 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
  233. darken_center yes 0/1 if 1, help keeps the image from getting too bright by continually dimming the center point
  234. wrap yes 0/1 sets whether or not screen elements can drift off of one side and onto the other
  235. invert yes 0/1 inverts the colors in the image
  236. brighten yes 0/1 brightens the darker parts of the image (nonlinear; square root filter)
  237. darken yes 0/1 darkens the brighter parts of the image (nonlinear; squaring filter)
  238. solarize yes 0/1 emphasizes mid-range colors
  239. monitor yes any set this value for debugging your preset code; if you hit the 'N' key,
  240. the value of 'monitor' will be posted in the upper-right corner of milkdrop.
  241. for example, setting "monitor = q3;" would let you keep an eye on q3's value.
  242. time NO >0 retrieves the current time, in seconds, since MilkDrop started running
  243. fps NO >0 retrieves the current framerate, in frames per second.
  244. frame NO retrieves the number of frames of animation elapsed since the program started
  245. 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.
  246. -note that if Scroll Lock is on, 'progress' will freeze!
  247. bass NO >0 retrieves the current amount of bass. 1 is normal; below ~0.7 is quiet; above ~1.3 is loud bass
  248. mid NO >0 -same, but for mids (middle frequencies)
  249. treb NO >0 -same, but for treble (high) frequencies
  250. bass_att NO >0 retrieves an attenuated reading on the bass, meaning that it is damped in time and doesn't change so rapidly.
  251. mid_att NO >0 -same, but for mids (middle frequencies)
  252. treb_att NO >0 -same, but for treble (high) frequencies
  253. meshx NO 8-128 tells you the user's mesh size in the X direction. always an integer value.
  254. meshy NO 6-96 tells you the user's mesh size in the Y direction. always an integer value.
  255. pixelsx NO 16-4096 width of the viz window, in pixels. If Canvas Stretch is on, this is the pre-stretched size. (same as "texsize.x" for shaders)
  256. pixelsy NO 16-4096 height of the viz window, in pixels. If Canvas Stretch is on, this is the pre-stretched size. (same as "texsize.y" for shaders)
  257. aspectx NO >0 multiply an x-coordinate by this to make the preset look the same at any aspect (window height:width) ratio.
  258. -value: if widescreen, 1; if window is tall, h/w.
  259. aspecty NO >0 multiply a y-coordinate by this to make the preset look the same at any aspect (window height:width) ratio.
  260. -value: if widescreen, w/h; if window is tall, 1.
  261. blur1_min yes 0..1 Normally these are set to 0 (min) and 1 (max).
  262. blur2_min yes 0..1 You can clamp the values in the blur texture to a tighter
  263. blur3_min yes 0..1 range, though.
  264. blur1_max yes 0..1 This will increase the precision in the blur textures,
  265. blur2_max yes 0..1 but you run the risk of clamping values to your min/max.
  266. blur3_max yes 0..1 If you use the GetBlur1() .. GetBlur3() functions to sample
  267. blur1_edge_darken yes 0..1 the blur texture, they will automatically "unpack" the
  268. values for you in the end!
  269. q1 yes any } Used to carry values along a chain
  270. q2 yes any } from the preset init code,
  271. q3 yes any } to the preset per-frame code, then on
  272. q4 yes any } to the preset per-vertex code;
  273. q5 yes any } or to the custom shape per-frame code,
  274. q6 yes any } or to the custom wave per-frame code,
  275. q7 yes any } then to the custom wave per-vertex code;
  276. ... } or to the [pixel] shader code.
  277. q31 yes any } <B><A HREF="q_vars.gif">Click here to see a diagram for the Q vars</A>.</B>
  278. q32 yes any }
  279. Some of the variables are read-only, meaning that you shouldn't change
  280. their values them through the equations. You can; it won't stop you;
  281. but the results are unpredictable.
  282. You can also make up to 30 of your own variables. For example:
  283. my_volume = (bass + mid + treb)/3;
  284. zoom = zoom + 0.1*(my_volume - 1);
  285. This would make the zoom amount increase when the music is loud,
  286. and decrease when the music is quiet.
  287. HOWEVER, custom variables do not carry over from per-frame equations
  288. to per-vertex equations; if you set a custom variable's value in the
  289. per-frame equations, and try to read it in the per-vertex equations,
  290. you will not get the correct value. Instead, you have to "bridge the
  291. gap" using 32 special variables: q1 through q32. This is usually only
  292. used when you want to precompute some custom values in the per-frame
  293. equations for later use in the per-vertex equations (or for use in
  294. the pixel shaders). For a good example of this, see the 'dynamic swirls'
  295. preset. See below for more information on q1-q32.
  296. <A NAME="3b">
  297. <B>b. PER-VERTEX EQUATIONS</B>
  298. -----------------------
  299. So far we've discussed only how to change parameters based on
  300. time. What if you wanted to also vary a parameter, such as the
  301. zoom amount, in different ways, for different locations on the
  302. screen? For example, normally, the result of the 'zoom' parameter
  303. is to just do a flat zoom. This doesn't look very realistic,
  304. because you don't see any perspective in the zoom. It would be
  305. better if we could give a unique zoom amount to each pixel on
  306. the screen; we could make the pixels far away from the center
  307. zoom more, and this would give it more perspective. In order
  308. to do this, we use "per-vertex" equations, instead of per-frame
  309. equations.
  310. The code for this per-vertex equation is simple:
  311. zoom = zoom + rad*0.1;
  312. Where 'rad' is the radius of the pixel if it were cast into
  313. polar coordinates; from another perspective, 'rad' is the distance
  314. of the pixel from the center of the screen. 'rad is zero at the
  315. center, and 1 at the corners. So if we run the above code,
  316. the image will be zoomed into 10% more at the edges of the screen
  317. than at the center.
  318. The per-vertex equations are really just like the per-frame equations,
  319. except for a variables. The following variables are available
  320. exclusively to per-vertex equations (and not to per-frame equations):
  321. NAME WRITEABLE? RANGE DESCRIPTION
  322. ---- ---------- ----- -----------
  323. 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.
  324. 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.
  325. 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.
  326. (The middle of the edges will be 0.707 (half of the square root of 2).
  327. ang NO 0..6.28 retrieves the angle of the current pixel, with respect to the center of the screen.
  328. 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).
  329. 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).
  330. (note: this is simply the arctangent of y over x, precomputed for you.)
  331. zoom yes >0 controls inward/outward motion. 0.9=zoom out 10% per frame, 1.0=no zoom, 1.1=zoom in 10%
  332. zoomexp yes >0 controls the curvature of the zoom; 1=normal
  333. rot yes controls the amount of rotation. 0=none, 0.1=slightly right, -0.1=slightly clockwise, 0.1=CCW
  334. warp yes >0 controls the magnitude of the warping; 0=none, 1=normal, 2=major warping...
  335. cx yes 0..1 controls where the center of rotation and stretching is, horizontally. 0=left, 0.5=center, 1=right
  336. cy yes 0..1 controls where the center of rotation and stretching is, vertically. 0=top, 0.5=center, 1=bottom
  337. dx yes controls amount of constant horizontal motion; -0.01 = move left 1% per frame, 0=none, 0.01 = move right 1%
  338. dy yes controls amount of constant vertical motion; -0.01 = move up 1% per frame, 0=none, 0.01 = move down 1%
  339. sx yes >0 controls amount of constant horizontal stretching; 0.99=shrink 1%, 1=normal, 1.01=stretch 1%
  340. sy yes >0 controls amount of constant vertical stretching; 0.99=shrink 1%, 1=normal, 1.01=stretch 1%
  341. time NO >0 retrieves the current time, in seconds, since MilkDrop started running
  342. fps NO >0 retrieves the current framerate, in frames per second.
  343. frame NO retrieves the number of frames of animation elapsed since the program started
  344. 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.
  345. -note that if Scroll Lock is on, 'progress' will freeze!
  346. bass NO >0 retrieves the current amount of bass. 1 is normal; below ~0.7 is quiet; above ~1.3 is loud bass
  347. mid NO >0 -same, but for mids (middle frequencies)
  348. treb NO >0 -same, but for treble (high) frequencies
  349. bass_att NO >0 retrieves an attenuated reading on the bass, meaning that it is damped in time and doesn't change so rapidly.
  350. mid_att NO >0 -same, but for mids (middle frequencies)
  351. treb_att NO >0 -same, but for treble (high) frequencies
  352. meshx NO 8-192 tells you the user's mesh size in the X direction. always an integer value.
  353. meshy NO 6-144 tells you the user's mesh size in the Y direction. always an integer value.
  354. pixelsx NO 16-4096 width of the viz window, in pixels. If Canvas Stretch is on, this is the pre-stretched size. (same as "texsize.x" for shaders)
  355. pixelsy NO 16-4096 height of the viz window, in pixels. If Canvas Stretch is on, this is the pre-stretched size. (same as "texsize.y" for shaders)
  356. aspectx NO >0 multiply an x-coordinate by this to make the preset look the same at any aspect (window height:width) ratio.
  357. -value: if widescreen, 1; if window is tall, h/w.
  358. aspecty NO >0 multiply a y-coordinate by this to make the preset look the same at any aspect (window height:width) ratio.
  359. -value: if widescreen, w/h; if window is tall, 1.
  360. q1 yes any } Used to carry values along a chain
  361. q2 yes any } from the preset init code,
  362. q3 yes any } to the preset per-frame code, then on
  363. q4 yes any } to the preset per-vertex code;
  364. q5 yes any } or to the custom shape per-frame code,
  365. q6 yes any } or to the custom wave per-frame code,
  366. q7 yes any } then to the custom wave per-vertex code;
  367. ... } or to the [pixel] shader code.
  368. q31 yes any } <B><A HREF="q_vars.gif">Click here to see a diagram for the Q vars</A>.</B>
  369. q32 yes any }
  370. The main reason for distinction between per-frame and per-vertex equations
  371. is simple: SPEED. If you have a per-vertex equation that doesn't make use
  372. of the x, y, rad, or ang variables, then there's no reason for it to be
  373. executed per-vertex; it could be executed once per frame, and the result
  374. would be the same. So, here's a maxim to write on the wall:
  375. "If a per-vertex equation doesn't use at least one of the variables
  376. { x, y, rad, ang }, then it should be actually be a per-frame
  377. equation."
  378. You might be wondering how on earth all these formulas could be computed
  379. for every pixel on the screen, every frame, and still yield a high frame
  380. rate. Well, that's the magic of the hamster. And the fact that it really
  381. does the processing only at certain points on the screen, then interpolates
  382. the results across the space between the points. In the config panel,
  383. the "mesh size" option defines how many points (in X and Y) there are at
  384. which the per-vertex equations are actually computed. When you crank this
  385. option up, you start eating up CPU cycles rather quickly.
  386. <A NAME="3c">
  387. <B>c. VARIABLE POOLS; DECLARING YOUR OWN VARIABLES; PERSISTENCE OF VALUES</B>
  388. -----------------------
  389. Declaring and using your own variables is easy - in some bit of code
  390. (init equations, per-frame equations, etc.) you just write something like
  391. the following:
  392. billy = 5.3;
  393. This creates a variable called 'billy' and sets its value to 5.3. You can
  394. then freely read and/or modify the value of 'billy' within that section
  395. of code.
  396. However, sometimes it is desireable to create (really, initialize) a variable
  397. in an "init" equations, then use and/or update it in the "per-frame" equations.
  398. You can always do this, because paired init and per-frame equations
  399. share the same <EM>variable pool.</EM> In addition, the values of user-defined
  400. variables will persist from frame to frame.
  401. <U>There are three variable "pools" in MilkDrop</U>:
  402. 1. preset init code + preset per-frame code
  403. 2. custom wave init + custom wave per-frame code
  404. 3. custom shape init + custom shape per-frame code
  405. So, you can probably guess that if you declare a variable in the preset
  406. init code, you can then read it in the preset per-frame code. You can
  407. also write to it (update it), and its value will persist to the next
  408. frame. All three pools work this way.
  409. As explained, though, you can't read the value of 'billy' in when in another
  410. variable pool. (This is intentional, and keeps MilkDrop running nice and
  411. fast.) If you want to pass values around between variable pools, you need
  412. to use a set of special variables: q1, q2, q3, etc. on up to q32. See
  413. the next section for details on how they work and how to properly use them.
  414. Just remember: the Q variables (and later, the T variables) are the only ones
  415. that you can use to "jump" between (carry values between) variable pools.
  416. You might notice that there are two other types of equations that weren't
  417. listed above. They are:
  418. * preset per-vertex code
  419. * custom wave per-point code
  420. For these two code sections, persistent values don't really make sense,
  421. because there is no way to properly initialize them. Any user-defined
  422. variables in these code sections should just be treated as scratch
  423. variables, not persisting from frame to frame, from vertex to vertex,
  424. or from point to point (even though technically, they will... but it
  425. probably won't be what you want). The only thing that really makes sense
  426. here is when you want to carry values along from point to point as
  427. you run the custom wave per-point code; to do this, use q1-q32. (See
  428. the next section for a more detailed explanation.)
  429. <A NAME="3d">
  430. <B>d. PRESET INIT CODE; CARRYING VALUES BETWEEN VARIABLE POOLS, USING q1-q32</B>
  431. -----------------------
  432. As we've just seen, you can't normally pass values around between variable
  433. pools. However, there is one mechanism for bridging this gap: the 'Q'
  434. variables. They are named q1, q2, q3, and so on, through q32. Their
  435. main function is to bridge the gap between various variable pools.
  436. In MilkDrop 1.03 and later, you can write code that is executed only once,
  437. when a preset is loaded (switched to). This 'preset initialization' code
  438. does two useful things:
  439. 1. It allows you to set the initial value of your own (user-defined)
  440. variables (such as 'my_variable'), as just explained.
  441. 2. It allows you to write the default ("sticky") values for q1, q2, q3...
  442. through q32. Whatever these values end up at after the init code,
  443. those are the values that q1-q32 will be reset to at the start of
  444. each frame (...the input to the per-frame equations). If the
  445. per-frame equations change the values of q1-q32, those new values will
  446. propagate on to other variable pools (see the diagram below), but on
  447. the next frame, the values will be reset to the original "sticky"
  448. defaults.
  449. See the flow chart below for a brief, and complete, glance at how the values
  450. of the Q variables flow throughout MilkDrop.
  451. <IMG SRC="q_vars.gif">
  452. Let's walk through the flow of the chart.
  453. If you write to the values of q1..q32 from the "preset init code", the values
  454. you write will become the new 'base values' to which q1..q32 are initialized
  455. at the start of each frame, for the per-frame code. So when you access (read)
  456. q1-q32 in the per-frame code, you'll get the values that were *initially* set -
  457. over and over, every frame. You can then modify them (or not) in the per-frame
  458. code, and the (possibly modified values) will then be readable by the per-vertex
  459. code - as well as by all pixel shader code, and others. However, any modified
  460. values will not persist to the next frame; they will be reset again, at the
  461. start of the next frame, to the values they had at the end of the preset init
  462. code.
  463. In the <B>per-vertex code</B>, the q1-q32 values start (for the first vertex
  464. in any frame) as the values they had at the end of the per-frame code. If you
  465. modify q1-q32 in the per-vertex code, those modified values will carry over
  466. from vertex to vertex. (This isn't a very desireable effect; you should avoid
  467. writing to the Q variables from the per-vertex equations.) Next frame, they
  468. will be reset to whatever value they had at the end of the [next frame's
  469. execution of the] per-frame code. (It's all in the diagram... look at that,
  470. and you'll just get it.)
  471. There is one trick here. You might notice that the custom wave/shape
  472. <EM>init</EM> boxes are missing from the diagram. That's because the q
  473. variables coming out of them <EM>don't go anywhere</EM>. The Q values that come
  474. into the per-<EM>frame</EM> wave/shape equations come from the <EM>preset per-frame</EM>
  475. equations, as you can see. But, just to humor you: in the wave/shape init code,
  476. the Q values coming in are the results from the preset init code. Any Q values
  477. you write to there (in the wave/shape init code) will be meaningless; although
  478. you can write to (initialize) your own custom variables, and read those in
  479. later, in the wave/shape per-frame equations! So, really, you can still route
  480. data that way, if you really want to.
  481. Side note: when you edit the preset init code and apply it (by hitting
  482. CTRL+ENTER), the init code will re-execute immediately. However, when you
  483. edit the regular per-frame/per-vertex code and hit CTRL+ENTER, the preset init
  484. code will NOT be re-executed; the results of the last execution will persist.
  485. If you change per-frame/per-vertex code and want to re-execute the initialization
  486. code (i.e. to randomize it or reset the preset), you'll have to save the preset
  487. and then re-load it.
  488. (Historical note: nothing here has changed since MilkDrop 1; these diagrams were
  489. just re-designed to be much simpler to read. Actually, there was a bug in
  490. the old diagrams that is now fixed: on frame 0, they showed the Q values
  491. going straight from the (frame 0!?) per-<EM>frame</EM> code, into the custom
  492. wave/shape init code. On frame 0, those Q values actually come straight from
  493. the preset init code. HOWEVER, they are virtually useless, as discussed above.)
  494. <A NAME="3e">
  495. <B>e. CUSTOM SHAPES AND WAVES</B>
  496. ----------------------
  497. As of MilkDrop 1.04, two new features are available: custom shapes, and custom
  498. waves. A preset can have up to 4 of each.
  499. With custom shapes, you can draw an n-sided shape (with 3-100 sides) anywhere
  500. on the screen, at any angle and size, in any color, and at any opacity. You
  501. even have the option to map the previous frame's image onto the shape, which
  502. makes for some incredible possibilities (such as realtime hardware fractals -
  503. see the 'Geiss - Feedback' preset). You can also write per-frame code to
  504. control all of these things about the shape(s). This way, they can react to
  505. the audio or change over time - whatever you can imagine. You are limited to
  506. four custom shapes per preset, however, each one of those can be instanced,
  507. which lets you draw a huge number (up to 1024) of them each frame, if you
  508. want to, and each one can be totally different (as long as the value of
  509. the 'instance' variable ends up influencing the other properties).
  510. With custom waves, you can draw the waveform (or the frequency spectrum)
  511. wherever, whenever, and however you want; a great addition since MilkDrop
  512. 1.03, where only the built-in waveforms were possible. With custom waves
  513. you can also write per-frame code to control the waves, and per-point code
  514. to place every point (or line segment) on the wave exactly where you want,
  515. and in exactly the color you want, and so on.
  516. Remember those q1-q32 variables that were committed at the end of the preset
  517. initialization code, then reset (to those values) at the beginning of each
  518. frame, and then (potentially) modified in the preset per-frame code? Those
  519. (potentially modified) values of q1-q32 - as they were at the end of the
  520. preset's per-frame code, each frame - are piped into the custom wave & custom
  521. shape per-frame code. So if you read 'q3' in the custom wave per-frame
  522. code, what you're really reading is the value of 'q3' as it was left at the
  523. end of this frame's per-frame code. Again, see the <A HREF="q_vars.gif">q_vars.gif</A> image
  524. for a diagram of the flow of the values of the q1-q32 varibles.
  525. For custom waves and shapes, you can modify q1-q32, if you like, in the per-
  526. frame equations. As usual, the values of the Q variables will not persist
  527. from frame to frame, though - they are reset on each new frame, to match
  528. the values they had at the end of the *preset's* per-frame code, this frame.
  529. For custom waves, you also have one more link in the chain: per-point
  530. (aka per-vertex) code. This code is executed once for each data point in the
  531. waveform. The initial values of q1-q32 coming in (for the first point)
  532. are the values that stood at the end of the custom wave per-frame code,
  533. this frame. If you then modify q1-q32 in the per-point code (or even if you
  534. don't), the values will pass on to the next point. You could, for example,
  535. smooth out a waveform using this.
  536. THE 'T' VARIABLES
  537. ----------------------
  538. There are 8 additional variables available for custom waves and shapes:
  539. <B>t1-t8</B>. These are very similar to the Q variables, but they exist only
  540. for custom waves & shapes. To see how the data flows from variable pool
  541. to variable pool for the T vars, take a look at the diagram below. Like
  542. the Q variables, they exist to help you bridge some gaps between variable
  543. pools. However, the T variables are a bit simpler to understand than the
  544. Q's. The diagram below should explain it all.
  545. <IMG SRC="t_vars.gif">
  546. CUSTOM SHAPE PER-FRAME VARIABLES
  547. ----------------------
  548. NAME WRITABLE? RANGE DESCRIPTION
  549. ---- --------- ----- -----------
  550. num_inst no 1-1024 The total # of instances (the number of times to repeat the per-frame equations for, & draw, this shape).
  551. instance no 0..num_inst-1 The current instance number that the equations are being executed for.
  552. sides yes 3-100 the default number of sides that make up the polygonal shape
  553. thick yes 0/1 if ON, the border will be overdrawn 4X to make it thicker, bolder, and more visible
  554. additive yes 0/1 if ON, the shape will add color to sature the image toward white; otherwise, it will replace what's there.
  555. x yes 0..1 default x position of the shape (0..1; 0=left side, 1=right side)
  556. y yes 0..1 default y position of the shape (0..1; 0=bottom, 1=top of screen)
  557. rad yes 0+ default radius of the shape (0+)
  558. ang yes 0..6.28 default rotation angle of the shape (0...2*pi)
  559. textured yes 0/1 if ON, the shape will be textured with the image from the previous frame
  560. tex_zoom yes >0 the portion of the previous frame's image to use with the shape
  561. tex_ang yes 0..6.28 the angle at which to rotate the previous frame's image before applying it to the shape
  562. r yes 0..1 default amount of red color toward the center of the shape (0..1)
  563. g yes 0..1 default amount of green color toward the center of the shape (0..1)
  564. b yes 0..1 default amount of blue color toward the center of the shape (0..1)
  565. a yes 0..1 default opacity of the center of the shape; 0=transparent, 1=opaque
  566. r2 yes 0..1 default amount of red color toward the outer edge of the shape (0..1)
  567. g2 yes 0..1 default amount of green color toward the outer edge of the shape (0..1)
  568. b2 yes 0..1 default amount of blue color toward the outer edge of the shape (0..1)
  569. a2 yes 0..1 default opacity of the outer edge of the shape; 0=transparent, 1=opaque
  570. border_r yes 0..1 default amount of red color in the shape's border (0..1)
  571. border_g yes 0..1 default amount of green color in the shape's border (0..1)
  572. border_b yes 0..1 default amount of blue color in the shape's border (0..1)
  573. border_a yes 0..1 default opacity of the shape's border; 0=transparent, 1=opaque
  574. time NO >0 retrieves the current time, in seconds, since MilkDrop started running
  575. fps NO >0 retrieves the current framerate, in frames per second.
  576. frame NO retrieves the number of frames of animation elapsed since the program started
  577. 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.
  578. -note that if Scroll Lock is on, 'progress' will freeze!
  579. bass NO >0 retrieves the current amount of bass. 1 is normal; below ~0.7 is quiet; above ~1.3 is loud bass
  580. mid NO >0 -same, but for mids (middle frequencies)
  581. treb NO >0 -same, but for treble (high) frequencies
  582. bass_att NO >0 retrieves an attenuated reading on the bass, meaning that it is damped in time and doesn't change so rapidly.
  583. mid_att NO >0 -same, but for mids (middle frequencies)
  584. treb_att NO >0 -same, but for treble (high) frequencies
  585. q1 yes any } Used to carry values along a chain
  586. q2 yes any } from the preset init code,
  587. q3 yes any } to the preset per-frame code, then on
  588. q4 yes any } to the preset per-vertex code;
  589. q5 yes any } or to the custom shape per-frame code,
  590. q6 yes any } or to the custom wave per-frame code,
  591. q7 yes any } then to the custom wave per-vertex code;
  592. ... } or to the [pixel] shader code.
  593. q31 yes any } <B><A HREF="q_vars.gif">Click here to see a diagram for the Q vars</A>.</B>
  594. q32 yes any }
  595. t1 yes any } Used to carry information
  596. t2 yes any } from the custom shape init code
  597. t3 yes any } to the custom shape per-frame code.
  598. t4 yes any } <B><A HREF="t_vars.gif">Click here to see a diagram for the T vars</A>.</B>
  599. t5 yes any }
  600. t6 yes any }
  601. t7 yes any }
  602. t8 yes any }
  603. CUSTOM WAVE PER-FRAME VARIABLES
  604. ---------------------
  605. NAME WRITABLE? RANGE DESCRIPTION
  606. ---- --------- ----- -----------
  607. r yes 0..1 base amount of red color in the wave (0..1)
  608. g yes 0..1 base amount of green color in the wave (0..1)
  609. b yes 0..1 base amount of blue color in the wave (0..1)
  610. a yes 0..1 base opacity of the waveform; 0=transparent, 1=opaque
  611. samples yes 0-512 read: retrieves the # of samples specified for this custom wave (from the menu).
  612. write: lets you dynamically change that #, frame to frame.
  613. time NO >0 retrieves the current time, in seconds, since MilkDrop started running
  614. fps NO >0 retrieves the current framerate, in frames per second.
  615. frame NO retrieves the number of frames of animation elapsed since the program started
  616. 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.
  617. -note that if Scroll Lock is on, 'progress' will freeze!
  618. bass NO >0 retrieves the current amount of bass. 1 is normal; below ~0.7 is quiet; above ~1.3 is loud bass
  619. mid NO >0 -same, but for mids (middle frequencies)
  620. treb NO >0 -same, but for treble (high) frequencies
  621. bass_att NO >0 retrieves an attenuated reading on the bass, meaning that it is damped in time and doesn't change so rapidly.
  622. mid_att NO >0 -same, but for mids (middle frequencies)
  623. treb_att NO >0 -same, but for treble (high) frequencies
  624. q1 yes any } Used to carry values along a chain
  625. q2 yes any } from the preset init code,
  626. q3 yes any } to the preset per-frame code, then on
  627. q4 yes any } to the preset per-vertex code;
  628. q5 yes any } or to the custom shape per-frame code,
  629. q6 yes any } or to the custom wave per-frame code,
  630. q7 yes any } then to the custom wave per-vertex code;
  631. ... } or to the [pixel] shader code.
  632. q31 yes any } <B><A HREF="q_vars.gif">Click here to see a diagram for the Q vars</A>.</B>
  633. q32 yes any }
  634. t1 yes any } Used to carry information
  635. t2 yes any } from the custom wave init code,
  636. t3 yes any } to the custom wave per-frame code,
  637. t4 yes any } then on to the custom wave per-point code
  638. t5 yes any } (and from point to point, too, if you write
  639. t6 yes any } to the values from the per-point equations).
  640. t7 yes any } <B><A HREF="t_vars.gif">Click here to see a diagram for the T vars</A>.</B>
  641. t8 yes any }
  642. CUSTOM WAVE PER-POINT (aka PER-VERTEX) VARIABLES
  643. ---------------------
  644. NAME WRITABLE? RANGE DESCRIPTION
  645. ---- --------- ----- -----------
  646. x yes 0..1 the x position of this point that makes up the wave (0=left, 1=right)
  647. y yes 0..1 the y position of this point that makes up the wave (0=bottom, 1=top)
  648. 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.
  649. value1 no any the value of the Left audio channel sample at this point in the waveform (or freq. spectrum).
  650. value2 no any the value of the Right audio channel sample at this point in the waveform (or freq. spectrum).
  651. r yes 0..1 amount of red color in this point of the wave (0..1)
  652. g yes 0..1 amount of green color in this point of the wave (0..1)
  653. b yes 0..1 amount of blue color in this point of the wave (0..1)
  654. a yes 0..1 opacity of this point of the waveform; 0=transparent, 1=opaque
  655. time NO >0 retrieves the current time, in seconds, since MilkDrop started running
  656. fps NO >0 retrieves the current framerate, in frames per second.
  657. frame NO retrieves the number of frames of animation elapsed since the program started
  658. 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.
  659. -note that if Scroll Lock is on, 'progress' will freeze!
  660. bass NO >0 retrieves the current amount of bass. 1 is normal; below ~0.7 is quiet; above ~1.3 is loud bass
  661. mid NO >0 -same, but for mids (middle frequencies)
  662. treb NO >0 -same, but for treble (high) frequencies
  663. bass_att NO >0 retrieves an attenuated reading on the bass, meaning that it is damped in time and doesn't change so rapidly.
  664. mid_att NO >0 -same, but for mids (middle frequencies)
  665. treb_att NO >0 -same, but for treble (high) frequencies
  666. q1 yes any } Used to carry values along a chain
  667. q2 yes any } from the preset init code,
  668. q3 yes any } to the preset per-frame code, then on
  669. q4 yes any } to the preset per-vertex code;
  670. q5 yes any } or to the custom shape per-frame code,
  671. q6 yes any } or to the custom wave per-frame code,
  672. q7 yes any } then to the custom wave per-vertex code;
  673. ... } or to the [pixel] shader code.
  674. q31 yes any } <B><A HREF="q_vars.gif">Click here to see a diagram for the Q vars</A>.</B>
  675. q32 yes any }
  676. t1 yes any } Used to carry information
  677. t2 yes any } from the custom wave init code,
  678. t3 yes any } to the custom wave per-frame code,
  679. t4 yes any } then on to the custom wave per-point code
  680. t5 yes any } (and from point to point, too, if you write
  681. t6 yes any } to the values from the per-point equations).
  682. t7 yes any } <B><A HREF="t_vars.gif">Click here to see a diagram for the T vars</A>.</B>
  683. t8 yes any }
  684. <A NAME="3f">
  685. <B>f. PIXEL SHADERS</B>
  686. ----------------------
  687. The world of realtime computer graphics made a huge stride around 2002-2003,
  688. with the advent of pixel shaders. Lots of people want to learn how to
  689. use pixel shaders; writing presets for MilkDrop is a <EM>great</EM> way
  690. to learn them, because you get to see the effects of your code instantly,
  691. on the screen.
  692. MilkDrop 1 ran on what is called the "fixed function" graphics pipeline.
  693. That meant that certain common graphics operations - and very few of them -
  694. could be executed for each pixel. You could do a few things - maybe multiply
  695. by a texture or a color, then maybe one more simple operation - but that was about it.
  696. Newer presets (MilkDrop 2 and later) can take advantage of <EM>programmable
  697. pixel shaders</EM>. GPUs (graphics processing units) are now capable of
  698. executing dozens, even thousands (on more expensive hardware) of instructions
  699. per pixel. To tell the GPU what to do at each pixel, you write some code
  700. called a "pixel shader". It looks a lot like C, except you'll see
  701. the types float3 (...often representing a color, or maybe a 3D coordinate),
  702. as well as float2 and float4, as often as you'll see the simple
  703. "float" type. There is also a lot of emphasis on sampling from textures.
  704. Textures can either be procedural (like the image from the previous
  705. frame, or a nicely gaussian-blurred version of it, or a procedurally-
  706. generated noise texture), or they can be loaded from disk. To sample
  707. from a texture on disk (...but cached in video memory, of course),
  708. in the shader, you simply specify the name of the image file you want to load,
  709. and how you want to sample it (what kind of filtering & wrapping) as well as
  710. where (the UV coordinates, like XY coordinates, always in the [0..1] range).
  711. It reads the sample (as a float4 - some image formats have four channels
  712. instead of just r/g/b). You can then do whatever you like (mathematically)
  713. with that sample, take other samples, combine them, and so on. The final
  714. output of the shader is always a color value, and it is this color value
  715. that is written to the render target (an internal texture, or the screen).
  716. <B>SHADER MODELS - 2.0, 3.0, etc.</B>
  717. ------------------------------
  718. Since pixel shaders were born, there have been a few revisions. Each new
  719. model has more capabilities than the last.
  720. MilkDrop 1 only supports fixed-function graphics - i.e. no pixel shaders.
  721. MilkDrop 2 supports shader model 2 at the lowest level. (If your GPU
  722. doesn't support this, MilkDrop 2 should still run - it just won't show
  723. you any presets that use pixel shaders.) Shader model 2 has a limit of
  724. 64 instructions (per shader), though.
  725. Presets can be authored to use Shader Model 3, however. This shader
  726. model is not as widely supported (...so be careful writing presets for
  727. it - half of the GPUs out there don't support it yet, so the preset
  728. won't show up in the preset list on those computers). However, it is
  729. much more powerful, with a virtually unlimited number of instructions.
  730. (You're just limited by the speed of your GPU and the number of pixels
  731. you need to draw each frame!) On a GeForce 8000-series, believe it
  732. or not, you can easily achieve smooth framerates running shaders with
  733. THOUSANDS of instructions!
  734. Shader Model 4.0 also exists, but only in DirectX 10; and DirectX 10
  735. is only available with Windows Vista. Because not many people have
  736. Vista yet, we've decided to wait (a damn long time) until going down
  737. that path. Shader Model 3 has virtually everything we need in it
  738. anyway.
  739. <B>PRESET FILE VERSIONS & COMPATIBILITY</B>
  740. ------------------------------------
  741. Note that if you load a MilkDrop 1 preset, you can save it back to disk
  742. (even after changing code, variables, etc.) and it will still be readable
  743. by MilkDrop 1. Only if you select the menu option to "Upgrade [its]
  744. Pixel Shader Version" will you be making it no longer backwards-compatible.
  745. Once you've done this, though, you'll notice that the menus look slightly
  746. different - some new shader-based options will appear, and some old stuff
  747. (video echo, gamma, etc. - all things that are now folded into the
  748. composite shader) are all gone. You'll also notice that two nice little
  749. default shaders (warp and composite) have been written for you, and that
  750. the relevant values and options from the old preset (gamma, decay, video
  751. echo, texture wrap, etc.) have all been set correctly in the new shaders,
  752. so that the preset does exactly what it did before. The only difference
  753. is that now, the preset takes advantage of the full programmability of
  754. pixel shaders (and you have a lot of freedom to tweak it), instead of
  755. being restricted by the highly restrictive DX8 fixed-function graphics
  756. pipeline.
  757. Some of the mash-up functions (discussed later) will mix old and new
  758. presets together. In this case, the newly-created preset file will only
  759. look correct on MilkDrop 1.xx if it uses neither a warp nor composite shader.
  760. It will still run in MilkDrop 1, but without shaders, so whatever random
  761. values gamma, video echo, etc. were left at, will all kick back in.
  762. One last note: keep in mind that MilkDrop 2 is smart enough to not show
  763. you any presets that your GPU can't support. MilkDrop 1, though, isn't
  764. so smart - it will let you look at MilkDrop 2 presets. It will
  765. ignore all the shader stuff, and probably not display correctly, though.
  766. <A NAME="3f1">
  767. <B>A PIXEL SHADER - CONCEPTUAL OVERVIEW</B>
  768. -------------------------------------
  769. Games are what have driven the Hardware Graphics revolution, and games
  770. work by projecting many thousands of 3D triangles onto your screen and
  771. rasterizing (pixelizing) & shading them. In MilkDrop, also,
  772. your graphics processing unit (GPU) is told to draw many triangle onto
  773. your screen. Each is described by three vertices (points). The interior
  774. of the triangle is a bunch of pixels. The GPU runs your "shader" code
  775. on each pixel to determine how to shade the pixel - i.e., light it,
  776. or determine its color. (The terminology is more geared toward the
  777. idea that these triangles were originally in 3D and require realistic
  778. lighting and shading.)
  779. In MilkDrop, the shaders are run on a dumb, regular grid of triangles
  780. that covers the entire visualizer window. The results of the preset's
  781. per-vertex equations are interpolated across the face of each of these
  782. triangles, and your pixel shader will see the interpolated results.
  783. They come in in the form of "UV" coordinates - they tell you where
  784. to sample (read) the source image, in order to create the desired warping
  785. effect each frame - the long-term effect of which is to create perceived
  786. motion.
  787. You can then sample that image (or others), do some math on the result,
  788. sample some other textures, do some more math, etc. By the end of
  789. the shader, whatever value is in "ret" (a float3 - three floating-point
  790. values) is the color that will be written for that pixel.
  791. Each preset in MilkDrop 2 has two pixel shaders: the warp shader,
  792. which warps the image from frame to frame, and the composite shader,
  793. which draws the frame to the screen (with or without special effects).
  794. To edit or experiment with these shaders, while MilkDrop is running,
  795. hit 'M' to view the preset editing menu. The scroll down to either
  796. [edit warp shader]
  797. or
  798. [edit composite shader]
  799. and hit ENTER. If you don't see either of these options, it means
  800. the current preset is an old MilkDrop 1 preset; in this case, you can
  801. either try a different preset, or you can upgrade the current preset
  802. by selecting
  803. update preset's pixel shader version
  804. toward the bottom of the menu. Keep in mind that if you upgrade
  805. a preset's pixel shader version and then save it to disk, it might
  806. not be usable anymore on other computers with older graphics chips.
  807. Now go edit one of the two shaders. Once you're in there, editing,
  808. hit F9 - this will toggle the onscreen quick reference for writing
  809. shaders. It's very handy. Press F9 again to hide it.
  810. <A NAME="3f2">
  811. <B>WARP SHADER</B>
  812. ----------------
  813. Here is an example of a simple WARP shader. It is run over every pixel of
  814. the internal canvas, with the output being back to the canvas itself (it's
  815. a double-buffered texture). Any special effects that happen here get "baked"
  816. into the image, and will persist into the next frame.
  817. <font color=#A00000>
  818. shader_body
  819. {
  820. // sample a pixel from the previous frame.
  821. // uv coord is slightly warped (driven by the per-vertex equations),
  822. // and is what creates the main "movement" in our preset.
  823. ret = tex2D( sampler_main, uv ).xyz;
  824. // darken over time
  825. ret *= 0.97;
  826. }</font>
  827. There are only two instructions here... sample the old frame, and
  828. darken the old color value (color values are always in the 0..1 range)
  829. to prevent the screen from turning white over time.
  830. This code is run on every pixel on the screen. If the UV's coming in
  831. were just [0..1] on X and Y, corresponding exactly to the location of
  832. the <EM>pixel</EM> on the screen, there would be no movement (or warp).
  833. What creates the warp is that the UV coordinates are slightly "off".
  834. Each frame, MilkDrop executes the per-vertex equations for the current
  835. preset at all the vertices on a grid covering the screen. The resulting
  836. UV coordinates are then interpolated (by the GPU) between the vertices,
  837. and this shader code is executed at each pixel, with the UV coordinates
  838. smoothly interpolated for you to do your sampling. Note that the
  839. original, un-distorted UV coordinates are always available in uv_orig.
  840. If the preset had no motion in it, or if we used uv_orig instead of uv,
  841. we would just see pixels getting darker over time, with no apparent motion.
  842. Note that MilkDrop's internal canvas (texture) can only store colors
  843. in the [0..1] range, so if your shader outputs values beyond that range,
  844. the values will be clipped to 0 or 1. Within the body of the shader,
  845. you can go nuts, using any number ranges you want; this restriction only
  846. applies to the final output.
  847. Note that there are several ways to darken pixels over time, and the
  848. color precision (8 bits per color channel, or 256 shades, or [0..1]
  849. in increments of 0.004) means you have to be careful about darkening
  850. the color over time. If you're going to darken using this:
  851. ret *= 0.97;
  852. then you shouldn't use a multiplier above 0.98, because, due to precision,
  853. dark-ish pixels will never become fully dark. Another way to do it
  854. is this:
  855. ret -= 0.004;
  856. The above darkening method will make the pixels go dark, although,
  857. sometimes too quickly. One way around this is to use error diffusion
  858. dithering (discussed later in this guide).
  859. Probably the best thing is to combine the two:
  860. ret = (ret - 0.002)*0.99;
  861. This gives you a partially constant, partially linear darkening effect,
  862. and it tends to look the best. Tweak the values as needed.
  863. <A NAME="3f3">
  864. <B>COMPOSITE SHADER</B>
  865. ----------------
  866. Here is an example of a simple COMPOSITE shader. It is run over every
  867. pixel in the visualizer window, the output being the actual screen that
  868. you see. Anything you do here will NOT affect the subsequent frame -
  869. it will only affect the display of the <EM>current</EM> frame.
  870. <font color=#A00000>
  871. shader_body
  872. {
  873. // sample the corresponding pixel from the internal rendering canvas
  874. // note that, here, 'uv' is undistorted.
  875. // in the warp shader, 'uv' is warped, and 'uv_orig' is undistorted!
  876. ret = tex2D(sampler_main, uv).xyz;
  877. // make it a little bit "overbright"
  878. ret *= 1.8;
  879. }</font>
  880. The composite shader is easy to understand. We just sample the
  881. internal canvas at the uv coords (undistorted here - but we could
  882. play with them if we want!), and manipulate the result if we want
  883. (here we brighten it a bit). The "overbrightening" here is nice because
  884. pixels in the brighter ranges will (for display to the user only)
  885. wash out to a white color; however, they can stay that way
  886. for a bit. If we just displayed the color as-is here, and
  887. instead drew our waveforms twice as bright, they would likely
  888. start out at white but very quickly fade to shades of grey.
  889. Note that we could do other fancy stuff here instead, like:
  890. <font color=#A00000>
  891. float2 uv_flipped = 1 - uv; // '1' auto-replicates to float2(1,1)
  892. ret = max( tex2D(sampler_main, uv).xyz,
  893. tex2D(sampler_main, uv_flipped).xyz );
  894. ret = pow(ret, float3(0.5, 1, 2));
  895. </font>
  896. This would flip the image about its diagonal, always show you
  897. the brighter pixel from the two orientations, and then ramp
  898. the R/G/B channels at different exponents to create a bit of
  899. a cepia color tone. Not too tough!
  900. Now that you have an understanding of what the two shaders do,
  901. let's look at all the intrinsic types and operators you can use
  902. in shaders.
  903. <A NAME="3f4">
  904. <B>PIXEL SHADER REFERENCE</B>
  905. ----------------------
  906. Here is a list of all the shader functions and operations at your disposal.
  907. Data types
  908. ----------
  909. float 1-4 component full-precision floating-point values.
  910. float2 Use these for most things except color values.
  911. float3 (When working with UV coords, time values, or big ranges
  912. float4 of values, for example.)
  913. half 1-4 component half-precision floating-point values.
  914. half2 Much faster on some older hardware; although drivers usually
  915. half3 automatically substitute the 'half' type on you (behind your back)
  916. half4 wherever it is prudent. Use 'half' for color values, or other
  917. computations where precision is largely unimportant.
  918. float2x2 2d transformation matrix. (Rotate and/or scale.)
  919. float3x2 2d transformation matrix. (Rotate, scale, translation.)
  920. float3x3 3d transformation matrix. (Rotate and/or scale.)
  921. float4x3 3d transformation matrix. (Rotate, scale, translation.)
  922. Operators
  923. ----------
  924. + - * / typical arithmetic operators.
  925. a += b same as "a = a + b". Also valid: -= *= /=
  926. == equality test.
  927. < less than.
  928. <= less than or equal to.
  929. > greater than.
  930. >= your mom is soo fat.
  931. var.x swizzle operators. You can stick a dot after any variable
  932. var.y and put up to four letters after it. If the variable is
  933. var.z a float4, you can choose from x, y, z, and w; if it's a float2,
  934. var.w just x and y; and so on. The data type yielded can be different
  935. var.xy than the input, and is determined by the number of letters after
  936. var.wzxy the dot, and which fields (from the input) you chose.
  937. etc. For example, if you had:
  938. float alpha = 104.37;
  939. float2 bravo = float2(1,2);
  940. float3 chuck = float3(10,20,30);
  941. float4 delta = float4(5,6,7,8);
  942. Then these swizzles would yield:
  943. alpha.xxx -> float3(104.37, 104.37, 104.37)
  944. bravo.yx -> float2(2,1)
  945. chuck.z -> 30
  946. delta.wywy -> float4(8,6,8,6)
  947. Preprocessor
  948. ------------
  949. If you're familiar with C/C++, you can use simple things like
  950. #define, #if (condition) / #endif, #if / #elif/#else / #endif, and so on.
  951. <A NAME="3f5">
  952. <B>Intrinsic Instructions</B>
  953. ----------------------
  954. Unless otherwise noted, these instructions all work on float, float2, float3,
  955. or float4 operands.
  956. <FONT COLOR="green">
  957. math operations
  958. ---------------
  959. abs(a) Absolute value. Returns max(a, -a).
  960. frac(a) Fractional value. Returns (a - (int)a). (the part after the decimal)
  961. floor(a) Floor. Returns ((int)a). (the part before the decimal)
  962. Only works on single floats.
  963. saturate(a) Clamps a to the [0..1] range. Often FREE (costs no extra instructions).
  964. max(a,b) Returns the greater of each component between a and b.
  965. min(a,b) Returns the lesser of each component between a and b.
  966. sqrt(a) Returns square root of input(s). Input should be >= 0. Output always positive.
  967. pow(a,b) Returns a^b. b can be same type as a, or just a scalar (single float).
  968. exp(a) Returns 2^a.
  969. log(a) Returns log2(a).
  970. lerp(a,b,c) Linear interpolate... blends from a to b based on the value of c[0..1].
  971. (Or extrapolates, if c is outside [0..1] range.)
  972. a and b must be same type; can can be that same type, or just float.
  973. Returns a + c*(b-a). Return type is same as a and b.
  974. dot(a,b) Dot product. All versions return <EM>A SINGLE FLOAT</EM>.
  975. dot(float a, float b) returns a+b.
  976. dot(float2 a, float2 b) returns a.x*b.x + a.y*b.y.
  977. dot(float3 a, float3 b) returns a.x*b.x + a.y*b.y + a.z*b.z.
  978. dot(float4 a, float4 b) returns a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w.
  979. lum(a) Converts a color (float3) to greyscale, or "luminance", for the human eye.
  980. Returns dot(a, float3(0.32,0.49,0.29)).
  981. Tip: oversaturate a color using "col = lerp(lum(col), col, 2);"
  982. length(a) Input is float2, float3, or float4 vector; returns the length of the vector.
  983. Returns sqrt(
  984. normalize(a) Input is float2, float3, or float4 vector; normalizes it to unit length (1.0).
  985. Returns a / length(a).
  986. texture operations
  987. ------------------
  988. <FONT COLOR="black">tex2D(sampler_name, uv) </FONT>
  989. Samples a 2D texture at the coordinates 'uv', where UV is a float2.
  990. Returns a float4 (r,g,b,alpha).
  991. tex3D(sampler_name, uvw)
  992. Samples a volume (3D) texture at the coordinates 'uvw', where UVW is a float3.
  993. You could use this to sample a built-in "noise volume" or a volume texture
  994. from a .DDS texture (that holds a 3D texture).
  995. Returns a float4 (r,g,b,alpha).
  996. GetBlur1(uv) Samples a slightly-blurred version of the main texture
  997. (internal canvas). Input is float2; outputs (returns) a float3.
  998. GetBlur2(uv) Samples a more-blurred version.
  999. GetBlur3(uv) Samples a very blurry version.
  1000. mega-slow operations
  1001. --------------------
  1002. sin(a) Returns cos(a), where a is in radians. Output is in -1..1 range.
  1003. SLOW - use with care.
  1004. cos(a) Returns sin(a), where a is in radians. Output is in -1..1 range.
  1005. SLOW - use with care.
  1006. atan2(y,x) Returns the arctangent of y/x. In english, this means that if you give
  1007. it a Y and X coordinate (with the origin at zero), it will tell you
  1008. the angle you are at, with respect to the origin. The signs of x and y
  1009. are used to determine the quadrant of the return values in the range
  1010. [-pi, pi]. atan2 is well-defined for every point other than the origin.
  1011. You basically always want to use it like this:
  1012. float2 uv2 = (uv-0.5)*aspect.xy; // widescreen- or 4:3-friendly
  1013. float ang = atan2(uv2.y,uv2.x);
  1014. SLOW - use with care.
  1015. mul(a,b) Multiplies a vector and a matrix together. You can treat the matrix
  1016. as row-major or column-major based on whether you do mul(vec,mat)
  1017. or mul(mat,vec).
  1018. cross(a,b) Cross product. Returns (a.yzx*b.zxy - a.zxy*b.yzx).
  1019. Input and output must be float3's.
  1020. Slow - use with care.
  1021. if (a == b) 'If' blocks work in pixel shaders, although they can be very slow;
  1022. { the full code is always executed, whether the branch is taken or not.
  1023. ... You can use the equality operator, == (note the two equals signs!
  1024. } very important!) or the >, >=, <, or <= comparators.
  1025. else
  1026. {
  1027. ...
  1028. }
  1029. </FONT>
  1030. Keep in mind that cos(), sin(), and atan2() are incredibly slow (~8 instructions).
  1031. Almost everything else (even divide, taking a reciprocal square root, etc.) is 1
  1032. or maybe, at most, 2 instructions.
  1033. Note that the saturate() instruction, as well as multiplying by 2, 4, or 8,
  1034. or dividing by 2, 4, or 8, is a free operation on many GPUs. And the ALUs
  1035. inside a GPU almost always do a multiply + add (both) in a single instruction.
  1036. Also, you can divide by an integer constant without suffixing it with ".0";
  1037. in C/C++, "float x = 1/5;" will give you ZERO; but in shader language, it
  1038. will give you what you expect: 0.2.
  1039. <A NAME="3f6">
  1040. <B>PER-VERTEX SHADER INPUTS</B>
  1041. ------------------------
  1042. <U>Warp shader</U>:
  1043. float2 uv; // .xy = warped UV coords, ~[0..1]
  1044. float2 uv_orig; // .xy = original (un-warped) UV coords. [0..1]
  1045. float rad; // radius of the current pixel from center of screen [0..1]
  1046. float ang; // angle of the current pixel from center of screen [0..2*PI]
  1047. <U>Composite shader</U>:
  1048. float2 uv; // .xy = [un-warped] UV coords.
  1049. float rad; // radius of the current pixel from center of screen [0..1]
  1050. float ang; // angle of the current pixel from center of screen [0..2*PI]
  1051. float3 hue_shader; // .xyz = a color that varies across the screen
  1052. // (the old 'hue shader' effect from MilkDrop 1).
  1053. Note that for both shaders, the vertex-interpolated angle value (ang)
  1054. gets a bit wonky near the center of the screen, where it is very difficult to
  1055. interpolate well (because it wraps suddenly from 0 to PI*2 at 9 o'clock on your
  1056. screen). If you see artifacts due to this, just use
  1057. float better_ang = atan2(uv.y - 0.5, uv.x - 0.5);
  1058. It's very slow, but will give you perfect results. Also, if you want a slightly
  1059. higher-quality value for the radius, use:
  1060. float better_rad = length(uv - 0.5);
  1061. The unwarped UV values will always be of impeccable quality, though,
  1062. because they will be interpolated in the direction that they vary,
  1063. and the rectilinear mesh is aligned perfectly for this.
  1064. <A NAME="3f7">
  1065. <B>PER-FRAME SHADER INPUTS</B>
  1066. -----------------------
  1067. MilkDrop feeds lots of data into the the shaders. Here is a list of everything
  1068. that the shaders can access.
  1069. float4 rand_preset; // 4 random floats [0..1], updated once per preset
  1070. float4 rand_frame; // 4 random floats [0..1], updated each frame
  1071. float time; // the time, in seconds, starting at zero when the *preset* starts.
  1072. // (wraps back to zero after 10,000 seconds locked on a single preset.)
  1073. float fps; // the current framerate (frames per second).
  1074. float frame; // the current frame #.
  1075. float progress; // the progress through the current preset. [0..1]
  1076. float bass; // immediate info about audio levels,
  1077. float mid; // just like in the per-frame equations,
  1078. float treb; // etc.
  1079. float vol; //
  1080. float bass_att; // slightly dampened info about audio levels.
  1081. float mid_att; // look at bass/bass_att, for example;
  1082. float treb_att; // if it's >1, then the bass is spiking.
  1083. float vol_att; //
  1084. float4 aspect // .xy: multiplier to use on UV's to paste an image fullscreen, *aspect-aware*; .zw = inverse.
  1085. float4 texsize // info about the size of the internal canvas, in pixels.
  1086. // .xy = (width,height); .zw = (1/(float)w, 1/(float)h)
  1087. // here are some values that roam around in the [0..1] range at varying speeds.
  1088. float4 slow_roam_cos // .xyzw ~= 0.5 + 0.5*cos(time * float4(~0.005, ~0.008, ~0.013, ~0.022))
  1089. float4 roam_cos // .xyzw ~= 0.5 + 0.5*cos(time * float4(~0.3, ~1.3, ~5, ~20))
  1090. // here are the corresponding sine values, in case you want them.
  1091. // pick a cos/sin pair and use the same accessor on it (.x, .z, etc.)
  1092. // to get plot a point making a circle over time.
  1093. float4 slow_roam_sin // .xyzw ~= same, but using sin()
  1094. float4 roam_sin // .xyzw ~= same, but using sin()
  1095. // of course, if you want anything more complicated, just generate it
  1096. // yourself in the per-frame equations, save it in q1-q32, and it will
  1097. // be available to your shaders!
  1098. float q1; // The values of the q1-q32 variables,
  1099. float q2; // as output by the preset's per-frame equations.
  1100. //... //
  1101. float q31; //
  1102. float q32; //
  1103. float4 _qa; // q1-q4 The values of the q1-q32 variables,
  1104. float4 _qb; // q5-q8 grouped into float4's
  1105. float4 _qc; // q9-q12 for more convenient access.
  1106. float4 _qd; // q13-q16
  1107. float4 _qe; // q17-q20
  1108. float4 _qf; // q21-q24
  1109. float4 _qg; // q25-q28
  1110. float4 _qh; // q29-q32
  1111. float blur1_min // these are the values of the min/max
  1112. float blur1_max // allowable color values for the 3 blur passes,
  1113. float blur2_min // as set from the onscreen menus.
  1114. float blur2_max // more info below.
  1115. float blur3_min //
  1116. float blur3_max //
  1117. // note/warning: in general, don't use the current time value
  1118. // as an input to the *dynamic* rotations; as time gets large,
  1119. // the results will become total chaos.
  1120. float4x3 rot_s1; // four random, static rotations.
  1121. float4x3 rot_s2; // randomized @ preset load time.
  1122. float4x3 rot_s3; // minor translation component (<1).
  1123. float4x3 rot_s4;
  1124. float4x3 rot_d1; // four random, slowly changing rotations.
  1125. float4x3 rot_d2;
  1126. float4x3 rot_d3;
  1127. float4x3 rot_d4;
  1128. float4x3 rot_f1; // faster-changing.
  1129. float4x3 rot_f2;
  1130. float4x3 rot_f3;
  1131. float4x3 rot_f4;
  1132. float4x3 rot_vf1; // very-fast-changing.
  1133. float4x3 rot_vf2;
  1134. float4x3 rot_vf3;
  1135. float4x3 rot_vf4;
  1136. float4x3 rot_uf1; // ultra-fast-changing.
  1137. float4x3 rot_uf2;
  1138. float4x3 rot_uf3;
  1139. float4x3 rot_uf4;
  1140. float4x3 rot_rand1; // random every frame
  1141. float4x3 rot_rand2;
  1142. float4x3 rot_rand3;
  1143. float4x3 rot_rand4;
  1144. <A NAME="3f8">
  1145. <B>TEXTURE SAMPLING</B>
  1146. ----------------
  1147. We've already used one texture: the internal canvas, also called "Main".
  1148. Because it's always being used, you don't have to declare it. You can
  1149. just sample it. However, you have some options for how to sample it.
  1150. There are four samplers tied to the Main canvas:
  1151. BEHAVIOR OUTSIDE
  1152. SAMPLER NAME FILTERING METHOD [0..1] UV RANGE
  1153. ------------ ---------------- ----------------
  1154. sampler_fw_main* bilinear filtering wrap
  1155. sampler_fc_main bilinear filtering clamp
  1156. sampler_pw_main point sampling wrap
  1157. sampler_pc_main point sampling clamp
  1158. * you can also just use "sampler_main" for this one,
  1159. since it's by far the most common.
  1160. When you go to sample a texture, the GPU finds the exact spot
  1161. in the texture that the UV coordinates point to. The chances
  1162. are good that it falls in between 4 texels (pixels) rather than
  1163. perfectly on one of them. If you use bilinear filtering to
  1164. sample, it will return a properly-weighted average of the four
  1165. pixels. If you use point sampling, it will just return the
  1166. nearest single pixel (also called "nearest neighbor").
  1167. Wrap vs. clamp is also pretty simple: if you specify a UV coord
  1168. of float2(-0.1, 0.5), the wrap mode would map this to (0.9, 0.5),
  1169. while the clamp mode would clamp it at (0.0, 0.5). Wrap mode
  1170. tends to create tiled images, while clamp mode takes the border
  1171. color and extends it out infinitely.
  1172. In general, other textures can be sampled similarly, using these
  1173. same two-letter prefixes ("_fw", "_pc", etc.). Or, you can
  1174. always just leave off the prefix, and MilkDrop will assume you
  1175. want to do "_fw" - bilinear filtering and wrap mode - the defaults.
  1176. <A NAME="3f9">
  1177. <B>MILKDROP'S BUILT-IN TEXTURES - MAIN, BLUR, and NOISE</B>
  1178. ----------------------------------------------------
  1179. MilkDrop has several built-in textures you can sample from.
  1180. MAIN
  1181. ----
  1182. First, there is the Main texture (the internal canvas). As already
  1183. mentioned, you can sample from it by using sampler_main or one
  1184. of its variants.
  1185. <A NAME="3f9b">
  1186. BLUR1, BLUR2, BLUR3
  1187. -------------------
  1188. Next, there are several blurred versions of the main texture.
  1189. These are called Blur1, Blur2, and Blur3. Each one is
  1190. progressively blurrier. You can access them using these special
  1191. functions:
  1192. GetBlur1(uv) // these take a float2 as input
  1193. GetBlur2(uv) // & return a float3 color value
  1194. GetBlur3(uv)
  1195. GetBlur1 returns a slightly blurred image, GetBlur2 a more blurry image,
  1196. and GetBlur3 an extremely blurry image. A call to one of the GetBlur
  1197. functions is very fast, but keep in mind that the blur textures are only
  1198. generated each frame if the shaders actually use them, and the results
  1199. find their way into the final output color value of the pixel shader!
  1200. Blur1 is the fastest to generate; then Blur2 (because it is generated
  1201. from Blur1); and finally, Blur3 is the slowest (generated from Blur2).
  1202. Here is an example of how to use one:
  1203. float3 blurry = GetBlur2(uv);
  1204. You could add this to your sample from the Main texture to
  1205. produce a softer-looking image, for example. Or, you could
  1206. do an edge detect in the composite shader, by taking the
  1207. [absolute value of the] difference between the crisp and blurred
  1208. main textures:
  1209. float3 crisp = tex2D(sampler_main, uv).xyz;
  1210. float3 blurry = GetBlur1(uv);
  1211. ret = abs( crisp - blurry )*4;
  1212. The "skin dots" effect in some of the presets (it makes spots
  1213. and stripes like you might see on fish or leopards, in nature)
  1214. is based on a very mild edge-detect in the *warp* shader,
  1215. and uses it to enforce a certain amount of variance in the
  1216. color values. It also serves to break up large areas of solid
  1217. white pixels.
  1218. Note that you can do some cool glow effects by raising the
  1219. "min" values above 0. Say, for example, you set blur1_min
  1220. to 0.5. That means that any pixels with color values below
  1221. 0.5 will get clipped to 0.5. So, when you call GetBlur1(),
  1222. it's going to give you values in the range [0.5 .. 1.0].
  1223. However, because you were only using half the range of possible
  1224. values, the precision of these values will be twice as good.
  1225. That's the purpose of the min/max values. Watch out, though -
  1226. having your values clipped to a minimum of 0.5 would look bad
  1227. if you actually had colors that are over 0.5, and you're not
  1228. subtracting that 0.5 off.
  1229. However, if you do set a min and then subtract it off, you can
  1230. also get some great glow effects, where only really
  1231. bright pixels contribute to the "glow" If you set the min to
  1232. 0.7, for example, and then sample like this:
  1233. ret += (GetBlur1(uv) - blur1_min)*2;
  1234. It will subtract off the 0.7 minimum threshold, but because
  1235. of the clipping, you will basically just see the bright
  1236. pixels "glowing". The *2 is just for a little extra glow.
  1237. <A NAME="3f9c">
  1238. <B>NOISE TEXTURES</B>
  1239. --------------
  1240. There are also "noise" (random value) textures built in to MilkDrop.
  1241. They are generated when MilkDrop starts, but only so the large amount
  1242. of (random) data wouldn't bloat the size of the MilkDrop download.
  1243. They vary in the quality (smoothness) of the noise, as well as
  1244. how often the pattern repeats itself. Always use the smallest
  1245. possible noise texture (_lite or _lq versions) when possible.
  1246. Here are the details on the six textures:
  1247. NAME DIMS PIXELS QUALITY
  1248. ---- ---- ------ ---------
  1249. noise_lq 2D 256x256 low
  1250. noise_lq_lite 2D 32x32 low
  1251. noise_mq 2D 64x64 medium
  1252. noise_hq 2D 32x32 high
  1253. noisevol_lq 3D 32x32x32 low
  1254. noisevol_hq 3D 8x8x8 high
  1255. Notice that four of them are two-dimensional (use tex2D(float2 uv)
  1256. to sample them), and two of them are three-dimensional (use
  1257. tex3D(float3 uvw) to sample them).
  1258. They come in at various sizes. You should always use the smallest
  1259. one necessary, to be video memory cache-friendly!
  1260. The _lq, _mq, and _hq suffixes denote low, medium, or high quality.
  1261. The _lq textures have one random value at every texel in the
  1262. texture. But the _mq textures have (generally) about four texels
  1263. per random value, with high-quality [cubic] filtering baked into the
  1264. texture. (Sometimes you just want something better than bilinear
  1265. filtering, you know?) The high-quality textures usually have about
  1266. 8 texels for every random value. The sizes given here, in pixels,
  1267. are actually abstractions - they are the conceptual # of pixels
  1268. (values) before repetition. In reality, the textures are bigger
  1269. (for medium & high quality), and the extra texels are all filled
  1270. in using high-quality interpolation.
  1271. The higher-quality textures aren't any slower to use, as long as
  1272. you're sampling them at the right frequency. If you sample any
  1273. of these at too high a frequency (i.e. tile them like crazy /
  1274. multiply the UV's by a large number) your video memory texture
  1275. cache will bring your GPU to a grinding halt. Don't do it!
  1276. If using Noise textures with the default sampler settings (filtering
  1277. and wrap), you don't need to declare them above the shader_body; they
  1278. are always available. However, if you want to sample them with
  1279. special options (clamping or point sampling), then you do have to.
  1280. (ex: "sampler sampler_fc_noise_lq", or "sampler_pw_noise_lq").
  1281. To sample a color value from a noise texture, add code like this:
  1282. float4 noiseVal = tex2D(sampler_noise_lq, uv_orig );
  1283. This returns a float4 of values in the [0..1] range. However, the noise
  1284. image will be stretched up so the 64x64 pixels cover the screen. What we'd
  1285. really like is to tile it so the noise values map 1:1 to pixels on the
  1286. screen.
  1287. To do this, we need to invoke another handy feature: you can fetch the size
  1288. of any texture in MilkDrop. Just declare a float4 (still outside the shader
  1289. body) with the name of the texture, preceded by "texsize_" - like this:
  1290. float4 texsize_noise_lq; // .xy = (w,h); .zw = (1/(float)w, 1/(float)h)
  1291. Also, recall that the size of the Main canvas is universally available to
  1292. all shaders, and looks like this: (this is auto-declared for you, by the way)
  1293. float4 texsize // .xy = (w,h); .zw = (1/(float)w, 1/(float)h)
  1294. So, if we change our sampling code to look like this:
  1295. float4 noiseVal = tex2D(sampler_noise_lq, uv_orig*texsize.xy*texsize_noise_lq.zw );
  1296. It's going to do exactly that. This is a very common and useful technique.
  1297. uv_orig gives you the original (unwarped)
  1298. UV coordinates [0..1]. If we then multiply by texsize.xy, we get the
  1299. pixel number we are on. For example, if the screen was 1280 x 1024 pixels,
  1300. we'd get float2 in the range [0..1279, 0..1023]. If we then multiply by
  1301. texsize_noise_lq.zw, we're dividing by the size of the noise texture,
  1302. in pixels (this one is 256x256). So, we'd end up with UV coords roughly
  1303. in the range [0..5, 0..4] - our image has been perfect tiled onto the
  1304. screen, with the pixels displaying 1:1.
  1305. This can be used to mix a bit of random noise into the image each frame,
  1306. which can increase image quality - it's similar to error diffusion
  1307. dithering (which is one of the things that set the original Geiss
  1308. plugin/screensaver apart from the others, image-quality wise!). You
  1309. can ponder the reasons why. Also, further adding "rand_frame.xy" to the
  1310. UV coords will reposition the noise values every frame, making it seem
  1311. like truly random [changing] noise:
  1312. float2 noise_uv = uv_orig*texsize.xy*texsize_noise_lq.zw + rand_frame.xy;
  1313. float4 noiseVal = tex2D(sampler_noise_lq, noise_uv);
  1314. To add random dithering (which, statistically, is the same as error-
  1315. diffusion dithering), try this:
  1316. float2 uv_noise = uv_orig*texsize.xy*texsize_noise_lq.zw + rand_frame.xy;
  1317. half4 noiseVal = tex2D(sampler_noise_lq, uv_noise);
  1318. ret = tex2D(sampler_main, uv);
  1319. ret += (noiseVal.xyz*2-1) * 0.01;
  1320. This will add a good deal of noise into the image each frame. Adding
  1321. 'rand_frame.xy' to the UV coordinate serves to randomly place
  1322. the noise texture each frame, preventing the noise imprint from being
  1323. exactly the same each frame, which would cause artifact buildup.
  1324. Important: Note that the medium- and high-quality textures should never be
  1325. used for 1:1 mapping! - it is a huge waste. You will only benefit from their
  1326. higher quality if you are *zoomed in* on these textures, seeing them
  1327. magnified, sampling them at a low frequency. If they are minified
  1328. (sampled at a high frequency / zoomed out of) or even displayed at 1:1,
  1329. you will thrash your video memory cache and the preset will run very
  1330. slow.
  1331. <A NAME="3f9d">
  1332. <B>READING TEXTURES FROM DISK</B>
  1333. --------------------------
  1334. Declaring and sampling from your own textures is easy. First,
  1335. create your texture. If you plan on sharing your presets with
  1336. other people, please make your texture SMALL (256x256 or less)
  1337. and save it as a JPG file at 95% quality. The file size should
  1338. be between 10k and 50k (kilobytes). Of course, the textures
  1339. could be huge, crisp photos if you want - they will just be
  1340. heavy (to send to other people) and will cause a little delay
  1341. when you switch to a preset that uses them (and loads the texture).
  1342. Save the texture to the folder:
  1343. c:\program files\winamp\plugins\milkdrop2\textures
  1344. or wherever you installed Winamp and MilkDrop to. Let's imagine
  1345. you called your texture billy.jpg.
  1346. Then, in any shader, above the shader_body section, declare a sampler
  1347. for the texture:
  1348. sampler sampler_billy;
  1349. That's all you have to do. It will find the file (billy.jpg)
  1350. and load it. Note that the sampler name DOES have to start with
  1351. "sampler_", and if you want, you could prefix it with "sampler_pc_"
  1352. or "sampler_fw_" (or whatever) to turn on texture clamp and/or point
  1353. sampling.
  1354. Texture formats supported include: [in order of priority]
  1355. <FONT COLOR="green">
  1356. jpg (great compression)
  1357. dds (a microsoft/directx format - very flexible - can even do 3D)
  1358. png (portable network graphics; can give you compress w/an alpha channel)
  1359. tga (truevision Targa - 1, 3, or 4 channels)
  1360. bmp (puke)
  1361. dib (puke)
  1362. </FONT>
  1363. Now that you've declared the texture, you can sample it like this,
  1364. from within the shader_body section:
  1365. float3 mypixel = tex2D(sampler_billy, uv2).xyz;
  1366. So first it will try to find billy.jpg; then billy.dds; and so
  1367. on, until it finds a valid texture. If the texture can not be
  1368. found in the "milkdrop2\textures" directory, it will then also try
  1369. to find it **in the current preset directory**; this is done so that
  1370. preset downloaders can be lazy and just put the presets, along
  1371. with the textures that come with them, into the same directory.
  1372. If your shader wants to know how big the texture is, declare this
  1373. (also above the shader_body section):
  1374. float4 texsize_billy; // .xy = (w,h); .zw = (1/w, 1/h)
  1375. MilkDrop will see the "texsize_" prefix and automatically know what
  1376. to do. (You don't have to include the //comment, of course.)
  1377. To stretch this texture to cover the screen, do this (in the shader
  1378. body):
  1379. ret = tex2D(sampler_billy, uv).xyz;
  1380. Or to map it fitted to the screen, aspect-aware:
  1381. ret = tex2D(sampler_billy, uv * aspect.xy).xyz;
  1382. Or to tile it so the pixels are represented 1:1:
  1383. ret = tex2D(sampler_billy, uv * texsize.xy * texsize_billy.zw).xyz;
  1384. Or to map it tiled exactly 5 times:
  1385. ret = tex2D(sampler_billy, uv * 5).xyz;
  1386. Or to zoom into the center 20% of the image:
  1387. ret = tex2D(sampler_billy, (uv-0.5)*0.2 + 0.5 ).xyz;
  1388. Of course, you could also declare sampler_pw_billy, to do point
  1389. sampling, or sampler_fc_billy, for clamping, and so on.
  1390. <A NAME="3f9e">
  1391. <B>RANDOM TEXTURE SELECTION</B>
  1392. ------------------------
  1393. You can also load in a random texture. Just use the name "rand00"
  1394. through "rand15" as the filename, and MilkDrop will pick a random
  1395. file and do the rest. The texsize_ parameters work too. For example:
  1396. sampler sampler_rand07;
  1397. float4 texsize_rand07;
  1398. shader_body
  1399. {
  1400. ...
  1401. float3 color = tex2D(sampler_rand07, uv);
  1402. ...
  1403. }
  1404. You can also choose from random subsets of textures on disk! Say you
  1405. have a whole slew of random textures in your textures\ subdirectory,
  1406. but you have a subset in there that begin with the word "smalltiled".
  1407. If you specify:
  1408. sampler sampler_rand02_smalltiled;
  1409. float4 texsize_rand02; // ...it's smart enough to get it from just this.
  1410. shader_body
  1411. {
  1412. ...
  1413. float3 color = tex2D(sampler_rand07_smalltiled, uv);
  1414. ...
  1415. }
  1416. Then every time the preset loads (or the shader is recompiled), it's
  1417. going to pick a new random texture, but it will choose only from the
  1418. subset of those textures whose names begin with "smalltiled".
  1419. One last thing, a tip: if you are working in windowed mode (or multimon)
  1420. and added textures to the directory and haven't yet exited the plugin,
  1421. to force the list of textures to update itself, edit one of the shaders
  1422. (any shader) and then hit CTRL+ENTER (accept). That will trigger it
  1423. to rescan the directory (but only if it needs to, because your shaders
  1424. ask for random textures).
  1425. <A NAME="3f10">
  1426. <B>MISC. COOL SHADER TRICKS</B>
  1427. ------------------------
  1428. AUTO CENTER DARKENING
  1429. ---------------------
  1430. MilkDrop 1 had a cool feature, "center darken", that would quickly dampen
  1431. bright pixels placed at the center of the screen, because in "zoomy"
  1432. (forward motion) presets, the screen would quickly become all white
  1433. if you didn't. As presets get more sophisticated, though, where the
  1434. "center" of the zooming motion is can be very hard to pinpoint.
  1435. You can actually find it algorithmically. Wherever on the screen you
  1436. have warped UV coordinates that are very close to the original UV
  1437. coordinates, it means there's either no motion there, or it's the
  1438. center of motion - you'll know, based on what kind of preset you're
  1439. writing. If it's a "zoomy" preset, it's probably the latter. In this
  1440. case, just use something like this in your warp shader:
  1441. // this darkens the pixels at the center of the zoom, only
  1442. ret *= 0.97 + 0.03*saturate( length(uv - uv_orig)*200 );
  1443. RANDOM DIFFUSION DITHER
  1444. -----------------------
  1445. See above, in the "noise" section.
  1446. SOFT MAX
  1447. --------
  1448. The max(a,b) function returns the max. value for each channel
  1449. of the two inputs, however, this can have a discontinuous
  1450. look sometimes, as it switches from a to b or back suddenly.
  1451. If you want a not-so-accurate, but smoother, max function,
  1452. try this:
  1453. a + b - a*b
  1454. Note that the inputs must be in the [0..1] range.
  1455. <A NAME="3f11">
  1456. <B>QUALITY ASSURANCE FOR SHADERS</B>
  1457. -----------------------------
  1458. *Please* adhere to these guidelines when writing shaders...
  1459. 1. use small (256x256 or less) textures; save as jpg 95%
  1460. -so your presets are small to download, and so they load w/o a pause.
  1461. 2. make sure your shaders are zippy.
  1462. -avoid 'if' statements.
  1463. -avoid "massive zoom-outs" of any texture. Sampling textures at too
  1464. high a frequency thrashes your texture cache and will drop your
  1465. framerate like mad. Sample things near 1:1, or feel free to zoom
  1466. in close on them, but avoid extreme zoom-outs.
  1467. -avoid sin() and cos() functions if you can. If their inputs don't
  1468. vary from pixel to pixel, calculate the sin/cos values in
  1469. the per-frame equations, then store them in q1-q32, and read
  1470. them into your shader from there.
  1471. -any calculation that results in the same value for all pixels
  1472. on the screen should be offloaded into MilkDrop's per-frame
  1473. equations, then passed to the shader via the q1-q32 variables.
  1474. These variables are directly accessible from all shaders (q1,
  1475. q2, etc.) and can also be read in as float4's for convenience
  1476. (q1-q4 make up a float4 called _qa; q5-q8 come together in _qb;
  1477. etc.).
  1478. -also avoid doing motion/warping calculations in the warp shader,
  1479. that you could do in the per-vertex equations. Those run on the
  1480. CPU, which is a huge resource that is almost never completely
  1481. used; the GPU, although processing 1,000 times as much math
  1482. because it works per-pixel instead of per-vertex, can use as
  1483. much of a break as it can get. Any low-frequency effects (values
  1484. that vary slowly over the screen) should go in the per-vertex
  1485. equations, and only the high-frequency component of the motion
  1486. or warping should come from the pixel shader.
  1487. -keep in mind that the DirectX shader compiler is superb at
  1488. optimizing; anything that can be thrown out, will be. Things like
  1489. ret *= 1.0;
  1490. ret += 0;
  1491. ret += tex2D(mytex, uv).xyz * 0;
  1492. will completely disappear. If you sample a texture and then the
  1493. sample doesn't end up making it into the final output color value,
  1494. the texture will never even get bound (or loaded from disk),
  1495. let alone sampled. And so on.
  1496. -you can use the 'half' type wherever you don't need full 'float'
  1497. precision. Generally use 'float' for UVs and time values, and
  1498. 'half' for almost everything else. However, don't stress about it
  1499. too much, because most GPUs run
  1500. everything at full-precision & full-speed nowadays - and for the
  1501. older GPUs that don't, the driver is probably very smart (if it's
  1502. an Nvidia or ATI card) about auto-substituting halfs for floats
  1503. wherever possible.
  1504. 3. before sharing your presets, please make sure they look good in a
  1505. SQUARE or WIDESCREEN window. If they don't, scan these guidelines
  1506. and you will probably be able to easily fix it.
  1507. The overall design goal in MilkDrop, concerning aspect ratio, is to
  1508. fit the preset to the long axis of the window, and to crop the rest,
  1509. but to do all of this without any stretching or zooming (so all internal
  1510. canvas pixels map 1:1 to screen pixels).
  1511. -per-frame/per-vertex equations:
  1512. * multiply XY coords by the values "aspectx" and "aspecty", respectively.
  1513. -shader code:
  1514. * multiply UV coordinates by 'aspect.xy', prior to using them
  1515. to sample a texture, to make the texture fit on the screen properly.
  1516. (For example, if the screen is wide, the image will be fitted to cover
  1517. the width of the screen, and it will be cropped at the top and bottom.)
  1518. * multiply by 'aspect.zw' to make it fit the other way (it will fit
  1519. the image to be completely visible in one dimension, and tiled in the
  1520. other direction).
  1521. * any time you perturb the UV coordinates in the warp shader, prior to
  1522. sampling the Main texture, you should multiply the "delta" you are applying
  1523. by aspect.xy. Otherwise, in a widescreen window, the "delta" will actually
  1524. be dramatically squished, or in a tall window, the change would be
  1525. elongated very vertically.
  1526. * the 'ang' value is aspect-aware, in the per-vertex equations, as well
  1527. as in the warp and composite shaders. However, if you generate your own
  1528. high-quality "ang" value using atan2(), beware - you really
  1529. should multiply the UV's by aspect.xy beforehand, like this:
  1530. float2 uv2 = (uv-0.5)*aspect.xy;
  1531. float ang = atan2(uv2.y,uv2.x);
  1532. <A NAME="3g">
  1533. <B>g. QUALITY ASSURANCE</B>
  1534. ----------------------
  1535. When designing presets, please adhere to the pixel shader 'quality assurance'
  1536. guidelines in the above section, as they are very important. But, in order
  1537. to make sure the presets you create work well on other systems, please
  1538. also keep in mind:
  1539. 1. Keep your presets fast. There's nothing to spoil the mood like
  1540. a preset popping up that chokes at 10 fps. Since division is 11
  1541. times slower than multiplication (or addition/subtraction), if you
  1542. divide a bunch of values by one other value, pre-divide that value
  1543. ("inv = 1/myval;") and then multiply those other values by that
  1544. inverse. Also, never put computations in the per-vertex code that
  1545. are the same for every pixel; move these into the per-frame code,
  1546. and carry the results to the per-vertex code using the q1-q32 variables.
  1547. Remember that maxim: "If a per-vertex equation doesn't use at least
  1548. one of the variables { x, y, rad, ang }, then it should be actually
  1549. be a per-frame equation."
  1550. 2. Design your presets using the default mesh size option
  1551. from the config panel, or at least check, before you distribute them,
  1552. to make sure they look correct at the default mesh size. If your
  1553. mesh is too coarse (small), then a viewer with the default mesh size
  1554. might see unexpected "bonus" effects that you might not have intended,
  1555. and might mess up your preset. If your mesh is too fine, then a
  1556. viewer with the default might not see all the detail you intended,
  1557. and it might look bad.
  1558. 2. Try to design your presets in a 32-bit video mode, so that its
  1559. brightness levels are standard. The thing to really watch out
  1560. for is designing your presets in 16-bit color when the "fix pink/
  1561. white color saturation artifact" checkbox is checked. This
  1562. checkbox keeps the image extra dark to avoid color saturation,
  1563. which is only necessary on some cards, in 16-bit color. If this
  1564. is the case for you, and you write a preset, then when you run
  1565. it on another machine, it might appear insanely bright.
  1566. 3. Don't underestimate the power of the 'dx' and 'dy' parameters
  1567. (in the per-vertex equations). Some of the best presets are based
  1568. on using these. If you strip everything out of a preset so that
  1569. there's no motion at all, then you can use the dx and dy parameters
  1570. to have precise manual control over the motion. Basically, all the
  1571. other effects (zoom, warp, rot, etc.) are just complicated
  1572. abstractions; they could all be simulated by using only { x, y,
  1573. rad, ang } and { dx, dy }.
  1574. 4. If you use the 'progress' variable in a preset, make sure you
  1575. try the preset out with several values for 'Time Between Auto
  1576. Preset Changes'. The biggest thing to avoid is using something
  1577. like sin(progress), since the rate at which 'progress' increases
  1578. can vary drastically from system to system, dependong on the user's
  1579. setting for 'Time Between Auto Preset Changes'.
  1580. 5. if writing shaders, please also see the 'Quality Assurance for
  1581. Shaders' section above.
  1582. <A NAME="3h">
  1583. <B>h. DEBUGGING</B>
  1584. -----------------------
  1585. One feature that preset authors should definitely be aware of is the
  1586. variable monitoring feature, which lets you monitor (watch) the value
  1587. of any per-frame variable you like. First, hit the 'N' key to show
  1588. the monitor value, which will probably display zero. Then all you
  1589. have to do is add a line like this to the per-frame equations:
  1590. monitor = x;
  1591. where 'x' is the variable or expression you want to monitor. Once you
  1592. hit CTRL+ENTER to accept the changes, you should see the value of the
  1593. per-frame variable or expression in the upper-right corner of the
  1594. screen!
  1595. Once again, note that it only works for *per-frame* equations, and NOT
  1596. for per-vertex equations.
  1597. <A NAME="3i">
  1598. <B>i. FUNCTION REFERENCE</B>
  1599. -----------------------
  1600. Following is a list of the functions supported by the expression evaluator
  1601. (for preset init, per-frame, and per-vertex equations; NOT for pixel shaders).
  1602. The list was blatently ripped from the help box of Justin Frankels' AVS
  1603. plug-in, since MilkDrop uses the expression evaluator that he wrote.
  1604. Format your expressions using a semicolon (;) to delimit between statements.
  1605. Use parenthesis ['(' and ')'] to denote precedence if you are unsure.
  1606. The following operators are available:
  1607. = : assign
  1608. +,-,/,* : plus, minus, divide, multiply
  1609. | : convert to integer, and do bitwise or
  1610. & : convert to integer, and do bitwise and
  1611. % : convert to integer, and get remainder
  1612. The following functions are available:
  1613. int(var) : returns the integer value of 'var' (rounds toward zero)
  1614. abs(var) : returns the absolute value of var
  1615. sin(var) : returns the sine of the angle var (expressed in radians)
  1616. cos(var) : returns the cosine of the angle var
  1617. tan(var) : returns the tangent of the angle var
  1618. asin(var) : returns the arcsine of var
  1619. acos(var) : returns the arccosine of var
  1620. atan(var) : returns the arctangent of var
  1621. sqr(var) : returns the square of var
  1622. sqrt(var) : returns the square root of var
  1623. pow(var,var2) : returns var to the power of var2
  1624. log(var) : returns the log base e of var
  1625. log10(var) : returns the log base 10 of var
  1626. sign(var) : returns the sign of var or 0
  1627. min(var,var2) : returns the smalest value
  1628. max(var,var2) : returns the greatest value
  1629. sigmoid(var,var2) : returns sigmoid function value of x=var (var2=constraint)
  1630. rand(var) : returns a random integer modulo 'var'; e.g. rand(4) will return 0, 1, 2, or 3.
  1631. bor(var,var2) : boolean or, returns 1 if var or var2 is != 0
  1632. bnot(var) : boolean not, returns 1 if var == 0 or 0 if var != 0
  1633. if(cond,vartrue,varfalse) : if condition is nonzero, returns valtrue, otherwise returns valfalse
  1634. equal(var,var2) : returns 1 if var = var2, else 0
  1635. above(var,var2) : returns 1 if var > var2, else 0
  1636. below(var,var2) : returns 1 if var < var2, else 0
  1637. <A HREF="#milkdrop_preset_authoring_top">return to top</A>
  1638. <A HREF="milkdrop.html">return to milkdrop.html</A>
  1639. </PRE>
  1640. </BODY>
  1641. </HTML>