Sun, Dec 22, 9:56 AM CST

Renderosity Forums / Poser - OFFICIAL



Welcome to the Poser - OFFICIAL Forum

Forum Coordinators: RedPhantom

Poser - OFFICIAL F.A.Q (Last Updated: 2024 Dec 20 7:20 am)



Subject: Matmatic question


kobaltkween ( ) posted Sun, 29 November 2009 at 7:20 AM · edited Sun, 22 December 2024 at 5:00 AM

does anyone have any idea how to build an equation that shiftes and transforms an input so that it fits a specified min and max?  a sort of f(min, max, input) = transformed and translated input.  i'm very sure this is possible, but i wouldn't even know where to begin.  i know it's possible, because it's basically the same thing the "Clouds" node for fbm: sets a floor color, a ceiling color, and calculates between them.    if any one knows how to make this equation, or even where to start, please let me know.  it would be helpful in tons of different situations.



bagginsbill ( ) posted Sun, 29 November 2009 at 10:01 AM · edited Sun, 29 November 2009 at 10:07 AM

Hmm. I really should finish my book. There is a pile of useful stuff like this in the chapters on BUF's, (Basic Unit Functions).

So here's a quick summary. Let's assume you have some control information as input, called "input", just as you said. Let's assume the range of values found in the input is 0 to 1 - what I call "the Unit". I'll show later what to do when your input is not in the unit.

OK. So, you would like to find a function (and therefore a node setup) that blends from one color (or number) to another, given the input from 0 to 1 (i.e. a unit input).

The Poser node that does that is the Blender node. Given two colors (or numbers - works either way), assuming they are c1 and c2, you simply write:

Blender(c1, c2, input)

For example, to get something like the Clouds node (where you have colors as outputs) applied to the fBm unit values:

input = fBm(... your fBm parameters here)
output = Blender(RED, BLUE, input)

Sometimes we do not have an input that is variable. Sometimes we just want to make a color by blending two colors, but it does not need to be dynamic. It can be calculated up front. For this, in matmatic, use the function "Blend" instead of "Blender". Blend is smart. If all the arguments are known at compile time, it will evaluate them and you have just a color. If any are dynamic or variable (i.e. they are nodes) then it will construct a Blender node instead.

For example:

Blend(RED, WHITE, .7) makes a pink color, not a Blender node.

But:

Blend(RED, WHITE, .7 * fBM()) makes a Blender node connected to an fBM node.

Or:

Blend(RED * fBM(), WHITE, .7) also makes a Blender node connected to an fBM node, but the fBm drives the luminance of the first color, not the blending factor.

The Blender node's blending argument (the third one) is automatically clamped, so that if you input is not in "the unit", the values outside "the unit" are forced to be in the unit. I.e., input < 0 becomes 0. Input > 1 becomes 1.

The math behind Blender is easy, and if we did not have a built-in node for it, we could make it like this:

def Blender(c1, c2, f): return (1-f) * c1 + f * c2

But we do not have to, as it is built in to Poser.

If you were to rearrange the math a bit, it is quite obvious how this works.

(1-f) * c1 + f * c2
== c1 - f * c1 + f * c2
== c1 + f * c2 - f * c1
== c1 + f * (c2 - c1)

Aha! Start with color #1 (c1) . Then take some fraction of the difference (c2 - c1) and add that to c1. When f is 0, you just get c1. When f is 1, you add all of the difference from c1 to c2, thus you get c2.

Finally, what if your input data is not in the range 0 to 1. Suppose it is some other bounded range, denoted by lo and hi. Then you can pre-condition the input before using it in the Blend, using a function very similar to the blend function itself, but the inverse of it.

unitInput = (input - lo) / (hi - lo)

For example, suppose you want input value .7 to be RED, 1.5 to be WHITE, and all in-between values interpolated accordingly.

Blend(RED, WHITE, (input - .7) / .8)

would take care of it.

There is a helper function in matmatic that does this. It is called Scale and is a little smarter than the scaling I did here.

To use it in this case I'd say:

Blend(RED, WHITE, Scale(input, .7, 1.5))

That says take the input, and transform the range .7 -> 1.5 into 0 -> 1.


Renderosity forum reply notifications are wonky. If I read a follow-up in a thread, but I don't myself reply, then notifications no longer happen AT ALL on that thread. So if I seem to be ignoring a question, that's why. (Updated September 23, 2019)


dlfurman ( ) posted Sun, 29 November 2009 at 12:11 PM

CRACKS WHIP!
Finish the book! :)

"Few are agreeable in conversation, because each thinks more of what he intends to say than that of what others are saying, and listens no more when he himself has a chance to speak." - Francois de la Rochefoucauld

Intel Core i7 920, 24GB RAM, GeForce GTX 1050 4GB video, 6TB HDD space
Poser 12: Inches (Poser(PC) user since 1 and the floppies/manual to prove it!)


kobaltkween ( ) posted Sun, 29 November 2009 at 1:59 PM

wow.  thanks so very much for explaining this, and doing so in a very straight forward and easy to follow way.

ah!  the Scale part of that is the one that eluded me.  for some reason i looked in the "Node Reference" under "Range" (i was just grasping at straws) but didn't try "Scale."  whoops, and looking at it now, i don't see it listed.  i realize it's not a node, but i was thinking that since Wood and Marble weren't precisely nodes, that was really just the API reference.

so, i guess my question is this: what if you don't know the values of "lo" and "hi".  that is, if you have some node and it's producing a range of numbers/colors, and you don't know the precise value it starts and ends on.  and what if "hi" and "lo" are colors rather than numbers?  that is, would it matter in terms of finding those values if you were working with grayscale output or not?  i'm thinking it woiuldn't, but it's always better to ask.



bagginsbill ( ) posted Sun, 29 November 2009 at 3:42 PM

Actually, Wood and Marble are precisely nodes. There are Poser nodes with those names. They are pretty much exactly not what I use to make wood and marble, but they are there and I documented them. I introduced additional functions to create much better wood and marble. These are discussed in the matmatic docs, particularly in WritingScriptsExtras.html. In there you will see images of marble, agate, wood, etc - lots of procedural patterns from nature.

"Scale" is not a node, it is a function I wrote that generates nodes. The matmatic node reference only lists actual Poser nodes. I discussed most of the functions in other places in the documentation. In particular, I talked a little about Scale (and Interpolate) in the file WritingScriptsFunctions.html.

If you don't know the range of values produced by a function, then there is no way to precisely transform that range into another range. But you can do experiments to measure what you're getting. For example, suppose you're trying to find what is the brightest value produced by the default FractalSum node. I might do something like this:

p = FractalSum()
s = Surface(0,0,0,0, Alternate_Diffuse = p <= .2)

This will show white wherever p is at or under .2. It will show black everywhere else. So if I see all black, everything is above .2. Then I might try p <= .7, p <= .8, p <= .88, p <= .884, etc. until I get all white - then I know there are no values above the one I tested. That gives me the upper bound. You can do a similar search for the lower bound.

You can also force values into a certain range through various mathematical tricks, like using functions with asymptotes.

For example, the function f(x) = x / (x + 1) is a function that never produces a value over 1 no matter how large x gets. Even if x is 50 billion, f(x) is extremely close to, but slightly less than 1.

I'm not suggesting that every situation admits to asymptotic functions as a solution, but some do. (Mapping HDR data to 8-bit RGB unit-range values, for example).

 


Renderosity forum reply notifications are wonky. If I read a follow-up in a thread, but I don't myself reply, then notifications no longer happen AT ALL on that thread. So if I seem to be ignoring a question, that's why. (Updated September 23, 2019)


bagginsbill ( ) posted Sun, 29 November 2009 at 3:45 PM · edited Sun, 29 November 2009 at 3:46 PM

In Poser, grayscale is a special case of color data, where R, G, and B are known to be identical.
In Poser, when you use colors as if they were numbers, it averages the three components to arrive at a number. Even if you're using really non-gray colors, this happens.

So, for example, if you have the gray-scale color, Color(.7, .7, .7), the numerical value of that as a number is (.7 + .7 + .7) / 3, which is .... tricky math here .... .7. LOL

Now you have to think carefully about things if you're really dealing with colors. Are you trying to do independent arithmetic on each color component of RGB, or are you trying to do simple arithmetic, and you happen to be using a grayscale image as collection of numbers?

I handle these differently. In particular, if an image is known to be just numbers (gray data), then I tell matmatic this by saying ImageMap("whatever.jpg").asNumber(). This will skip all the more expensive color math in any expression that consults this image.


Renderosity forum reply notifications are wonky. If I read a follow-up in a thread, but I don't myself reply, then notifications no longer happen AT ALL on that thread. So if I seem to be ignoring a question, that's why. (Updated September 23, 2019)


kobaltkween ( ) posted Sun, 29 November 2009 at 6:13 PM · edited Sun, 29 November 2009 at 6:14 PM

gotcha.  that's kind of what i was thinking in terms of grayscale vs. color, and i'd noticed the asNumber() trick, but i've been lazily relying on Matmatic to optimize so far and not considering ways i could optimize. 

so there's no function that would spit out the min or max of a result?  i was thinking that one would be obvious, but i just wasn't bright enough to figure out how to use math nodes to discover it.  i'm just thinking, it's not the function in the abstract, but an actual result set.   i feel like there must be a way to get the min and max from a result set.  but then, there's lots of things i feel should be possible and aren't.

thanks so much for your help.  you've explained a lot.



bagginsbill ( ) posted Sun, 29 November 2009 at 7:26 PM

It is not possible to write a shader that determines the min or max of a result.

It is possible to write a function, or more specifically a computer program could be written to sample the results of a function well enough to determine the min and max of a given result set. But there is the key - one must evaluate the entire result set, or close to it. A shader can only evaluate one point - the point it is being asked to shade. While the same shader seems to produce all possible values, in fact it is only producing one value and that is for the currently shaded point. To find the maximum of a million points, one must evaluate the shader at a million points. See the problem?

We could write a crapload of nodes that would allow a shader to evaluate something like fBm at points other than its own, but not enough to determine a global maximum and minimum.

However, when we are able to reason about a result set, then we can also reason about any manipulation of that result set that is deterministic. For example, if I happen to know that the max of a result set is .4, then I'm certain that 2 times that result set has a maximum of .8. This is no problem. Even more complicated things like Bias, Gain, all of these have easy ways to calculate the outcome for the domain of its input, and give us the range of its output.

But anything where we don't have a deterministic result, we cannot predict the value. For example, suppose we were to make two different Noise nodes and add them together. In theory, the maximum of the sum would be 1.0. But in fact, that would only happen if both nodes happened to produce a 1 at the same point. Suppose they never did? Suppose that behind the scenes there is some hidden coupling that means that this never actually happens? Then assuming the max is 2 would be incorrect. There's not a lot we can do about this, except to avoid using the non-deterministic nodes altogether.


Renderosity forum reply notifications are wonky. If I read a follow-up in a thread, but I don't myself reply, then notifications no longer happen AT ALL on that thread. So if I seem to be ignoring a question, that's why. (Updated September 23, 2019)


bagginsbill ( ) posted Sun, 29 November 2009 at 8:33 PM

Correction: Above I said about the maximum of two noise nodes added together, that the maximum of the sum would be 1.0. I meant to say 2.0.


Renderosity forum reply notifications are wonky. If I read a follow-up in a thread, but I don't myself reply, then notifications no longer happen AT ALL on that thread. So if I seem to be ignoring a question, that's why. (Updated September 23, 2019)


kobaltkween ( ) posted Mon, 30 November 2009 at 4:31 AM

right, right.  that makes sense.  even poking around the net a bit, i can see how you can't determine min or max without knowing something about the equation in the first place.  it was less that i was expecting magic than i feel like i don't properly understand some of the different types of Math nodes.  that is, i understand them sort of literally, but not in a more flexible,intuitive way.  well, and while i can follow explanations when you give them, the actual inventing process where you go from what you want to an equation to specific nodes, is completely opaque to me.  so i have much less idea of what is possible and what isn't than i should. 

i really appreciate you taking the time to write about all this.  i know you have lots of other stuff to do.



Privacy Notice

This site uses cookies to deliver the best experience. Our own cookies make user accounts and other features possible. Third-party cookies are used to display relevant ads and to analyze how Renderosity is used. By using our site, you acknowledge that you have read and understood our Terms of Service, including our Cookie Policy and our Privacy Policy.