html 生成image java makenoise,利用随机噪声生成纹理 Texture Generation using Random Noise A D V E R T I S E M E N...

In nature, everything has a random look, while mathematical formulas typically don't generate random looking results, unless you use them well. Random noise, such asPerlin noise invented by Ken Perlin, uses random numbers to generate natural looking textures.

Smooth Noise

As source for the random noise we need an array of random values, called noise[x][y]. Since our interest is generating 2D textures, a 2D array is used. The function generateNoise will fill the array with noise, and the main function is programmed to show this noise array on the screen. The noise itself is generated with the rand() function from the header file, this function returns a random integer value between 0 and 32768 (as defined in the header file). It's normalized to a random real number between 0 and 1 by dividing it through 32768.0 (make sure to use floating point division).

#define noiseWidth 128

#define noiseHeight 128

double noise[noiseWidth][noiseHeight]; //the noise array

void generateNoise();

int main(int argc, char *argv[])

{

screen(noiseWidth, noiseHeight, 0, "Random Noise");

generateNoise();

ColorRGB color;

for(int x = 0; x < w; x++)

for(int y = 0; y < h; y++)

{

color.r = color.g = color.b = Uint8(256 * noise[x][y]);

pset(x, y, color);

}

redraw();

sleep();

return 0;

}

void generateNoise()

{

for (int x = 0; x < noiseWidth; x++)

for (int y = 0; y < noiseHeight; y++)

{

noise[x][y] = (rand() % 32768) / 32768.0;

}

}

Here's the noise it generates:

0818b9ca8b590ca3270a3433284dd417.png

This noise doesn't look very natural however, especially if you zoom in. Zoom in by dividing the x and y used to call the noise array through 8, in the pixel loop of the main function. You get something blocky:

color.r = color.g = color.b = Uint8(256 * noise[x / 8][y / 8]);

pset(x, y, color);

When zooming in, we want something smoother. For that, linear interpolation can be used. Currently the noise is an array and it's got only a discrete set of integer indices pointing to it's contents. By using bilinear interpolation on the fractional part, you can make it smoother. For that, a new function, smoothNoise, is introduced:

double smoothNoise(double x, double y)

{

//get fractional part of x and y

double fractX = x - int(x);

double fractY = y - int(y);

//wrap around

int x1 = (int(x) + noiseWidth) % noiseWidth;

int y1 = (int(y) + noiseHeight) % noiseHeight;

//neighbor values

int x2 = (x1 + noiseWidth - 1) % noiseWidth;

int y2 = (y1 + noiseHeight - 1) % noiseHeight;

//smooth the noise with bilinear interpolation

double value = 0.0;

value += fractX * fractY * noise[x1][y1];

value += fractX * (1 - fractY) * noise[x1][y2];

value += (1 - fractX) * fractY * noise[x2][y1];

value += (1 - fractX) * (1 - fractY) * noise[x2][y2];

return value;

}

The returned value is the weighed average of 4 neighboring pixels of the array. In the main function, now use this instead of directly calling the noise array, and use real numbers for the division:

color.r = color.g = color.b = Uint8(256 * smoothNoise(x / 8.0, y / 8.0));

pset(x, y, color);

This is again the result zoomed in 8 times, but now with the bilinear interpolation. If you don't zoom in you won't be able to see the interpolation:

0818b9ca8b590ca3270a3433284dd417.png

This is quite useful for random noise, the smoothing method could be better maybe, bilinear interpolation is often used by 3D cards for smoothing textures in games as a cheap and fast technique.

Let's call this image a "noise texture".

Turbulence

Turbulence is what creates natural looking features out of smoothed noise. The trick is to add multiple noise textures of different zooming scales together. An example of how this represents nature can be found in a mountain range: there are very large features (the main mountains), they are very deeply zoomed in noise.

0818b9ca8b590ca3270a3433284dd417.png

Then added to the mountains are smaller features: multiple tops, variations in the slope, ...

0818b9ca8b590ca3270a3433284dd417.png

Then, at an even smaller scale, there are rocks on the mountains.

0818b9ca8b590ca3270a3433284dd417.png

An even smaller layer is the grains of sand. Together, the sum of all these layers forms natural looking mountains.

In 2D, this is done by adding different sizes of the smoothed noise together.

0818b9ca8b590ca3270a3433284dd417.png

The zooming factor started at 16 here, and is divided through two each time. Keep doing this until the zooming factor is 1. The small features in the mountain example weren't only smaller in the width, but also in the height. To achieve this in 2D textures, make the images with a smaller zoom darker, so adding them will have less effect:

0818b9ca8b590ca3270a3433284dd417.png

By adding these 5 images together, and dividing the result through 5 to get the average, you get a turbulence texture:

0818b9ca8b590ca3270a3433284dd417.png

Here's a function that'll automaticly do all this for a single pixel. The parameter "size" is the initial zoom factor, which was 16 in the example above. The return value is normalized so that it'll be a number between 0 and 255.

double turbulence(double x, double y, double size)

{

double value = 0.0, initialSize = size;

while(size >= 1)

{

value += smoothNoise(x / size, y / size) * size;

size /= 2.0;

}

return(128.0 * value / initialSize);

}

To use the turbulence function, change the small part of the code in the loop that goes through every pixel by the following:

color.r = color.g = color.b = Uint8(turbulence(x, y, 64));

pset(x, y, color);

The size is set to 64 there, and the result looks like this:

0818b9ca8b590ca3270a3433284dd417.png

If you set the initial size to 256 instead, the result is much bigger and smoother:

0818b9ca8b590ca3270a3433284dd417.png

And here's a very small initial size of only 8:

0818b9ca8b590ca3270a3433284dd417.png

The textures here have some obvious horizontal and vertical lines because of the bilinear filter smooth function. The Clouds filter in

Photoshop generates a texture similar to the ones above, but with a nicer smooth function. Nicer smooth functions are beyond the scope of this article though.

If you use no smooth function at all, it looks like this:

0818b9ca8b590ca3270a3433284dd417.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值