Page MenuHome

Blender noise texture gives vertical stripe patterns
Closed, ResolvedPublic

Description

System Information

openSUSE 12.3 64bits
NVIDIA 480GTX SC
AMD FX-8350

Blender Version
Broken: a8705e9

Short description of error

Strange vertical stripe patterns coming from the noise texture

Exact steps for others to reproduce the error

Render this:

Event Timeline

Daniel Salazar (zanqdo) set Type to Bug.
Daniel Salazar (zanqdo) created this task.
Daniel Salazar (zanqdo) renamed this task from Blender noise texture gives vertical tripe patterns to Blender noise texture gives vertical stripe patterns.
Daniel Salazar (zanqdo) raised the priority of this task from to Needs Triage by Developer.

Yep, reproducable here on Win7/64, Blender 2.72. Problem seems to be there "forever", i.e. tried back to first 2.5 release. Don't know if it's a bug as I've never used a noise texture in the compositer yet.

It's noticable that the preview of the texture in the texture property section, if enlarged, doesn't show this behavior.

yes, confirmed here too. Ubuntu 14.04 64bit, blender 2.72 47b8bf5

Thomas Dinges (dingto) triaged this task as Confirmed, Medium priority.

Well, looks like the problem may be in the texnoise function of the render_texture.c file. This is from a commit by Ton in 2003. Here it is:

static int texnoise(Tex *tex, TexResult *texres)
{
	float div=3.0;
	int val, ran, loop;
	
	ran= BLI_rand();
	val= (ran & 3);
	
	loop= tex->noisedepth;
	while (loop--) {
		ran= (ran>>2);
		val*= (ran & 3);
		div*= 3.0f;
	}
	
	texres->tin= ((float)val)/div;

	BRICONT;
	return TEX_INT;
}

If you change texres->tin line to:

	texres->tin= BLI_frand();

Then you get actual noise and the lines go away.

As far as the part above with the loop, I don't really know why it was done like that. The noisedepth variable is always 2, as far as I can tell. Which means you only have a few values possible (0-3 * 0-3 * 0-3)/27, and a higher chance of getting darker values and pure black (1 in 4 chance I think), which you can see easily in the image produced by the noise. I can't think of why this part would make the lines, but I haven't dug into it more then this either.

To add a little more info, the lines only show up with certain render size X resolutions. At 1024 you get vertical lines, at 1023 you get diagonal lines, and at 1022 you get even more slanted lines. At a size of about 1000 I can't really see the lines anymore. At 512 and 2048 the lines show up again, with the same pattern of going away if you increment/decrement by 1 repeatedly.

The idea was to get noise with control over the noise "depth". It was to simulate a primitive sort of grain or digital camera noise.

Why this pattern happens i dunno, but the solution (replace with frand) is of course not a solution.
There might have been an optimization in our rand code? I don't think we had BLI_rand in 2003.

Checked - we did have BLI_rand() - no time to further investigate what happened there.

I have a feeling this problem is due to the use of the global random number generator (RNG) in the noise function. This is succeptible to re-seeding in other parts of the code. In this case i suspect the compositor or some other part of the code resets the RNG for each tile, line etc. This could lead to repetitive values in the noise function and give the stripe pattern. Another potential cause could be threading: the original RNG seed is a static variable, which starts at the same value for each compositor thread or so.

See this comparison of compositor noise with rendered noise - no stripes in render output using the same function:

Ideally random numbers in textures should use per-thread RNGs for consistency - but making this reliable and repeatable is not so easy, not least due to legacy design issues (no real texture instances for BI materials and other tex users). Might be best to file this under "todo" and recommend reliable cloud patterns etc instead, but will see if fiddling with random seed in the compositor helps.

Thanks @Antony Riakiotakis (psy-fi) I owe you another beer gawd dammit!

Hi psy-fi,

I'm a little confused about some parts of this commit for a couple of reasons.

First, the reason I suggested just using frand was that it gave the full value of the random number and it also provided even distribution of the values. Of course one of the problems with this is that it breaks old files. Meaning someone may have setup nodes or combinations of textures that expect the old formula and now when they open their file they get a different value weight of noise.

Your commit also significantly changes the value weight of the noise. In this case it's not even distribution like using the full random value or with a strong black weight like the old formula, but instead weights the values to grey, which you can see easily in the histogram. So this leaves me with questions. Was it not possible to just use the upper bits and the new random thread functionality but with the old formula so it didn't change old files? If it was intended to change the formula, why did you choose one that weights grey?

The second issue is just an implementation problem. In your commit you start the loop by getting the 31st and 32nd bits in the random number, but if you look in the random code implementation and comments you see that it only provides 31 bits. The 32nd bit is masked off I assume so that you always get positive numbers on signed ints. This gives a strange set of possible values ((0 to 7)/9) with your current formula, which you can see in this histogram.

To fix this just set shift to 29 instead of 30. This gives ((0 to 9)/9), which I think is what you intended and gives a histogram like this.

Lukas Toenne (lukastoenne) reopened this task as Open.

Yes, the old implementation may not be ideal, but changing the visual result should be avoided if possible. Reopening for investigation and assigning to @Antony Riakiotakis (psy-fi).

Thanks, I hadn't noticed that random used 31 bits, I'll recheck and also reuse the old multiplication formula to keep the old look if possible.

Fixed, thanks for doing the hard work here :)