Voronoi texture cells biased towards mapping coordinates
Closed, ArchivedPublic


System Information

Blender Version
Broken: 2.78a

Short description of error

When subtracting (.5, .5, .5) from the output of a high frequency Voronoi cell texture, a pattern which looks suspiciously like the input coordinates emerges:

This *might* be related to the rather unexpected tendency for Voronoi-cell-modified-normals to cause square reflections of round light sources when used in a glossy shader.
The two phenomena occur together, but beyond that I have no idea why either happens or why one would cause the other.

Exact steps for others to reproduce the error

  1. Open
  2. Switch to rendered viewport shading
  3. Take note of pattern which appears to correspond to input coordinates (takes a fare number of samples to really become apparent)
  4. Connect glossy shader output to material surface input.
  5. Note the "square" reflection of the round sun lamp.



Related Objects

Sergey Sharybin (sergey) triaged this task as Confirmed priority.Feb 16 2017, 5:59 PM
Sergey Sharybin (sergey) claimed this task.

While this isn't really a bug but like a limitation of current hashing function this is an interesting phenomena to investigate.

Think correlation is coming from the order of coordinate components we use to hash r, g and b components:

x, y, z
y, x, z
y, z, x

Would need to plot our hash() function to see if there's something intrinsicly wrong in there, but such a quick experiment solves the correlation issue:

1diff --git a/intern/cycles/kernel/svm/svm_noise.h b/intern/cycles/kernel/svm/svm_noise.h
2index 3f75ae5c04e..71cfaf2134f 100644
3--- a/intern/cycles/kernel/svm/svm_noise.h
4+++ b/intern/cycles/kernel/svm/svm_noise.h
5@@ -316,9 +316,9 @@ ccl_device_noinline float cellnoise(float3 p)
7​ ccl_device float3 cellnoise_color(float3 p)
8​ {
9- float r = cellnoise(p);
10- float g = cellnoise(make_float3(p.y, p.x, p.z));
11- float b = cellnoise(make_float3(p.y, p.z, p.x));
12+ float r = cellnoise(make_float3(p.y, p.x, p.z*p.y));
13+ float g = cellnoise(make_float3(p.y*p.x, p.x, p.z));
14+ float b = cellnoise(make_float3(p.y, p.z*p.y, p.x));
16​ return make_float3(r, g, b);
17​ }

Note that patch is only working on GPU, CPU would need SSE-optimized version.

That's the math aspect of the issue. Now let's talk about practical aspect. Don't really think Voronoi was intended to have same randomness entropy as a white noise and if you need white noise just use a dedicated function for that. Surely solving correlation issues will be nice, but that's not possible without changing behavior of the voronoi noise. Which means, it'll break all existing files which are using this texture.

Maybe we can do it in 2.8 branch, but only if it's indeed something important to solve.

@Brecht Van Lommel (brecht), wouldn't mind hearing your opinion on this issue.

Perhaps changing the order to this helps? So there is no repetition in the rows or columns.

x, y, z
z, x, y
y, z, x

Whatever solves the issue, seems ok to fix in 2.8.

Not sure diverging from what OSL is doing is that good of an idea, even for 2.8, We either have to re-implement cellnoise+Voronoi in osl scripts which will be significantly slower, or patch osl while we're building it to keep consistent results between SVM and OSL. Is it really a problem worth solving?

@Brecht Van Lommel (brecht), woops. After days of bugfix hunting didn't think of such a simple shuffle :) Seems promising since that's simple to implement on SSE.

@LazyDodo (LazyDodo), not sure why that would diverge for OSL. We just need to update kernel/shaders/node_texture.h. OSL does not implement Voronoi on their side.

My bad, i could have sworn we used the internal noise functions from osl. I stand corrected.

Maybe we can do it in 2.8 branch, but only if it's indeed something important to solve.

My particular use-case is using detailed voronoi cells to modify normals to simulate aluminum flakes in car paint

@LazyDodo (LazyDodo), we use noise while voronoi is a "wrapper" on top noise. That being said, we use perlin noise from OS for example.

@Ellwood Zwovic (gandalf3), why not to use regular noise if the scale to be so small?

@Brecht Van Lommel (brecht), tested that shuffle patch from you. Unfortunately, it does not solve the issue. So guess our noise() function isn't really good in terms doesn't give nice distribution when shuffling arguments around. This is still to be confirmed tho. Will give it a deeper later.

@Sergey Sharybin (sergey), it is easier to get distinct faces using the vorinoi texture. Using noise often results in less distinct pieces. Further, for certain camera angles the scale is not as small as one might believe. Some paints have pretty large flecks.

Sergey Sharybin (sergey) closed this task as Archived.Feb 27 2017, 5:05 PM

Was trying various things here. The cell-noise itself is not biased by the looks of it, and in fact it matches implementation from OIIO/OSL. it is something combined with the way how we do cells and then hashing the coordinate which gives distribution issues.

Since there is no way to fix that without introducing regressions and because it's not a bug in implementation considering it a TODO for 2.8 projects there: https://wiki.blender.org/index.php/Dev:Source/Render/Cycles/ToDo

@GiantCowFIlms, doubt you'll see bias with larger flecks tbh.