Archive for September, 2008

Varyingness vs variable tagging

Bwain| No Comments »

I’ve got a single output bit field that specifies the output parameter. I use this for tagging variables as I go along, and to propagate varyingness. This works for everything except ‘mov’ ‘=’. mov does NOT propagate varyingness, but it certainly needs to be taken into account for tagging. Maybe we need two bit fields, one for output flow, and another for varyingness??

Still, this assembly level varyingness propagation is working well. I’ve gotten through about 5 shader code examples, they all work pretty well. Even some of the ‘for’ loop examples work.

Ok, FUCK IT!!! I already got the logic working with the varyingness defined at compile time. This is turning out to take way too much time. I can be done, I see the path, but its kind of a diversion at this point. Doing to put the code back to the way it was and move on….  The good news is that both modes of varyingness calculation are optional. You can specify varying at compile time, or calculate it at render time. I can go back to it if necessary. The API is the same.

Ultrafractal file type decoding

Bwain| No Comments »

Under the Formula’s directory, we have (ufm, ucl, uxf, upr, txt) file types.

  • ufm,frm - Fractal formulas
  • uxf - Transformation formulas
  • ucl - Color formulas. These are iterated along with the pixel
  • upr - Parameter files. Seems to contain all the parameters for a full render. When you do a Copy on the main window, it grabs all the parameters, which you can save out as text into a .upr file.
  • ufr - Fractal file - contains the parameters (like a upr), but also the entire rendered state, pixels and everything. You can restart an old render by loading in a ufr.
  • ugr - Gradient file.

On page 262 of UF402.pdf, there is a breakdown of the formula file format. Page 300 has pseudocode for the entire execution path. Good info.

For writing fractal formals, there are the following sections, (in order). If there is no label, (init) is assumed. An empty label (:) assumes the start of the loop section, in which case, the last expression is a boolean for the bailout condition. This last condition is for Fractint compatibility.

  • global - executed only once per image.
  • builtin - points to an internal formula.
  • init - executed once per pixel
  • loop - executed once per iteration
  • bailout - contains a single boolean expression. Loop executes until bailout = false
  • default - contains parameters
  • switch - can be used to switch between julia/mandelbrot formulas

Coloring Algorithms. If there is no label, it assumes the ‘final’ tag. Some of the formulas can only be INSIDE or OUTSIDE coloring algorithms. They’re usually specified in the title.

  • global - executed once per image
  • init - executed once per pixel
  • loop - executed once per iteration, right after the ‘loop’ section of the fractal formula. It can look at the current value of #z.
  • final - executed after the bailout has been acheived. Calculates an lookup into the gradient by writing to #index, which is a normalized floating point value. Other lut transformations are done after this. You can create a direct color algorithm by writing to #color instead of #index.
  • default - parameter blocks

Transformation Formulas: If a transformation doesn’t start with a label, it assumed ‘transform’ label by default.

  • global - executed once per image
  • transform - reads #pixel does a transformation on it, then writes #pixel
  • default - parameters

Each default section can have a parameter definition, and it can also set defaults for the following parameters.

  • angle - (float) orientation of view
  • center - (complex) center of view
  • helpfile -
  • helptopic
  • magn - (float) zoom
  • maxiter - (int) max iterations
  • method - (enum) {onepass, multipass, guessing}
  • periodicity - (enum) { off, conservative, normal, rough }
  • precision
  • render
  • skew
  • stretch
  • title - (string) title of render

For a first pass, I need a plugin to find all the relevant formula files and suck them in.

The expressions are obviously recursively parsed, but the file format is not. There are no semicolons, no brackets. As far as I can tell, there is only one expression per line. So writing a parser by hand is an option. This could also make my life easier, especially since I don’t have to re-purpose the existing shading language grammar.  I can even re-use the Cmd classes for holding the compiled results, probably read them all in on startup.

We’ll have a menu plugin, (the first menu plugin!) It allows to specify a list of directories, which are scanned for the appropriate files. (Or, to start, we can have it just do one file). The directories (or files) are stored in a statefile (like 123.cmd), and is rescanned on startup. What this plugin does is keep a library of fractal and color files, which can be accessed by a client later.

Plug-in architecture

Bwain| No Comments »

The only reason I’m calling this a plugin is because I’m having the client extend the application menu. Some necessary things:

  • Need to be able to save parameters to places other than the node heirarchy. We can have a repository to keep plugins, objects and their parameters. Just name it /plug or something. The objects aren’t created by the user, they get created on startup.

I’ve made a new Node type called Plugin. They all have only one instance each, and they get created at bootstrap time. Upon creation, they have the option of adding custom menus and modifying MainWin. What’s nice about this is that it encapulates parameters nicely, plus it will be easy to make active GUI controls for them.

We will be needing two plugins, one to create the fractal formula repository, another for reading in a parameter file for initializing nodes.

I’ve got a plugin that takes a directory and scans the formulas and their subsections. So at least, it can recognize their top level file structure. It took a bit of time to scan through all the formulas. I might consider just keeping pointers to formulas, and compile them when needed. Don’t know how much memory it will take to keep all compiled formulas in ram at once. Both are options.

Uf Formula Parsing

Bwain| No Comments »

The order of the sections doesn’t define variables as they’re being used. (Conveniently enough….) For all formula types, the first parse the default section (if it exists) to get the variable defaults and the parameter definitions that will be used for the formula.

Apparantly, there are some predefined symbols that I have to provide. Also just found out that ‘#’ is optional. It also appears that the symbols are not case sensitive.

  • #angle - float - returns view angle
  • #calculationPurpose - int 0-3
    • 0 - rendering to a fractal window
    • 1 - thumbnail render
    • 2 - rendering to disk
    • 3  - rendering a preview for the formula browser
  • #center - complex - center of the view
  • #color - color - write only in the final: section of coloring algorithms.  Direct coloring algorithms return a color here. Its initialized to black. Can’t write to #color and #index in the same algorithm.
  • #e - float - returns exp(1).
  • #height - int - height of image in pixels
  • #index - (float) - write only, in the final: section of coloring algorithms. 0-1 is a lookup into the gradient. Initialized to zero.
  • #magn - (float) - returns the view magnification
  • #maxiter - (int) - returns maxIterations in the formula tab
  • #numiter - (int) - readable only in the final: section of a coloring algorithm.
  • #pi - (float) - pi
  • #pixel - (complex) - readable, except in global: sections. Writeable in transformation formulas.
  • #random - (complex) - readable, except in global: sections. Returns a per pixel random complex number. The random value is from 0-1.
  • #randomrange - (float) - largest size of random(seed) + 1. random(seed)/#randomrange will return a float from (-1 .. 1)
  • #screenmax - (complex) screen size in a complex number. (#width, #height i )
  • #screenpixel - (complex) screen pixel in a complex number. Readable except in a global: section.
  • #skew - (float) - I think its the #angle in radians.
  • #solid - (bool) - not readable. Writeable only in transformation formulas, and in the final: section of coloring algorithms. Allows for the final value to be a user defined solid color instead of assigning #color or #index.
  • #stretch - (float) - returns the stretch factor for the view.
  • #whitesq - (bool) - readable except in global sections - Returns true if the x+y pixel positions returns an even number. So it creates a boolean checkerboard over the image.
  • #x - (int) - readable except in global sections - returns the x pixel position.
  • #y - (int) - readable execept in global sections - returns the y pixel position
  • #z - (complex) - readable in fractal formulas and coloring algorithms - writeable in fractal formulas
  • #z, #Z - the complex value being iterated. This value is tracked for periodicity checking.

Predefined functions

  • int random(seed) - churns an integer. its a not unsigned!, full range from -#randomrange to #randomrange
  • complex flip(complex)  - transposes real and imaginary parts
  • bool isInf(float) - returns true if input is INF.
  • bool isNan(float) - returns true if input is NAN
  • int length(a) - returns the length of a dynamic array. (yikes…)
  • complex oldz(int) - Used to index the entire history of z. deprecated.
  • print(anything) - prints to stdout.
  • setLength(a) - sets the length of a dynamic array.

Turns out the ultrafractal can do classes, and dynamic arrays.. wow.

uf grammar issues

Bwain| No Comments »

I’ve spent the last few days implementing complex numbers in the shading language, constructors, operators, and ways to combine it with existing data types.

An issue that’s come up with the Ultrafractal grammar is that they initialize complex numbers with floats and ints, and (num, num). For starters, we have to have the expression grammar recognize (num, num) as a native complex number.  More generally, we need to be able to define user defined equality assignment translators between different types. Its not enough that assignments be perfectly type-safe. The Uf grammar allows for this, so I guess I have to as well.

This (num, num) as a constructor for complex numbers is becoming a pain. I’m creating these expression stack errors, its not working as smoothly as I thought. The stack logic is kinda scattered, so its hard to debug in its current state. So I think I’m going to consolidate the stack stuff into its own class, centralize all its control. It should be easier to trace its behavior this way. Also will clean up the code a lot.

This diversion has given me a chance to clean up the stack code. Also, the existing parenthesis operator was kind of hacked together. It always should have been using the stack for evaluation. That’s working properly now. Also, the Spirit parser has a mechanism for doing issuing commands for cleanup when rules only partially are executed. This will help with the (expr, expr) constructor since its very similar to (expr).

Got (expr) and (expr, expr) working!!! The former is just a parenthesis operator, the latter is a complex operator. They both use the stack properly and can co-exist in the same grammar.

The next thing is to get assignments automatically working between different types. The one’s I see the most commonly are Complex = Int.

Got those working. Another feature I forgot to add was exponentiation. Things like 10^2 = 100, things like that. Logs and exponents are very important for fractals. Also, complex exponents, and complex logs. Found a formulation here and here. Adding them to the shading language now.

Some success

Bwain| No Comments »

I’m able to parse a minimal form of fractal formula files. When I tried to run it on the full formula directory, I found the remaining features that I needed to implement.

Some parameters return function names, which are called indirectly by the code. Very slick. I have to be able to implement this, which shouldn’t be a problem. A parameter can return any of the following functions, which means I also have to implement this in the shading language: sin, sinh, asin, asinh, cos, cosh, acos, acosh, tan, tanh, atan, atanh, cotan, cotanh, sqr, sqrt, log, exp, abs, cabs, conj, flip, ident, zero, recip, ceil, floor, trunc, round.

Fuck….. I can look up the trig functions for complex values, but I don’t know what ‘floor’ and ‘ceil’ are supposed to do with complex numbers. I supposed they just get executed on each component…..

Good reference for complex trancendental functions here. Complex asin and acos were kind of hard to find, but I found references here and here respectively. More here.

I implemented all the functions in the math library. Now I have to put in hooks for all of them in the expression library and the shading language. 29 complex functions in all. It should get done within a few days.

Also have to start thinking about how to deal with the indirect function calling. Have to modify the grammar to be able to handle things like  @funcName(z)  ,  @funcName(z, zz)  stuff like that. So basically, we have to be able to handle expression(expression). The first expression needs to be callable. This could be interesting, since constructors should be handled this way. Currently, Double() is a function, but it should be a proper constructor, parameterized by its type. Ctor could be a meta-object type, that takes a type (or a type string) as an argument. Then, when its called, it just preforms the constructor as a function.

So basically, I have to have the expression grammar be able to handle objects being callable, in addition to regular functions being callable. The spa::Value needs to have a mechanism for being able to resolve its own indirect function calls.

This is getting interesting. This feature would push the grammar to become more object oriented, as opposed to being strictly functional. It was on my to-do list, but I guess it has to happen sooner than later.

Another thing to consider is the dot operator. For doing things like object.method(). This would be calling a method on an object as opposed to just evaluating an object as a function. It would help to be able to see a c-grammar to see what precedence order the ‘.’ takes w.r.t. other operators.


Copyright © 2010 Luna-Canis | Created by miloIIIIVII
Top | Sidebar | Sitemap | Disclaimer | Network