﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-酱坛子-文章分类-2. 3D渲染</title><link>http://www.cppblog.com/sunraiing9/category/1807.html</link><description>专注C++技术  在这里写下自己的学习心得 感悟 
和大家讨论 共同进步（欢迎批评！！！）</description><language>zh-cn</language><lastBuildDate>Tue, 20 May 2008 21:01:01 GMT</lastBuildDate><pubDate>Tue, 20 May 2008 21:01:01 GMT</pubDate><ttl>60</ttl><item><title>Perlin Noise(摘)</title><link>http://www.cppblog.com/sunraiing9/articles/13738.html</link><dc:creator>@王一伟</dc:creator><author>@王一伟</author><pubDate>Mon, 16 Oct 2006 00:40:00 GMT</pubDate><guid>http://www.cppblog.com/sunraiing9/articles/13738.html</guid><wfw:comment>http://www.cppblog.com/sunraiing9/comments/13738.html</wfw:comment><comments>http://www.cppblog.com/sunraiing9/articles/13738.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunraiing9/comments/commentRss/13738.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunraiing9/services/trackbacks/13738.html</trackback:ping><description><![CDATA[
		<center>
				<h1>Perlin Noise</h1>
		</center>
		<hr />
		<p>
		</p>
		<dd>Many people have used random number generators in their programs to create unpredictability, make the motion and behavior of objects appear more natural, or generate textures. Random number generators certainly have their uses, but at times their output can be too harsh to appear natural. This article will present a function which has a very wide range of uses, more than I can think of, but basically anywhere where you need something to look natural in origin. What's more it's output can easily be tailored to suit your needs. 
<p></p></dd>
		<dd>If you look at many things in nature, you will notice that they are fractal. They have various levels of detail. A common example is the outline of a mountain range. It contains large variations in height (the mountains), medium variations (hills), small variations (boulders), tiny variations (stones) . . . you could go on. Look at almost anything: the distribution of patchy grass on a field, waves in the sea, the movements of an ant, the movement of branches of a tree, patterns in marble, winds. All these phenomena exhibit the same pattern of large and small variations. The Perlin Noise function recreates this by simply adding up noisy functions at a range of different scales. 
<p></p></dd>
		<dd>To create a Perlin noise function, you will need two things, a Noise Function, and an Interpolation Function. 
<p><font size="+2">Introduction To Noise Functions</font></p></dd>
		<dd>A noise function is essentially a seeded random number generator. It takes an integer as a parameter, and returns a random number based on that parameter. If you pass it the same parameter twice, it produces the same number twice. It is very important that it behaves in this way, otherwise the Perlin function will simply produce nonsense. 
<p></p><table><tbody><tr><td><img height="135" src="http://freespace.virgin.net/hugo.elias/models/noise1.gif" width="284" /><p></p></td><td></td></tr></tbody><dd>Here is a graph showing an example noise function. A random value between 0 and 1 is assigned to every point on the X axis. <br /><p></p></dd></table><table><tbody><tr><td><img height="139" src="http://freespace.virgin.net/hugo.elias/models/noise2.gif" width="289" /><p></p></td><td></td></tr></tbody><dd>By smoothly interpolating between the values, we can define a continuous function that takes a non-integer as a parameter. I will discuss various ways of interpolating the values later in this article.<br /></dd></table><p><font size="+2">Definitions</font></p></dd>
		<dd>Before I go any further, let me define what I mean by <b>amplitude</b> and <b>frequency</b>. If you have studied physics, you may well have come across the concept of amplitude and frequency applied to a sin wave. 
<p></p><table><tbody><tr><td><img height="152" src="http://freespace.virgin.net/hugo.elias/models/m_sinwav.gif" width="340" /></td><td><h4>Sin Wave</h4></td></tr></tbody><dd>The wavelength of a sin wave is the distance from one peak to another. The amplitude is the height of the wave. The frequency is defined to be 1/<font size="+1"><sub>wavelength</sub></font>. </dd><tr><td><img height="143" src="http://freespace.virgin.net/hugo.elias/models/m_ranwav.gif" width="254" /></td><td><h4>Noise Wave</h4></td></tr><dd>In the graph of this example noise function, the red spots indicate the random values defined along the dimension of the function. In this case, the amplitude is the difference between the minimum and maximum values the function could have. The wavelength is the distance from one red spot to the next. Again frequency is defined to be 1/<font size="+1"><sub>wavelength</sub></font>. </dd></table><br /><font size="+2">Creating the Perlin Noise Function</font></dd>
		<dd>Now, if you take lots of such smooth functions, with various frequencies and amplitudes, you can add them all together to create a nice noisy function. This is the Perlin Noise Function.<br /><center><table border="2"><tbody><tr><td><center><font size="+1">Take the following Noise Functions</font></center></td></tr><tr><td><img height="200" src="http://freespace.virgin.net/hugo.elias/models/noise_a.gif" width="256" /><img height="200" src="http://freespace.virgin.net/hugo.elias/models/noise_b.gif" width="256" /><img height="200" src="http://freespace.virgin.net/hugo.elias/models/noise_c.gif" width="256" /><img height="200" src="http://freespace.virgin.net/hugo.elias/models/noise_d.gif" width="256" /><img height="200" src="http://freespace.virgin.net/hugo.elias/models/noise_e.gif" width="256" /><img height="200" src="http://freespace.virgin.net/hugo.elias/models/noise_f.gif" width="256" /></td></tr><tr><td><img height="200" src="http://freespace.virgin.net/hugo.elias/models/perlin1.gif" width="256" align="right" /><br /><p></p><center><font size="+1">Add them together, and this is what you get.</font></center><p></p></td></tr></tbody><dd>You can see that this function has large, medium and small variations. You may even imagine that it looks a little like a mountain range. In fact many computer generated landscapes are made using this method. Of course they use 2D noise, which I shall get onto in a moment. </dd></table></center><p></p></dd>
		<dd>You can, of course, do the same in 2 dimensions. 
<center><table border="0"><tbody><tr><td><center><font size="+1">Some noise functions are created in 2D</font></center><img height="128" src="http://freespace.virgin.net/hugo.elias/models/perlin_a.jpg" width="128" /><img height="128" src="http://freespace.virgin.net/hugo.elias/models/perlin_b.jpg" width="128" /><img height="128" src="http://freespace.virgin.net/hugo.elias/models/perlin_c.jpg" width="128" /><img height="128" src="http://freespace.virgin.net/hugo.elias/models/perlin_d.jpg" width="128" /><img height="128" src="http://freespace.virgin.net/hugo.elias/models/perlin_e.jpg" width="128" /><img height="128" src="http://freespace.virgin.net/hugo.elias/models/perlin_f.jpg" width="128" /></td></tr><tr><td><center><dd>Adding all these functions together produces a noisy pattern.<br /><img height="128" src="http://freespace.virgin.net/hugo.elias/models/p_128.jpg" width="128" /></dd></center></td></tr></tbody></table></center></dd>
		<p>
				<font size="+2">Persistence</font>
		</p>
		<dd>When you're adding together these noise functions, you may wonder exactly what amplitude and frequency to use for each one. The one dimensional example above used twice the frequency and half the amplitude for each successive noise function added. This is quite common. So common in fact, that many people don't even consider using anything else. However, you can create Perlin Noise functions with different characteristics by using other frequencies and amplitudes at each step. For example, to create smooth rolling hills, you could use Perlin noise function with large amplitudes for the low frequencies , and very small amplitudes for the higher frequencies. Or you could make a flat, but very rocky plane choosing low amplitudes for low frequencies. 
<p></p></dd>
		<dd>To make it simpler, and to avoid repeating the words Amplitude and Frequency all the time, a single number is used to specify the amplitude of each frequency. This value is known as <b>Persistence</b>. There is some ambiguity as to it's exact meaning. The term was originally coined by Mandelbrot, one of the people behind the discovery of fractals. He defined noise with a lot of high frequency as having a low persistence. My friend Matt also came up with the concept of persistence, but defined it the other way round. To be honest, I prefer Matt's definition. Sorry Mandelbrot. So our definition of persistence is this: 
<p></p><pre><font size="+1">
frequency = 2<sup>i</sup>
amplitude = persistence<sup>i</sup></font></pre><p></p></dd>
		<dd>Where <b>i</b> is the <b>i</b><sup>th</sup> noise function being added. To illustrate the effect of persistence on the output of the Perlin Noise, take a look at the diagrams below. They show the component noise functions that are added, the effect of the persistence value, and the resultant Perlin noise function. 
<p></p><table border="0"><tbody><tr valign="center" align="middle"><td><b>Frequency<b></b></b></td><td><font size="+2">1</font></td><td></td><td><font size="+2">2</font></td><td></td><td><font size="+2">4</font></td><td></td><td><font size="+2">8</font></td><td></td><td><font size="+2">16</font></td><td></td><td><font size="+2">32</font></td><td></td></tr><tr><td><pre></pre></td></tr><tr valign="center"><td><b>Persistence = 1/4</b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_b1.gif" width="64" /></td><td><b><font size="+2">+</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_b2.gif" width="64" /></td><td><b><font size="+2">+</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_b3.gif" width="64" /></td><td><b><font size="+2">+</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_b4.gif" width="64" /></td><td><b><font size="+2">+</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_b5.gif" width="64" /></td><td><b><font size="+2">+</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_b5.gif" width="64" /></td><td><b><font size="+2">=</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_br.gif" width="64" /></td><td><b></b></td></tr><tr valign="top" align="middle"><td><b>Amplitude:</b></td><td>1</td><td></td><td><sup>1</sup>/<sub>4</sub></td><td></td><td><sup>1</sup>/<sub>16</sub></td><td></td><td><sup>1</sup>/<sub>64</sub></td><td></td><td><sup>1</sup>/<sub>256</sub></td><td></td><td><sup>1</sup>/<sub>1024</sub></td><td></td><td>result</td><td></td></tr><tr><td><pre></pre></td></tr><tr valign="center"><td><b>Persistence = 1/2</b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_c1.gif" width="64" /></td><td><b><font size="+2">+</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_c2.gif" width="64" /></td><td><b><font size="+2">+</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_c3.gif" width="64" /></td><td><b><font size="+2">+</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_c4.gif" width="64" /></td><td><b><font size="+2">+</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_c5.gif" width="64" /></td><td><b><font size="+2">+</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_c6.gif" width="64" /></td><td><b><font size="+2">=</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_cr.gif" width="64" /></td><td><b></b></td></tr><tr valign="top" align="middle"><td><b>Amplitude:</b></td><td>1</td><td></td><td><sup>1</sup>/<sub>2</sub></td><td></td><td><sup>1</sup>/<sub>4</sub></td><td></td><td><sup>1</sup>/<sub>8</sub></td><td></td><td><sup>1</sup>/<sub>16</sub></td><td></td><td><sup>1</sup>/<sub>32</sub></td><td></td><td>result</td><td></td></tr><tr><td><pre></pre></td></tr><tr valign="center"><td><b>Persistence = 1 / root2</b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_a1.gif" width="64" /></td><td><b><font size="+2">+</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_a2.gif" width="64" /></td><td><b><font size="+2">+</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_a3.gif" width="64" /></td><td><b><font size="+2">+</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_a4.gif" width="64" /></td><td><b><font size="+2">+</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_a5.gif" width="64" /></td><td><b><font size="+2">+</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_a6.gif" width="64" /></td><td><b><font size="+2">=</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_ar.gif" width="64" /></td><td><b></b></td></tr><tr valign="top" align="middle"><td><b>Amplitude:</b></td><td>1</td><td></td><td><sup>1</sup>/<sub>1.414</sub></td><td></td><td><sup>1</sup>/<sub>2</sub></td><td></td><td><sup>1</sup>/<sub>2.828</sub></td><td></td><td><sup>1</sup>/<sub>4</sub></td><td></td><td><sup>1</sup>/<sub>5.656</sub></td><td></td><td>result</td><td></td></tr><tr><td><pre></pre></td></tr><tr valign="center"><td><b>Persistence = 1</b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_d1.gif" width="64" /></td><td><b><font size="+2">+</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_d2.gif" width="64" /></td><td><b><font size="+2">+</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_d3.gif" width="64" /></td><td><b><font size="+2">+</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_d4.gif" width="64" /></td><td><b><font size="+2">+</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_d5.gif" width="64" /></td><td><b><font size="+2">+</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_d6.gif" width="64" /></td><td><b><font size="+2">=</font></b></td><td><img height="50" src="http://freespace.virgin.net/hugo.elias/models/prln_dr.gif" width="64" /></td><td><b></b></td></tr><tr valign="top" align="middle"><td><b>Amplitude:</b></td><td>1</td><td></td><td>1</td><td></td><td>1</td><td></td><td>1</td><td></td><td>1</td><td></td><td>1</td><td></td><td>result</td><td></td></tr></tbody></table><p><br /></p><p><font size="+2">Octaves</font></p></dd>
		<dd>Each successive noise function you add is known as an <b>octave</b>. The reason for this is that each noise function is twice the frequency of the previous one. In music, octaves also have this property. 
</dd>
		<dd>Exactly how many octaves you add together is entirely up to you. You may add as many or as few as you want. However, let me give you some suggestions. If you are using the perlin noise function to render an image to the screen, there will come a point when an octave has too high a frequency to be displayable. There simply may not be enough pixels on the screen to reproduce all the little details of a very high frequency noise function. Some implementations of Perlin Noise automatically add up as many noise functions they can until the limits of the screen (or other medium) are reached. 
</dd>
		<dd>It is also wise to stop adding noise functions when their amplitude becomes too small to reproduce. Exactly when that happens depends on the level of persistence, the overall amplitude of the Perlin function and the bit resolution of your screen (or whatever). 
<p><font size="+2">Making your noise functions</font></p></dd>
		<dd>What do we look for in a noise function? Well, it's essentially a random number generator. However, unlike other random number generators you may have come across in your programs which give you a different random number every time you call them, these noise functions supply a random number calculated from one or more parameters. I.e. every time you pass the same number to the noise function, it will respond with the same number. But pass it a different number, and it will return a different number. 
<p></p></dd>
		<dd>Well, I don't know a lot about random number generators, so I went looking for some, and here's one I found. It seems to be pretty good. It returns floating point numbers between -1.0 and 1.0. 
<table border="2"><tbody><tr><td><pre>  function IntNoise(32-bit integer: x)			 

    x = (x&lt;&lt;13) ^ x;
    return ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) &amp; 7fffffff) / 1073741824.0);    

  end IntNoise function
</pre></td></tr></tbody></table><p></p></dd>
		<dd>Now, you'll want several different random number generators, so I suggest making several copies of the above code, but use slightly different numbers. Those big scarey looking numbers are all prime numbers, so you could just use some other prime numbers of a similar size. So, to make it easy for you to find random numbers, I have written a little program to list prime numbers for you. You can give it a start number and an end number, and it will find all the primes between the two. Source code is also included, so you can easily include it into your own programs to produce a random prime number. <a href="http://freespace.virgin.net/hugo.elias/models/primes.zip"><b>Primes.zip</b></a><p><font size="+2">Interpolation</font></p></dd>
		<dd>Having created your noise function, you will need to smooth out the values it returns. Again, you can choose any method you like, but some look better than others. A standard interpolation function takes three inputs, <b>a</b> and <b>b</b>, the values to be interpolated between, and <b>x</b> which takes a value between 0 and 1. The Interpolation function returns a value between <b>a</b> and <b>b</b> based on the value <b>x</b>. When <b>x</b> equals 0, it returns <b>a</b>, and when <b>x</b> is 1, it returns <b>b</b>. When <b>x</b> is between 0 and 1, it returns some value between <b>a</b> and <b>b</b>. 
<p></p><table cellspacing="5" border="0"><tbody><tr><td><p><font size="+1">Linear Interpolation:</font></p></td></tr></tbody><dd>Looks awful, like those cheap 'plasmas' that everyone uses to generate landscapes. It's a simple algorithm though, and I suppose would be excusable if you were trying to do perlin noise in realtime. 
<center><table width="95%" border="1"><tbody><tr><td><pre>  function <b>Linear_Interpolate</b>(<b>a</b>, <b>b</b>, <b>x</b>)
	return  <b>a</b>*(<b>1</b>-<b>x</b>) + <b>b</b>*<b>x</b>
  end of function
</pre></td></tr></tbody></table></center><p></p></dd><td><img height="85" src="http://freespace.virgin.net/hugo.elias/models/m_inter1.gif" width="213" /></td><tr><td><p><font size="+1">Cosine Interpolation:</font></p></td></tr><dd>This method gives a much smother curve than Linear Interpolation. It's clearly better and worth the effort if you can afford the very slight loss in speed. 
<center><table width="95%" border="1"><tbody><tr><td><pre>  function <b>Cosine_Interpolate</b>(<b>a</b>, <b>b</b>, <b>x</b>)
	<b>ft</b> = <b>x</b> * <b>3.1415927</b><b>f</b> = (<b>1</b> - cos(<b>ft</b>)) * <b>.5</b>

	return  <b>a</b>*(<b>1</b>-<b>f</b>) + <b>b*</b>f
  end of function
</pre></td></tr></tbody></table></center><br /><p></p></dd><td><img height="85" src="http://freespace.virgin.net/hugo.elias/models/m_inter2.gif" width="213" /></td><tr><td><p><font size="+1">Cubic Interpolation:</font><br /></p></td></tr><dd>This method gives very smooth results indeed, but you pay for it in speed. To be quite honest, I'm not sure if it would give noticeably better results than Cosine Interpolation, but here it is anyway if you want it. It's a little more complicated, so pay attention. Whereas before, the interpolation functions took three inputs, the cubic interpolation takes five. Instead of just <b>a</b> and <b>b</b>, you now need <b>v0</b>, <b>v1</b>, <b>v2</b> and <b>v3</b>, along with <b>x</b> as before. These are: <img height="86" src="http://freespace.virgin.net/hugo.elias/models/m_inter4b.gif" width="148" align="left" /></dd><dd><b>v0</b> = the point before <b>a</b></dd><dd><b>v1</b> = the point <b>a</b></dd><dd><b>v2</b> = the point <b>b</b></dd><dd><b>v3</b> = the point after <b>b</b><br clear="left" /><center><table width="95%" border="1"><tbody><tr><td><pre>  function <b>Cubic_Interpolate</b>(<b>v0</b>, <b>v1</b>, <b>v2</b>, <b>v3</b>,<b>x</b>)
	<b>P</b> = (<b>v3</b> - <b>v2</b>) - (<b>v0</b> - <b>v1</b>)
	<b>Q</b> = (<b>v0</b> - <b>v1</b>) - <b>P</b><b>R</b> = <b>v2</b> - <b>v0</b><b>S</b> = <b>v1</b>

	return <b>Px<sup>3</sup></b> + <b>Qx<sup>2</sup></b> + <b>Rx</b> + <b>S</b>
  end of function
</pre></td></tr></tbody></table></center></dd><td><img height="85" src="http://freespace.virgin.net/hugo.elias/models/m_inter4.gif" width="213" /></td></table><p><font size="+2">Smoothed Noise</font></p></dd>
		<dd>Aside from Interplolation, you can also smooth the output of the noise function to make it less random looking, and also less square in the 2D and 3D versions. Smoothing is done much as you would expect, and anyone who has written an image smoothing filter, or fire algorithm should already be familiar with the process.<br /><table border="0"><tbody><tr><td valign="top"></td></tr></tbody><dd>Rather than simply taking the value of the noise function at a single coordinate, you can take the average of that value, and it's neighbouring values. If this is unclear, take a look at the pseudo code below. 
</dd><dd>On the right, you can see a little diagram illustrating the difference between smoothed noise, and the same noise function without smoothing. You can see that the smooth noise is flatter, never reaching the extremes of unsmoothed noise, and the frequency appears to be roughly half. There is little point smoothing 1 dimensional noise, since these are really the only effects. Smoothing becomes more useful in 2 or three dimensions, where the effect is to reduce the squareness of the noise. Unfortunately it also reduces the contrast a little. The smoother you make it, obviously, the flatterthe noise will be. </dd><td valign="top"><img height="85" src="http://freespace.virgin.net/hugo.elias/models/m_inter6.gif" width="213" /><center><img height="96" src="http://freespace.virgin.net/hugo.elias/models/smooth_n.gif" width="96" /><img height="96" src="http://freespace.virgin.net/hugo.elias/models/smooth_y.gif" width="96" /><br /></center></td></table><font size="+1">1-dimensional Smooth Noise</font><center><table width="95%" border="1"><tbody><tr><td><pre>  function <b>Noise</b>(<b>x</b>)
    <b>.</b><b>.</b>
  end function

  function <b>SmoothNoise_1D</b>(<b>x</b>)

    return <b>Noise</b>(<b>x</b>)/<b>2</b>  +  <b>Noise</b>(<b>x</b>-<b>1</b>)/<b>4</b>  +  <b>Noise</b>(<b>x</b>+<b>1</b>)/<b>4</b>

  end function

</pre></td></tr></tbody></table></center><p><font size="+1">2-dimensional Smooth Noise</font></p><center><table width="95%" border="1"><tbody><tr><td><pre>  function <b>Noise</b>(<b>x</b>, <b>y</b>)
    <b>.</b><b>.</b>
  end function

  function <b>SmoothNoise_2D</b>(<b>x</b>&gt;, <b>y</b>)
    
    <b>corners</b> = ( <b>Noise</b>(<b>x-1</b>, <b>y-1</b>)+<b>Noise</b>(<b>x+1</b>, <b>y-1</b>)+<b>Noise</b>(<b>x-1</b>, <b>y+1</b>)+<b>Noise</b>(<b>x+1</b>, <b>y+1</b>) ) / <b>16</b><b>sides</b>   = ( <b>Noise</b>(<b>x-1</b>, <b>y</b>)  +<b>Noise</b>(<b>x+1</b>, <b>y</b>)  +<b>Noise</b>(<b>x</b>, <b>y-1</b>)  +<b>Noise</b>(<b>x</b>, <b>y+1</b>) ) /  <b>8</b><b>center</b>  =  <b>Noise</b>(<b>x</b>, <b>y</b>) / 4

    return <b>corners</b> + <b>sides</b> + <b>center</b>


  end function

</pre></td></tr></tbody></table></center><p><font size="+2">Putting it all together</font></p></dd>
		<dd>Now that you know all that, it's time to put together all you've learned and create a Perlin Noise function. Remember that it's just several Interpolated Noise functions added together. So Perlin Noise it just a function. You pass it one or more parameters, and it responds with a number. So, here's a simple 1 dimensional Perlin function. 
</dd>
		<dd>The main part of the Perlin function is the loop. Each iteration of the loop adds another octave of twice the frequency. Each iteration calls a <i>different</i> noise function, denoted by <b>Noise<sub>i</sub></b>. Now, you needn't actually write lots of noise functions, one for each octave, as the pseudo code seems to suggest. Since all the noise functions are essentially the same, except for the values of those three big prime numbers, you can keep the same code, but simply use a different set of prime numbers for each. 
<p><font size="+1">1-dimensional Perlin Noise Pseudo code</font></p><center><table width="95%" border="2"><tbody><tr><td><pre>
  function <b>Noise1</b>(integer <b>x</b>)
    <b>x</b> = (<b>x</b>&lt;&lt;<b>13</b>) ^ <b>x</b>;
    return ( <b>1.0</b> - ( (<b>x</b> * (<b>x</b> * <b>x</b> * <b>15731</b> + <b>789221</b>) + <b>1376312589</b>) &amp; <b>7fffffff</b>) / <b>1073741824.0</b>);    
  end function


  function <b>SmoothedNoise_1</b>(float <b>x</b>)
    return <b>Noise</b>(<b>x</b>)/<b>2</b>  +  <b>Noise</b>(<b>x</b>-<b>1</b>)/<b>4</b>  +  <b>Noise</b>(<b>x</b>+<b>1</b>)/<b>4</b>
  end function


  function <b>InterpolatedNoise_1</b>(float <b>x</b>)

      <b>integer_X</b>    = int(<b>x</b>)
      <b>fractional_X</b> = <b>x</b> - <b>integer_X</b><b>v1</b> = <b>SmoothedNoise1</b>(<b>integer_X</b>)
      <b>v2</b> = <b>SmoothedNoise1</b>(<b>integer_X</b> + <b>1</b>)

      return <b>Interpolate</b>(<b>v1</b> , <b>v2</b> , <b>fractional_X</b>)

  end function


  function <b>PerlinNoise_1D</b>(float <b>x</b>)

      <b>total</b> = <b>0</b><b>p</b> = <b>persistence</b><b>n</b> = <b>Number_Of_Octaves</b> - <b>1</b>

      loop <b>i</b> from <b>0</b> to <b>n</b><b>frequency</b> = <b>2<sup>i</sup></b><b>amplitude</b> = <b>p<sup>i</sup></b><b>total</b> = <b>total</b> + <b>InterpolatedNoise<sub>i</sub></b>(<b>x</b> * <b>frequency</b>) * <b>amplitude</b>

      end of <b>i</b> loop

      return <b>total</b>

  end function

</pre></td></tr></tbody></table></center><p></p></dd>
		<dd>Now it's easy to apply the same code to create a 2 or more dimensional Perlin Noise function: 
<p><font size="+1">2-dimensional Perlin Noise Pseudocode</font></p><center><table width="95%" border="2"><tbody><tr><td><pre>  function <b>Noise1</b>(integer <b>x</b>, integer <b>y</b>)
    <b>n</b> = <b>x</b> + <b>y</b> * <b>57</b><b>n</b> = (<b>n</b>&lt;&lt;<b>13</b>) ^ <b>n</b>;
    return ( <b>1.0</b> - ( (<b>n</b> * (<b>n</b> * <b>n</b> * <b>15731</b> + <b>789221</b>) + <b>1376312589</b>) &amp; <b>7fffffff</b>) / <b>1073741824.0</b>);    
  end function

  function <b>SmoothNoise_1</b>(float <b>x</b>, float <b>y</b>)
    <b>corners</b> = ( <b>Noise</b>(<b>x-1</b>, <b>y-1</b>)+<b>Noise</b>(<b>x+1</b>, <b>y-1</b>)+<b>Noise</b>(<b>x-1</b>, <b>y+1</b>)+<b>Noise</b>(<b>x+1</b>, <b>y+1</b>) ) / <b>16</b><b>sides</b>   = ( <b>Noise</b>(<b>x-1</b>, <b>y</b>)  +<b>Noise</b>(<b>x+1</b>, <b>y</b>)  +<b>Noise</b>(<b>x</b>, <b>y-1</b>)  +<b>Noise</b>(<b>x</b>, <b>y+1</b>) ) /  <b>8</b><b>center</b>  =  <b>Noise</b>(<b>x</b>, <b>y</b>) / 4
    return <b>corners</b> + <b>sides</b> + <b>center</b>
  end function

  function <b>InterpolatedNoise_1</b>(float <b>x</b>, float <b>y</b>)

      <b>integer_X</b>    = int(<b>x</b>)
      <b>fractional_X</b> = <b>x</b> - <b>integer_X</b><b>integer_Y</b>    = int(<b>y</b>)
      <b>fractional_Y</b> = <b>y</b> - <b>integer_Y</b><b>v1</b> = <b>SmoothedNoise1</b>(<b>integer_X</b>,     <b>integer_Y</b>)
      <b>v2</b> = <b>SmoothedNoise1</b>(<b>integer_X</b> + <b>1</b>, <b>integer_Y</b>)
      <b>v3</b> = <b>SmoothedNoise1</b>(<b>integer_X</b>,     <b>integer_Y</b> + <b>1</b>)
      <b>v4</b> = <b>SmoothedNoise1</b>(<b>integer_X</b> + <b>1</b>, <b>integer_Y</b> + <b>1</b>)

      <b>i1</b> = <b>Interpolate</b>(<b>v1</b> , <b>v2</b> , <b>fractional_X</b>)
      <b>i2</b> = <b>Interpolate</b>(<b>v3</b> , <b>v4</b> , <b>fractional_X</b>)

      return <b>Interpolate</b>(<b>i1</b> , <b>i2</b> , <b>fractional_Y</b>)

  end function


  function <b>PerlinNoise_2D</b>(float <b>x</b>, float <b>y</b>)

      <b>total</b> = <b>0</b><b>p</b> = <b>persistence</b><b>n</b> = <b>Number_Of_Octaves</b> - <b>1</b>

      loop <b>i</b> from <b>0</b> to <b>n</b><b>frequency</b> = <b>2<sup>i</sup></b><b>amplitude</b> = <b>p<sup>i</sup></b><b>total</b> = <b>total</b> + <b>InterpolatedNoise<sub>i</sub></b>(<b>x</b> * <b>frequency</b>, <b>y</b> * <b>frequency</b>) * <b>amplitude</b>

      end of <b>i</b> loop

      return <b>total</b>

  end function

</pre></td></tr></tbody></table></center><p></p><hr /><p><font size="+2">Applications of Perlin Noise</font></p></dd>
		<dd>Now that you have this fantastic function, what can you do with it? Well, as the cliche goes, you're limited only by your imagination. Perlin Noise has so many applications that I can't think of them all, but I'll have a go. 
<p><u><font size="+1">1 dimensional</font></u></p><p></p><table border="0"><tbody><tr><td valign="top"><b>Controlling virtual beings:</b></td><td></td></tr></tbody><dd>Living objects rarely stay still for very long (except students). Use perlin noise to constantly adjust the joint positions of a virtual human player, in a game for example, to make it look like it's more alive. 
<p></p></dd><tr><td valign="top"><b>Drawing sketched lines:</b></td><td><img height="100" src="http://freespace.virgin.net/hugo.elias/models/sketch1.gif" width="128" align="right" /></td></tr><dd>Computer drawn lines are always totally straight, which can make them look unnatural and unfriendly. You can use Perlin Noise to introduce a wobblyness to a line drawing algorithm to make it appear as if it's been drawn by hand. You can also draw wobbly circles and boxes. Some research has been done on making a Sketchy User Interface.<br />See: <a href="http://mrl.nyu.edu/meyer/projects/etchapad/">Creating Informal Looking Interfaces</a>. 
<p></p></dd></table><p></p><hr /><p><u><font size="+1">2 dimensional</font></u></p><p></p><table border="0"><tbody><tr><td valign="top"><b>Landscapes:</b></td><td></td></tr></tbody><dd>These are a perfect application for 2D Perlin Noise. Unlike the subdivision method, you do not have to store the landscape anywhere in memory, the height of any point on the landscape can be calculated easily. What's more, the land stretches indefinitely (almost), and can be calculated to minute detail, so it's perfect of variable level of detail rendering. The properties of the landscape can be defined easily too. </dd><tr><td valign="top"><b>Clouds:</b></td><td></td></tr><dd>Again, cloud rendering is well suited to Perlin Noise. </dd><tr><td valign="top"><b>Generating Textures:</b></td><td></td></tr><dd>All sorts of textures can be generated using Perlin Noise. See the table below for some examples. The textures generated can go on for ages before repeating (if ever), which makes them much more pleasant to look at than a repeating tiled texture map. </dd></table><p></p><hr /><p><u><font size="+1">3 dimensional</font></u></p><p></p><table border="0"><tbody><tr><td valign="top"><b>3D Clouds:</b></td><td></td></tr></tbody><dd>You can, of course, produce volumetric clouds. You'll probably have to use some sort of ray tracing to visualise them. </dd><tr><td valign="top"><b>Animated Clouds:</b></td><td></td></tr><dd>You can produce animated 2 dimensional clouds with 3D Perlin Noise, if you consider one dimension to be time. </dd><tr><td valign="top"><b>Solid Textures:</b></td><td></td></tr><dd>Some rendering / raytracing programs, like POVray, apply texture to objects by literally carving them from a 3-dimensional texture. This was, the textures do not suffer from the warping usually associated with mapping 2D textures onto (non-flat) 3D objects. </dd></table><p></p><hr /><p><u><font size="+1">4 dimensional</font></u></p><p></p><table border="0"><tbody><tr><td valign="top"><b>Animated 3D Textures and Clouds:</b></td><td></td></tr></tbody><dd>Moving into higher dimensions, you can easily produce animated clouds and solid textures. Just consider the extra dimension to be time. </dd></table><p></p><hr /><p></p><table><tbody><tr><td><img height="120" src="http://freespace.virgin.net/hugo.elias/models/lakedistrict.jpg" width="160" /><br /><font size="-2">Copyright Matt Fairclough 1998</font></td><td>The land, clouds and water in this picture were all mathematically generated with Perlin Noise, and rendered with <a href="http://planetside.base.org/">Terragen</a>.</td></tr><tr><td><a href="http://freespace.virgin.net/hugo.elias/models/m_clouds.htm"><img height="120" src="http://freespace.virgin.net/hugo.elias/models/cldcover.jpg" width="160" /></a></td><td>The clouds in this demo are animated with 3D perlin Noise. The algorithm had to be modified slightly to be able to produce Perlin Noise in real time. See the <a href="http://freespace.virgin.net/hugo.elias/models/m_clouds.htm">Clouds Article</a> for more info on how this was done. </td></tr></tbody></table><p></p><hr /><p><font size="+2">Generating Textures with Perlin Noise</font></p></dd>
		<dd>Perlin is fantastic for generating textures. You can produce textures that are (for all practical purposes) infinitely large, but take up almost no memory. You can create marble, wood, swirly patterns, probably anything if you try hard. You can also define a 3D texture. You can think of this as a solid block of material, from which you can 'carve' an object. This allows you to produce textures which can be applied to any shaped object without distortion. It can take a lot of imagination, thought and experimentation to get a texture to look really good, but the results can be very impressive indeed. 
<p></p></dd>
		<dd>Play around as much as you like. Use several Perlin functions to create a texture, try different persistences and different frequencies in different dimensions. You can use one Perlin function to affect the properties of another. Apply functions to their output. Do whatever you want, there's almost certainally a way to produce almost any texture you can dream up. 
<p><font size="+1">The following textures were made with 3D Perlin Noise</font></p><table border="2"><tbody><tr><td><img height="100" src="http://freespace.virgin.net/hugo.elias/models/perlsph2.gif" width="100" /><p><img height="100" src="http://freespace.virgin.net/hugo.elias/models/perlsph1.gif" width="100" /></p></td><td></td></tr></tbody><dd>Standard 3 dimensional perlin noise. 4 octaves, persistence 0.25 and 0.5 </dd><tr><td><img height="100" src="http://freespace.virgin.net/hugo.elias/models/perlsph3.gif" width="100" /></td><td></td></tr><dd>Low persistence. You can create harder edges to the perlin noise by applying a function to the output. </dd><tr><td><img height="100" src="http://freespace.virgin.net/hugo.elias/models/perlsph4.gif" width="100" /></td><td></td></tr><dd>To create more interesting and complicated textures, you should try mixing several Perlin functions. This texture was created in two parts. Firstly a Perlin function with low persistence was used to define the shape of the blobs. The value of this function was used to select from two other functions, one of which defined the stripes, the other defined the blotchy pattern. A high value chose more of the former, a low value more of the latter. The stripes were defined by multiplying the first Perlin Function by some number (about 20) then taking the cosine. </dd><tr><td><img height="100" src="http://freespace.virgin.net/hugo.elias/models/perlsph5.gif" width="100" /></td><td></td></tr><dd>A marbly texture can be made by using a Perlin function as an offset to a cosine function. 
<p></p><pre><b>
    texture = cosine( x + perlin(x,y,z) )
</b></pre></dd><tr><td><img height="100" src="http://freespace.virgin.net/hugo.elias/models/perlsph9.gif" width="100" /><p><img height="100" src="http://freespace.virgin.net/hugo.elias/models/perlsph10.gif" width="100" /></p></td><td></td></tr><dd>Very nice wood textures can be defined. The grain is defined with a low persistence function like this: <pre><b>
    g = perlin(x,y,z) * 20
    grain = g - int(g)
</b></pre></dd><dd>The very fine bumps you can see on the wood are high frequency noise that has been stretched in one dimension. <pre><b>
    bumps = perlin(x*50, y*50, z*20)
    if bumps &lt; .5 then bumps = 0  else bumps = 1t
</b></pre></dd></table><p></p><hr /></dd>
<img src ="http://www.cppblog.com/sunraiing9/aggbug/13738.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunraiing9/" target="_blank">@王一伟</a> 2006-10-16 08:40 <a href="http://www.cppblog.com/sunraiing9/articles/13738.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>点面关系的判定方法</title><link>http://www.cppblog.com/sunraiing9/articles/13731.html</link><dc:creator>@王一伟</dc:creator><author>@王一伟</author><pubDate>Mon, 16 Oct 2006 00:32:00 GMT</pubDate><guid>http://www.cppblog.com/sunraiing9/articles/13731.html</guid><wfw:comment>http://www.cppblog.com/sunraiing9/comments/13731.html</wfw:comment><comments>http://www.cppblog.com/sunraiing9/articles/13731.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunraiing9/comments/commentRss/13731.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunraiing9/services/trackbacks/13731.html</trackback:ping><description><![CDATA[法向量是垂直屏幕的法线表示的向量<br />设平面法向量为{A,B,C}，平面与法向量的交点为P0:(x0,y0,z0).<br />则平面上一点(x,y,z)与(x0,y0,z0)的向量必然与法线垂直。因此得出平面的点法式方程:<br />A(x-X0) + B(y-y0) + C(z-z0) = 0<br />将判断点坐标代入方程 满足条件 则点在平面上。<br />另:若方程坐标多项式&gt;0,则在平面正面（法向量方向），反之在背面<br /><br />注释：<br />两向量a * b  的长度为：<br />||a ||   *   ||b||    * sin(thta)   //thta为a与b的夹角<br /><br /><br />这样 A(x-X0) + B(y-y0) + C(z-z0) = 0  a,b垂直<br />     A(x-X0) + B(y-y0) + C(z-z0) &gt; 0  a在b方向<br />     A(x-X0) + B(y-y0) + C(z-z0) &lt; 0  a不在b方向<img src ="http://www.cppblog.com/sunraiing9/aggbug/13731.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunraiing9/" target="_blank">@王一伟</a> 2006-10-16 08:32 <a href="http://www.cppblog.com/sunraiing9/articles/13731.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>初学的一些理解</title><link>http://www.cppblog.com/sunraiing9/articles/11396.html</link><dc:creator>@王一伟</dc:creator><author>@王一伟</author><pubDate>Fri, 18 Aug 2006 02:44:00 GMT</pubDate><guid>http://www.cppblog.com/sunraiing9/articles/11396.html</guid><wfw:comment>http://www.cppblog.com/sunraiing9/comments/11396.html</wfw:comment><comments>http://www.cppblog.com/sunraiing9/articles/11396.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/sunraiing9/comments/commentRss/11396.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunraiing9/services/trackbacks/11396.html</trackback:ping><description><![CDATA[自己没写过底层的渲染，多多少少有些惭愧，做了这么久3D竟然简单的渲染都不熟悉，真的很惭愧啊。<br /><br />前几天来了个弟弟，要学3D，所以也和他一起写了写渲染部分。<br /><br />昨天吧，他写了一天的顶点渲染（带索引缓冲），结果回家问我怎么有时候渲染是一个平面上的4个点是渲染成的矩形，有时候渲染成的是三角形。我也不了解，就帮他看了看书，最后发现在没有开启双面渲染的情况下，你的眼点只有在三角面的正向的时候才能看见渲染的三角形，然而什么是正面就是这个问题的核心了。<br /><br />在定义渲染顶点stream的时候,渲染出图象的正向遵守左手法则，大拇指为三角面的正向，弟弟之所以只渲染出了半个矩形是因为另外半个是背朝屏幕的，所以看不见。<br /><br /><img src ="http://www.cppblog.com/sunraiing9/aggbug/11396.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunraiing9/" target="_blank">@王一伟</a> 2006-08-18 10:44 <a href="http://www.cppblog.com/sunraiing9/articles/11396.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>