Subversion Repositories filter_foundry

Compare Revisions

Regard whitespace Rev 143 → Rev 144

/trunk/Filter Factory Compatibility.txt
51,43 → 51,13
-------------------
 
Filter Foundry's implementation of rst(i) (undocumented function that sets the seed for the PRG)
differs from the implementation of Filter Factory.
and rnd(a,b) (generate random number between a and b, inclusively)
differs from the implementation of Filter Factory in many ways.
 
1. In Filter Foundry, the function rnd(a,b) retrieves a random number at realtime; therefore, if the
seed is changed via rst(i), there is an immediate effect on the next call of the rnd(a,b) function.
For example, following filter would generate an one-colored picture without any randomness:
R=rst(123), rnd(0,255)
G=rnd(0,255)
B=rnd(0,255)
1. In Filter Foundry, the random seed is automatically initialized with seed 691204.
In Filter Factory, the random seed is automatically initialized with seed 0.
 
In Filter Factory, the rnd(a,b) function is more complex.
(The analysis of Filter Factory's rnd and rst function is not yet completed, so
following notes might not be 100% accurate.)
It seems like there is a buffer with 56 random integers that will be refilled regularly.
The rst(i) function seems to change the seed for the next batch of random numbers,
so there is not immediate effect on the rnd() calls.
 
2. Furthermore, it seems like in Filter Factory, if rst(i) is called multiple times
with the same argument, there will be no effect.
So, while following filter would generate random vertical bars in Filter Foundry,
it would generate a picture with random pixels in Filter Factory:
R=(x==0) ? rst(123) : 0, rnd(0,255)
G=0
B=0
In Filter Foundry, every call of rst(i) will perform an update of the seed.
So, if you like to have a random-pixel picture with a specific seed,
you must make sure that rst(i) will only be called once.
You would need to write your filter like this
R=(x==0 && y==0) ? rst(123) : 0, rnd(0,255)
G=0
B=0
if you want generate a similar result as Filter Factory outputs with the filter
R=rst(123), rnd(0,255)
G=0
B=0
 
3. In Filter Foundry, the argument i of the function rst(i) is limited to the
2. In Filter Foundry, the argument i of the function rst(i) is limited to the
type "unsigned int" (argument of the function srand() in the C StdLib),
so the allowed range is 0..4294967295.
 
95,10 → 65,79
If the argument is not within this range, the operation "and 0x7FFF" will be applied to it
to extract the low 15 bits.
 
3. In Filter Foundry, the function rnd(a,b) retrieves a random number at realtime; therefore, if the
seed is changed via rst(i), there is an immediate effect on the next call of the rnd(a,b) function.
For example, following filter would generate an one-colored picture without any randomness:
R: rst(123), rnd(0,255)
G: rnd(0,255)
B: rnd(0,255)
If you want to generate a random pixel image with a non-default seed, you need to make sure
that rst(i) is called only once at the beginning (channel 0, coordinate 0|0):
R: (x==0 && y==0) ? rst(123) : 0, rnd(0,255)
G: rnd(0,255)
B: rnd(0,255)
 
In Filter Factory, the rnd(a,b) function is more complex.
As soon as the function rnd(a,b) is used once, rst(i) will not have any effect.
So, if you want to use rst(i), you must make sure to call it before using rnd(a,b).
Following filter will generate a random pixel picture:
R: rst(123), rnd(0,255)
G: rnd(0,255)
B: rnd(0,255)
Following filter would generate a different random pixel picture:
R: rst(456), rnd(0,255)
G: rnd(0,255)
B: rnd(0,255)
Following filter would generate the same random pixel picture:
R: rst(456), rnd(0,255)+rst(123) <-- note that rst() always returns 0, so the '+' operator is OK
G: rnd(0,255)
B: rnd(0,255)+rst(456) <-- the last rst(456) call is to mitigate a bug; see below.
 
4. In Filter Factory, due to a bug, the random state is not reset to its initial state (0) before the filter is applied:
The preview image processing will modify the random state, and once the filter is actually applied (pressing "OK"),
the random state that was set in the preview picture, will be used.
Example:
R: rnd(0,255), rst(123) <-- note that the rst(123) is ignored because rnd() was already called.
G: rnd(0,255)
B: rnd(0,255)
This filter will produce a random pixel picture with the initial default random seed 0,
but only for the first calculation (i.e. in the preview picture processing, or in a standalone filter without dialog).
Any further calculation will result in a random pixel picture with random seed 123,
since the random seed 123 will be taken from the previous run.
 
Furthermore, the random state can't be changed again, not even at the beginning of the red channel before any rnd() call.
Example:
R: rst(333), rnd(0,255)
G: rnd(0,255)
B: rnd(0,255)+rst(555)
This filter will produce a picture with random seed 333 on the first calculation,
and at every further calculation, a random picture with seed 555.
Another example:
R: rst(ctl(0)), rnd(0,255)
G: rnd(0,255)
B: rnd(0,255)+rst(555)
In this filter, the slider value is ignored and the resulting picture will always be the same.
 
 
Evaluation of conditional branches
----------------------------------
 
Filter Foundry:
Only the branches which will be chosen due to the conditional expression will be evaluated.
This means that following filter would generate a black canvas: (Testcase conditional_eval_1.afs)
R: 1==0 ? put(255,0) : 0
G: get(0)
B: 0
In boolean expressions, the evaluation will be aborted if the result is already determined.
So, this will also generate a black canvas: (Testcase conditional_eval_2.afs)
R: 1==0 && put(255,0) ? 0: 0
G: get(0)
B: 0
This will also generate a black canvas: (Testcase conditional_eval_3.afs)
R: 1==1 || put(255,0) ? 0 : 0
G: get(0)
B: 0
 
Filter Factory:
Each branch inside a if-then-else expression will be evaluated.
This means that following filter would generate a green canvas: (Testcase conditional_eval_1.afs)
105,25 → 144,12
R : 1==0 ? put(255,0) : 0
G : get(0)
B : 0
A : 255
Also, all arguments of an boolean expression will be fully evaluated.
So, this will also generate a green canvas: (Testcase conditional_eval_2.afs)
R : 1==0 && put(255,0) ? 0: 0
G : get(0)
B : 0
A : 255
 
Filter Foundry:
Only the branches which will be chosen due to the conditional expression will be evaluated.
This means that following filter would generate a black canvas: (Testcase conditional_eval_1.afs)
R : 1==0 ? put(255,0) : 0
This will also generate a green canvas: (Testcase conditional_eval_3.afs)
R: 1==1 || put(255,0) ? 0 : 0
G : get(0)
B : 0
A : 255
In boolean expressions, the evaluation will be aborted if the result is already determined.
So, this will also generate a black canvas: (Testcase conditional_eval_2.afs)
R : 1==0 && put(255,0) ? 0: 0
G : get(0)
B : 0
A : 255