MaterialX
MaterialX copied to clipboard
Integer support for the basic Math nodes.
It would be good to take a pass at improving the integer support in MaterialX's math nodes. Having these low-level building-blocks would improve the types of nodegraphs that can be expressed.
Node | Input | Output |
---|---|---|
Add | integer, integer | integer |
Add | integer, float | integer |
Subtract | integer, integer | integer |
Subtract | integer, float | integer |
Multiply | integer, integer | integer |
Multiply | Integer, float | integer |
Divide | integer, integer | integer |
Divide | integer, float | integer |
Min | integer, integer | integer |
Max | integer, integer | integer |
I'm not sure if there are other options necessary. Or if we need to do things like Vector (I) signatures...
I would disagree with having e.g. an "Add" with integer and float inputs, and certainly with having that combination produce an integer output. Instead, I would suggest we only have same-type inputs and outputs for the nodes themselves, and refine the "auto convert" logic to insert conversion nodes (int to float "convert", or "floor(float) with int output") when someone wants to connect a different type to an input, similar in concept to what we do with swizzle/extract or colorspace-convert on input.
Not sure about how useful integer vector types would be- do you have any use cases in mind?
Thanks @dbsmythe - that all makes sense. The integer-vector types was more about vec3 * int cases - and only for the sake of completeness. If the math nodes only supported integer inputs and outputs, that's perfectly fine by me. As you pointed out, (in the future) integer-aware floor
and ceil
, along with future round
can take care of float-to-int cases.
I'd like to propose integer variants for these as well:
- modulo
- sign
- clamp What do you think ?
Another suggestion is to have integer separate
and combine
, otherwise I think the graph will need to use N float->int , and int->float converts to work on vector individual components and put them back into the original vector. Just a thought.
This isn't specifically a justification for integer vector types, but thinking out loud on the justification for integer types in general. The general justification for integer types would be support chained integer computations whose intermediate results can't be exactly expressed with a floating point operation.
as an example
(int) (16777216.f + 1.f)
is 16777216.f
since the float mantissa can only hold 24 bits.
For a realistic example, let's say I have a 4k texture, 4096 x 4096 and I want to make some calculation on specific elements, perhaps my texture is stored in a linear array of floats, 4096x4096x4 elements long. 4096 x 4096 is 16777216, x 4 is 67108864. In i32, 67108864 + 1 is 6710885, in f32 it is 67108864. Even if surrounding context is f32, and I end the calculation with a divide by 4096x4 to get an exact f32 line number within the texture, it's important that before I go back to f32 that the intervening calculations are exact.
This is a marginally contrived example, but it is easy to come up with examples where exact values after intermediate calculations DO fit into floating point values, but the intermediate calculations DO NOT fit into floating point values. I picked the 4k texture indexing example to demonstrate that values we encounter daily easily suffer from inexactness in an f32.
So the strong argument for supporting integer types is to enable exact math to a greater degree than is possible with strictly f32 values.
Algebraic shenanigans would be the alternative to using i32 in my example, but such shenanigans are not in principal generally available to keep exactness in the f32 realm.
I wonder if this gives any ideas for justifying vector types?
Linking this issue to the recent work from @ld-kerley on #1777 and #1786.