Cloud Cover
2015-09-23 06:34
204 查看
Cloud Cover
Requires DOS4GW |
|
I intend to be a little vague in this article. This is for a couple of reasons, but mainly because I don't want anyone to feel they have to follow our program exactly. The way we did it was just one possible way of many (and not an especially good way at that). I would much rather people experimented themselves, rather than just blatently copied our algorithms. So I shall go as far as telling you why we made each step, and how it was based on real clouds, but probably won't give a lot of pseudocode. |
We thought a good deal about what screen mode to render the clouds in, eventually coming to the decision that an 8-bit mode would be very restrictive, and not really do the clouds justice. We settled, eventually,
for a truecolour (24-bit) mode, rather than Hicolour (16-bits). Firstly it would look better, and secondly it would be easier/faster to program.
Not being a wizard, and being unable to communicate with the VESA 1.5 BIOS from within the 32-bit .EXE, I initially had some trouble getting the program to autodetect the graphics card. Eventually I gave up, and
decided to place the burden on the user. The trouble is this. Truecolour modes come in two flavours, 24-bit or 32-bit, but it's up to the graphics card which it supplies you with. It's possible to query the number of bits per pixel, but I was having serious
trouble calling the Real Mode VESA functions. In the end, we had to write two inner loops, one to render to a 24-bit screen, and one to render to a 32-bit screen, and let the user choose whichever one doesn't look like nonsense.
As I said before, this program was written in just two weeks, so it's a bit of a mess, and many things could have been done a lot better. Everything is software rendered, and little attempt was made to optimise
it. It uses a good deal of look up tables, so the more cache you've got, the faster it'll run. However, I expect that it would be possible to speed it up a great deal with 3D graphics hardware. It should even be possible to make a version that allows you to
look around freely. Anyway, I'll leave that up to you, and get on with the article.
About Cloudscapes
The first thing you should do if you're going to simulate clouds is to rush outside and look at some real clouds. Make as many observations about the clouds as you can. However, if you're anything like me, you're
probably reading this at night, so I'll tell you some things about clouds.
1. The sun is very bright and it is making you squint ! 2. The clouds near the sun are glowing much brighter than clouds far from the sun. 3. Luckly the clouds are moving across the sky, and occasionally block out the sun, making it easier to see, so you don't have to squint as much. 4. The clouds are also changing shape as they move across the sky. 5. Not all the sky contains cloud. Some areas of sky are completely cloud free. 6. The clouds do not continue into the distance forever. The furthest clouds are often obscured by haze. |
Creating Clouds
If you have not already, I suggest you read the article on Perlin Noise.
Perlin Noise is great for creating cloudy type things, and can produce very realistic results. However, it is far too slow to be used for a realtime graphics application like this, and a faster alternative must
be found.
In the end, we settled for comopsition of four octaves of animated noise at various frequencies and amplitudes.
Each octave (four in total) was calculated seperately, and they were all added together to create a cloud texture. A sheet of noise was handled like this:
Create an array of noise | Smooth it | Resample it up. |
This was done for four arrays of noise to create noise textures of size 32x32, 64x64, 128x128 and 256x256. Imagine now that these noise textures are tiled together to create four maps each of size 256x256. (see left). The white lines have been added as a guide just to help you see the tiling. | ||||
Now, add these four maps together:CloudMap = Map1 + (Map2 / 2) + (Map3 / 4) + (Map4 / 8) It doesn't look a great deal like the cloud cover in the program yet, but it's getting there. Importantly, observation number 5 (above) has not been satisfied. This entire texture contains cloud to some extent. What we really want is areas of cloud, and areas of totally empty sky. | ||||
thinner clouds. Do not use values any greater than 1.0. You should agree that these look a lot more like clouds than the previous image. |
If you hadn't already noticed, the sky is curved. It's amazing how many computer generated images of the sky fail to take this into account. If you have a totally flat sky, the clouds will appear to go
forever into the distance. You will notice that this does not happen with the real sky, so it should not happen with our simulation.
So, we shall take our little square of clouds, and lay it over a sphere to represent the curvature of the earth. The camera is then positioned, not in the centre of the sphere, as this is not realistic. We live on the surface of the earth, not in the centre. So, put the camera somewhere near the top of the sphere, and point it at the clouds. Sorry that the diagram doesn't really show the correct position of the camera, but it would have been too cluttered. |
Right, now that the clouds are in place, they're going to need to be coloured like clouds. You might be tempted to colour the sky blue, and the clouds white, and leave it at that. You're more than welcome, but
it would look lame.Firstly, we'll render the backdrop to the clouds. The sky directly overhead is blue, but if you look into the distance, you will see that it becomes a pale blue / grey.
Blue Sky
To do this, we needed the know the distance to the cloud dome at each pixel. Knowing this information, we kind of bodged together an algorithm to produce a blue/grey gradient across the sky. I'm sure you can figure out something similar, so I won't go into detail here. |
Since the light from the sun scatters in the atmosphere, you get a bright glow around it. We modeled this glow with an exponential function. See there it is again. Also, a constant value was added to light up the atmosphere to make the atmosphere calculations work correctly. This was stored as a 320x150x8bit texture map to be used later to make the clouds glow near the sun. In the pseudocode at the end of this page, I shall refer to this as the Glow map. |
Now, the blue sky and the glow were combined to create a bright glowing atmosphere. Since the camera never moved, this was stored as a 320x150x24bit texture map. In the pseudocode at the end of this page, I shall refer to this as the BlueSkymap. |
Lastly, a lens flare texture was created. You can use any lens flare map you like. This one was created in much the same way as the glow map, but six lines were added as well. The lines are the width of the sun, and fade off exponentially. In the pseudocode at the end of this page, I shall refer to this as the LensFlaremap. |
There are a couple of things going on every frame. Firstly, the cloud map must be animated. Then the blue sky, sun glow, cloud map, and lens flare are all combined to create the final image.
Animating the clouds
If you read and understood my very brief explanation of how the clouds were created, then it is a simple task to animate them. All you need to do it to animate the original noise maps.You will remember that there are basically 4 noise maps. The ones we used were 32x32 pixels each. Animating them is simply a matter of interpolating them from one noise map to another.
Animating a single noise map
| |||||
Noise map 1 | Crossfade between Noise 1 and Noise 2 | Noise map 2 |
| Pseudocode to animate an octave of noise Hopefully this small fragment of code will help to convey something which I am finding very hard to explain in words. The idea is to use this code to maintain four octaves of animating noise. The four octaves will need to animate at different speeds. The noise map responsible for producing the the largest amplitude of noise should animate the slowest. The Initialise Noisemap procedure should fill a noise map with random pixels, then apply a smoothing filter. The noise maps are thes used as explained in the Creating Cloudsparagraph. |
Any finally, you will have to actually take all this information (BlueSky, Glow, Lensflare and Clouds), and combine them into an image. Now, we took a look at the original code, and we can't figure out what some
of it does, so we haven't included it here, for the sake of simplicity. This fragment of pseudocode will probably not produce nice clouds straight off, so don't write to me complaining. It's only really meant as a guide to how we achieved it, to point you
in the right direction. You may have to do a lot of fiddling around and rearranging, and lots of optimising. Basically, don't copy out this code. read it, try and figure out vaguely what's going on, and write your own version from scratch.
Take a look at the Exposure article for information on the ExposureFunction.
function HazeExpCurve(d) c = a couple of hundred. Depends on how far away the sky dome is Hazyness = about .95 p = d2 / c return Hazynessp end function FlareStrength = Cloud Density over sun for each pixel c = pixel from CloudMap gl = pixel from GlowMap fl = (pixel from FlareMap) * FlareStrength h = HazeExpCurve(Distance to cloud dome) Start with Blue Sky Map HazeRed = Red Component of pixel from BlueSky map HazeGreen = Green Component of pixel from BlueSky map HazeBlue = Blue Component of pixel from BlueSky map Add simple shading to clouds shading = simple bump mapping on cloud Apply the bright glow on the clouds from the sun shading = shading * gl Fade the amount of cloud by the haze (according to distance) CloudVal = c * h Alpha-Blend the clouds with the blue sky using CloudVal Red = Red + (CloudCol-Red) * CloudVal Green = Green + (CloudCol-Green)* CloudVal Blue = Blue + (CloudCol-Blue) * CloudVal Add Lens Flare Red = Red + fl Green = Green + fl Blue = Blue + fl Now, use the exposure function, since values of Red, Green and Blue may be quite high Red = ExposureFunction(Red) Green = ExposureFunction(Green) Blue = ExposureFunction(Blue) Draw this pixel end loop |
LIGHT (in C++) ! : http://math1.uibk.ac.at/~werner/light/
Interesting sky / clouds / landscape renderer written in C++.
Mapping Reality: Simulating Clouds : http://patate.virtualave.net/clouds/index.html
Information on rendering plasma clouds.
Convective Clouds : http://www-imagis.imag.fr/Membres/Fabrice.Neyret/clouds/index-eng.html
Research into models of convecting clouds.
Radiant lense flare render engine : http://www.geocities.com/SiliconValley/Ridge/7251/radiant.htm
Pretty self explanatory.
Intel Developer Site : http://developer.intel.com/software/idap/games/index.htm
Kim Pallister has written an article, based on this one, explaining some methods of using hardware acceleration to speed up the rendering of clouds. However, I get the feeling that hardware acceleration is not
appropriate for all aspects of these clouds. I think that, until graphics cards get more advanced, or allow you to program your own routines, some of this will still have to be done in software.
Noise Machine : http://www.noisemachine.com/
Ken Perlin's course notes from the GDCHardCore gamers workshop, San Francisco, Dec 9, 1999.
Return to the Good Looking Textured Light Sourced Bouncy Fun Smart and Stretchy Page.
相关文章推荐
- Perlin Noise
- 对比下,看看你离企业的要求还有多远
- NetworkStream.Read
- *Jump Game
- hello world
- 解密一个U盘
- hdu-1823 Luck and Love
- hdu-1823 Luck and Love
- js == 和 === 的不同 (两个等号 三个等号)
- *LeetCode-Number of 1 Bits
- 多语言处理
- Solr 5.3安装和使用
- js 计算输入框的字节数
- [hihoCoder1231 2015BeijingOnline]求圆与多边形公共部分的周长
- LintCode "Search a 2D Matrix II"
- LeetCode-Partition List
- Maximal Square
- Download google drive public shared file in terminal
- Android Api Demos登顶之路(七十七)Graphics-->FingerPaint
- LintCode "Submatrix Sum"