So I’ve made this procedural tile texture and the whole time I’ve been looking at it in Eevee assuming it would look the same in Cycles as I dont believe i’ve used any Eevee specific techniques. The problem is that the pattern I have created is wrong when rendered in Cycles, here are two screenshots to demonstrate the problem:
Thats interesting.I have rebuild this test and get this GPU artifacts too.Is it a bug, or lack of GPU calculation precision?
If its lack in precision,why other procedural shader builds dont show such artifacts?
Maybe a CPU/GPU detection in the Nodes would select a more render device fitting algorithm would fix the bug?
From what I can see… the semi-* don’t need clamping in the Add node, and the diagonals* don’t need the Power node…
The rest looks ok.
I could look further to check what is causing the precision errors, but I’ve to leave that to the weekend.
Yes,have tryed that too,get artifacts with modulo CPU OSL.I am not sure this is a known expected/wanted result.Then this (and with the test before) might be causes many maybe tiny little renderbugs.Maybe with normal mapping and other vector related tasks.
Maybe worth a bug report?
edit,did a quick test.warp and snap producing artifacts too,with OSL and GPU,snap is not that visible though.
The problem of using functions that aren’t continuous (mod, snap, ==, etc), is that they will likely produce these artifacts when your input values are of floating point types.
These artifacts are expected whenever you are near the discontinuities of the resulted function, because at that point the value is too ambiguous to be calculated correctly (by any processor).
IMHO, this is not a blender bug, but a limitation of logical arithmetics (which are used in both CPU’s and GPUs).
This isn’t a bug. If you try to report it, the best case scenario is that devs figure out your node groups and then get irritated and close the issue. The problem is that you’re operating with undefined values.
What is 0^-1? This is like saying, 1/0. But there’s no such thing as division by zero.
And you get that with your power nodes, operating on the output of clamped add nodes.
Yes, different architecture handles impossible operations like this differently. One architecture might be capable of expressing it as NAN. Another architecture might just say, screw it, I’m calling that zero. Another architecture might just return whatever happened to be in memory at the time. None of those are wrong answers, because there is no right answer. (Well, maybe NAN is the right answer, but not everything supports NAN. And in any case, NAN just means, “Uhh, there isn’t an answer.”)
Now, it is pretty interesting that you get different output from a clamped Add node outputting 0 than you do from an explicit value node outputting 0 on GPU rendering. Why? Maybe tiny imprecisions, I don’t know. (Wait, I might be wrong about that part.)
If you want to do this right, then you need explicit “code” to handle the impossible situation of taking the -1 power of 0.
A floating point is something that is used to ‘encode’ (represent) arbitrarily different ranges/scales into a fixed pack of bits.
How to ‘encode’ them and perform operations with them is something specific to each compiler (and gpus or special processors have their own compilers). They are complied to give the same results within a certain (established minimal) error…
But making further operations on the previous ‘sligthly incorrect’ result will cascade into total different error.
Like: the hit point of a ray in a triangle’s surface, that will be multiplied by a matrix, a dot product after it, squareroot, then still add -0.5 and 1/sqr(res) with it…
And this sequence of operations is one of the culprits in this thread’s problem.