Noise

However using a RNG (random number generator) to add variation to the appearance of a 3D object isn't sufficient. Random patterns we can observe in nature are usually smooth. Two points on the surface of a real object usually look almost the same when they are fairly close to each other. But two points on the surface of a same object which are far apart can look very different. In other words local changes are gradual, while global changes can be large. RNG do not have this property. Every time we call them they return numbers which are not related (uncorrelated) to each other. Therefore calling this function is likely to produce two very different numbers. This would be unsuitable for introducing a slight variation to the visual appearance of two points that are spatially close.

The conclusion of this experiment is that to create a smooth random pattern, we need to assign random values at fixed position on a grid which we call a lattice (in our example the grid corresponds to the pixel locations of our 10x10 input image) using a RNG, and blur these values using something equivalent to a gaussian blur (a smoothing function to blur these random values). In the next chapter we will show you how this can be implemented. But for now all you need to remember is that noise (within the context of computer graphics) is a function that blurs random values generated on a grid (which we often refer to as a lattice).

Properties of an Ideal Noise

  • Noise is pseudo-random and this is probably its main property. It looks random but is deterministic. Given the same input, it always returns the same value. If you render a image for a film several times, you want to noise pattern to be consistent/predictable. Or if you apply this noise pattern to a plane for example, you want that pattern to stay the same from frame to frame (even if the camera moves or the plane is transformed. The pattern sticks to the plane. We say that the function is invariant: it doesn't change under transformations).
  • It takes a n-dimensional point with real coordinates as input and returns a float.
  • the noise function is potentially made of multiple frequencies (low frequencies account for large scale changes, high frequencies account for small changes). But one of these frequencies dominates all the others. And this one frequency defines both the visual and frequency (if you look at your signal in frequency space) appearance/characteristic of your noise function. When the noise is small in frame (imaging an object textured with noise far away from the camera) it becomes white noise again which is a cause of what we call in our jargon, aliasing.

When successive layers of a fractal noise have an amplitude which is inversely proportional to their frequency, the term used to describe the result is pink noise. If we formalize this in a formula we could write:

float pinkNoise = 0; 
static const unsigned numlayer = 5; 
float rateOfChange = 2.0f; 
for (unsigned i = 0; i < numLayers; ++i) 
{ 
    // change in frequency and amplitude
    pinkNoise += noise(P * pow(rateOfChange, i)) / pow(rateOfChange, i); 
} 

The term "layer" is more generic than "octave" . An "octave" is used in a program (or in literature) it should mean that each successive layer in the computation of a fractal sum is twice the frequency of the previous layer. If the frequency ratio between successive layers is different than 2, the use of this term"octave" is inaccurate and "layer" should be used instead. When we double the frequency between layers and that the amplitude of these layers is inversely proportional to their frequency, we obtain a special type of pink noise which we call Brownian noise (named after the mathematician Robert Brown).

In the generic form of the fBm function, the amplitude of a layer doesn't have to be inversionaly proportional to its frequency. You can use two different values to control how the frequency and the amplitude change between layers. The word lacunarity is used to control the rate by which the frequency changes from layer to layer.There is no special word for the rate of change in the amplitude from layer to layer. We will be using gain in the following pseudo-code of an fBm function:

float fBm(Vec3f P, float lacunarity = 2, float gain = 0.5, int numLayers = 5) 
{ 
    float noiseSum = 0; 
    Vec3f Pnoise = P; 
    float amplitude = 1; 
    for (unsigned i = 0; i < numLayers; ++i) 
    { 
        // change in frequency and amplitude
        noiseSum += noise(Pnoise) * amplitude; 
        Pnoise *= lacunarity; 
        amplitude *= gain; 
    } 
    return noiseSum; 
} 

Turbulence is a function built on the same principle as the fractal sum. However instead of using the noise function directly for each layer, we will use the absolute value of the signed noise.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值