2010
08.12

Procedural graphics is surely my favorite. The concept of create visual things with just code. Really comes in handy when your a crappy designer and still want to do visual stuff. Here you can see the result of yet another experiment on this track. It’s a eye-shader for generating procedural eyes. The 3D-engine of choice is Away3d. I use a CompositeMaterial consisting a PhongMultiPassMaterial and a SphericEnvMapPBMaterial (for the environment reflections). The bitmap that is used in the material is generated by a haxe-swf that is loaded in runtime. Just as previous experiments. The same bitmap is used as a base for the spherical normalmap. That adds a nice displacement to the surface. The iris is quite simple and could have more layers and complexity to get a more realistic pattern. Anyway, the texture looks something like this.

When wrapping this on a sphere it will fit seamlessly . I know, the blood-vessels aren’t that great. Perhaps I should use lines with turbulence instead.

Design your own eye

Here is a tool where you can try the different settings and create a unique eye.
Open editor

Demo

This “mars-attacks”-demo follows the mouse. To get two eyes I duplicates the output from the view. Thats why he can’t look at his nose (if existed). Notice that he is reacting to light, sort of…


Click to open

Open demo

2010
08.04

Cubes

There have been a lot of things to deal with lately so I have kept a low profile online. But last night I finally did a little experiment. It’s a little toy to make models made of cubes in away3d. Or infact, there is just ordinary planes. I suspect that it should be much faster if I created the geometry inside i single object, but this was fast enough for this experiment.

The material of choice is a WhiteShadingBitmapMaterial. The shadows are baked into the bitmap depending on the surrounding nodes. To render the shadow I use fillRect-method on the BitmapData. To make the shadows more soft I use the diffuse-color, but with lower brightness. When all shadow-rectangles are drawn the bitmap is blurred with applyFilter. The shadows was added to get a kind of fake ambient occlusion. Each cube, or node, has it’s own position in a 3d-grid (multidimensional array). When a plane is clicked a new node and its corresponding planes is created, animated and evaluated. If there is any doublets or planes inside the structure, it’s removed.


Click on the some of the models for a closeup view. Or just try it out yourself: Extrude the cube, dude!


Open

I have been a huge fan of voxels and voxel-engines lately. I know it’s pretty big and few voxels, but let me call this a micro-voxel-editor please ;-)

2010
06.01

Last time I made some wood. Now let’s burn that up. Still experimenting with the same 3D perlin noise as before, but this time animated. When you can take control over each pixel of noise it’s easy to add extra rules to form the shape of the noise such as turbulence based on y-value or an offset animation along the z-axis to gain some depth. Applying “ridges” to the perlin noise (invert all negative values when the range is between -1 to 1) makes the flames look more interesting. The bitmap generated is just 80×80 and 2 octaves of Perlin noise, so the possibilities are quite limited.

Click here or on the fireplace above to get warm.

If you want to see how it works, here is a zip with sources for a simple example. No graphics or UI is included though. The noise is compiled with Haxe, but a swf is included if you want to skip that.

See this post for additional credits.

2010
05.18

My next track on my journey through procedural domains goes through the woods. Not so revolutionary maybe, but I haven’t seen it in flash before and that’s enough challenge for me. And it’s a good way to learn the basics of textures. Here is the first tests:

For the sphere, I use the spherical mapping from the previous post. The cube has one texture for each side. One benefit if using a 3D procedural texture is that the wrapping is accurate and it looks like a block of massive wood. I can also use the optimized 3D Perlin noise as turbulence to make the grains look more natural.

Simple tree texture designer

I have added a few parameters to change, but several features could be added like: more object types, ring-types (tri,saw, sine), base texture blending.

Try it out here

2010
05.06

Noise Editor

The images in the last post was created with this tool. I use the heightmap to create a normal map with a excellent class called SphericalDispToNormConverter. So since I now have a heightmap and a normal map, Away3D can do the rest. The material used in this example is the PhongMultiPassMaterial. When “displacement map” is disabled a simple BitmapMaterial is used. The @away3D -team has really done a great job with the pixelbender materials.

Among the settings you can choose between a regular perlin noise or a ridged one. You will notice that the difference is pretty big. Also, check out the different presets.

The resolution on the heightmap is 400×200, but scaled down in the UI. (By the way I can’t tell you enough how I love the minimalcomps by mr @bit101.)  The heightmap-generation is pretty heavy on the CPU, so choose browser with care and stay away from debug-players ;)


Sphere designer

What do you think? Time for a generative material-library for Away3D?

2010
05.05

I’m not quite done experimenting with 3d perlin noise. Another cool feature that I haven’t seen in flash is to wrap the noise on a sphere seamlessly. Here is the result:


Click the spheres for a slightly larger version

To get the texture to wrap seamless without distortion, we can use the 3d nature of the noise in a interesting way. If we evaluating the 3d-position of each point on the surface of a sphere we can get the noise in that particular point. To convert the point from 3d-space to 2d-space some trigonometry is needed. My math-skills really suck, but my cut-n-paste skills are excellent. Once again, LibNoise showed me the way with 5 lines of code. First I only got chaotic noise with some sort of repeating pattern. It took some time to figure out that I had to convert the numbers to a positive range.

lat = py / height * 180- 90;
lon = px / width * 360-180;
r = Math.cos(DEG_TO_RAD *  lat);

//range between 0-1
_x = (r * Math.cos (DEG_TO_RAD * lon) +1)*.5
_y = (Math.sin (DEG_TO_RAD * lat)+1)*.5
_z = (r * Math.sin(DEG_TO_RAD * lon)+1)*.5

For the sphere and the material/lighting I use Away3d. In the next post I will show you more about that and the tool for creating the different materials. Oh, and it’s looks a lot better animated :)

2010
04.19

While doing research for the terrain editor I found a lot of different methods for creating noise. One of my favorite algorithms is “ridged fractal noise”. I haven’t found any examples of this in AS3 so I created my own version based on the Optimized Perlin Noise seen in the community before. I think the route of that source began with Ron Valstar’s AS3 version (@Sjeiti), then with a optimized version by @quasimondo, and further optimized with a haxe-version by Nicolas Cannasse. It was very easy to just add the ridged part to the noise generated. There is some source to look at in other languages such as C++, Java or C#. First some examples to see whats the characteristics of ridges. Some of them uses a Stok3d PhongShader created by @DerSchmale to add a nice depth:


Terrain | My favorite. Imagine using this with a voxelengine.


Marble


Electric


Trails | Put together in Photoshop to demonstrate the effect of the shader


Space


Stone texture

It’s quite fun to search for new patterns by just adjusting the few parameters:

Make some noise

Try it out for yourself. I have limited the size of the bitmap to 200×200. It’s pretty optimized, but still to slow for large bitmaps. A Cool thing is that the swf is just 26 kB. Thanks @bit101 for MinimalComps.


Open editor

Here is a explanations for some of the parameters (I borrowed the descriptions from the reference of world-machine):

Offset: Offset determines at what elevation the fractal behavior begins to change its character.
Gain: A multifractal parameter, Gain typically controls the relative strength of the detailed versus smooth regions of the fractal. Low values are very smooth, while high values bring on the detailed nature more quickly.
Persistence: Controls the degree to which the strength of each layer of noise is reduced as they are layered together. Low persistence values produce very smooth terrains, whereas increasing the persistence produces more detail (and spikiness). Unlike a low octaves value, all layers of noise are still calculated when using a low persistence, so that terrain features are smoothly introduced as the value is increased.

If you’re interested, here is the source code for the noise generator (in Haxe).

In a terrain a heightmap with ridges is suitable for creating high mountains or sand dunes, which was my primary goal. Next step is to visualize it in 3d. The ridges does not look so good with a low poly mesh, so I have to look for a voxel-engine now.


2010
04.06

It’s finally time to render a landscape with all the different parts that I have covered so far.

I’m really curious of your output and render-time, so please upload it to the gallery when you created your own landscape. The gallery will be published as soon as I got a collection of images.

This tool is in a very experimental phase and this applications using pretty much memory and CPU-power. There is plenty of memory-leaks and optimization that has to be fixed. But for now, I don’t want to focus on that. Some calculations freezing the player for a while. But I think that the tolerance-level is higher if the user can see the progress both with a bar and status-notifications. Notice the effect when drawing the geometry above sea-level. It’s completely cosmetic and waste of CPU but makes it looks more advanced :)

FlashTerrain demo

Post production

I have also added the possibility to do some adjustments on the result. For now you can change the colorMatrix (brightness, contrast, hue and saturation) and add some sharpening.

Save / upload

If you have a flickr account, you can save it to your own photostream. Or upload to the public gallery, also using flickr, but a account dedicated to FlashTerrain. Or of course, encode the image to a jpg and save it to your desktop.

Credits and useful links so far

Papervision3d: http://www.papervision.org
AS3Dmod library: http://code.google.com/p/as3dmod/
Stok3d: http://www.derschmale.com/2009/06/08/introducing-stok3d-more-fp10-3dpixel-bender-shading/
ColorMatrix: http://www.gskinner.com/blog/archives/2007/12/colormatrix_upd.html
Gradient color component: http://mariosh.com/components/gradient-editor/
Advanced color picker: http://www.sephiroth.it/file_detail.php?id=150#
Multipart URLLoader Class by Eugene Zatepyakin (in-spirit): http://code.google.com/p/in-spirit/wiki/MultipartURLLoader
Flickr authorization control: http://www.mikechambers.com/blog/2008/08/12/flex-based-flickr-api-authorization-control/
phpFlickr: http://phpflickr.com/

2010
03.21

Next step is to distribute the tree we just created on to the terrain. I use the heightmap as the source. I create an array with objects representing all pixels. The reason for this is that I now can filter and sort these points. First, filter out all points in the defined range, based on the y-value and the range defined in the editor. Then, sorting out a specified amount of random points, sort them on the z-value for correct render order. Before this last sorting I can add all different objects to the same batch. I’m sure there are much better and faster methods than this. Analyzing the terrain for more realistic distribution should make it more interesting.   When rendering, I have to make a render for each position and merge the result with the final image.  It will not work to just paste the result on top of the terrain. The tree is sometimes behind the terrain and partly hidden. And if the terrain is included in each pass, next render will cover the previous. So after some experimenting with masks, pixel bender matte calculation, my solution was this:

  1. Render the object by itself in a transparent viewport.
  2. Add the terrain and set the material to a white color material and viewport background color to white. Move the object to a new position and render.
  3. Get the boundingbox of all none white pixels with getColorBoundsRect. This is the rectangle that we want to work with. Draw a new BitmapData with this rectangle from the viewport. Lets call it maskTree, the object with white surroundings.
  4. Crop the transparent pass with the same clipping-rectangle  as maskTree. Lets call the result transparentTree.
  5. Add effects like fog and filters like blur to transparentTree.
  6. If the tree got covered by any terrain, the edges now has straight cuts because we just use a rectangle clipping. We have to fix that. Loop through all pixels in the maskTree . If  its completely white in the mask, its a transparent pixel in the transparent image, so set that pixel transparent in transparentTree. Left is a masked image, but with correct multiplied alpha colors.
  7. Merge transparentTree with the final result. To do this a put the final canvas and the new object in sprites and cache them with draw() to a new final canvas
  8. Send an event so the user can follow the progress and start over with next iteration.

I tried to use a matte pixelbender-filter so that I just had to render the viewport once, but the alpha-channel in flash is pre-multiplied (correct me if I’m wrong here), so the edges became white when blending it with the final canvas. One downside is that it’s pretty slow. Another is the z-sorting issues that occurs. Maybe a down-sampled heightmap can be used instead when setting the position in 3d space.

Shadows and effects

Because the result of each tree is a single transparent bitmap, I can use different effects on each tree. A blur-filter based on the distance to the camera is added. A small random value on the hue/saturation make the trees more random. If fog is enabled a color tint is added. I didn’t find out how to change the color-transformation correctly , so I found a workaround by setting the tint with TweenMax and change the progress to 0-1 depending on the z-position and fog amount. Have to work more on this later on.

I mentioned the shadow-layers in one of the previous posts. To add every shadow to the final result, I make a temporary container and add a sprite with a radial gradient fill for every tree and cache that with bitmapData.draw(). This is then baked into the texture with the multiply blendmode.

Distribution demo

Things to improve:

- There is plenty of optimization here to do here. This is the most time-consuming part.
- Check visibility against the clipping planes and skip those objects.
- Adjust all the effects with better z-depth-control.
- Let the position of the sun affect the brightness.
- More realistic distribution such as slope detection or algorithms.

2010
03.18

Trees

This part was the reason I started all this. It’s thanks to the work of  Den Ivanov and an experiment of his: http://www.cleoag.ru/labs/flex/plant3d/. To create 3d-objects manually in papervision3D is a little bit to advanced for me, so thanks for sharing once again. I added some features and made it possible to customize it. Here is some samples:

I used 3d studio max to create the different leafs.  You can  adjust the leaf with various settings like width, height and bend-modifier ( credits to Bartek DrozdzAS3mod is great!).  It would be cool to create leaf manually by drawing a outline, adding vertices, triangulate and upload textures in runtime. But I have to experiment with  triangulation and uv-mapping first. The rules for generating the tree is stored in a 2d-array like this:

_branchMap = [
[0, 0, 2, 2, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]

This trunk uses 2 levels of recursive depths. One trunk and two levels of branches. Each array decide in which joint a new branch is growing while we iterate through the segments. The stored value is how many new branches there will be at that joint. The length of each array reflects how many segments there will be in that level. Oops, I got carried away with boring details… I’m not even pleased with this solution.  I think I have to use a completely different approach. A L-system maybe?  But there is a lot of things that I want to first, so I put it on hold for now. Still, you can get a lot of different trees by adjusting the few settings available.

There is pretty much research around, for example:

http://algorithmicbotany.org/papers/colonization.egwnp2007.html
http://algorithmicbotany.org/papers/#abop
http://www.cs.duke.edu/courses/cps124/fall02/resources/p119-weber.pdf

Tree Designer

I quickly put together a standalone tool so you can try to change the settings available. Some parameters in the building process  has random values (like branch-rotation), so when changing the branch and trunk settings the tree will be different every time.

Open Tree Designer

Future improvements:
- Leaf editor.
- New tree generation algorithm.
- Different tree-characteristics depending of the value of the normalmap when distributing on the mesh.
- More types of vegetation like grass, bushes.

Have you seen the previous posts about creating terrain with flash? Check them out here: http://www.inear.se/?cat=6

2010
03.15

Okay, lets add some water. This time an ocean.

One way would be to set set each vertex under a certain level to the same y-value, but I wanted to control the geometry under the surface as well. The SplitMesh util in papervision solved that for me. First I split the mesh and then adding another plane in that intersection. It was a little tricky to get the z-sorting right when previewing all parts together. One problem was to assign a viewport layer to the new objects. The triangles had different parents so some triangles got hidden. One solution was to clone the object and it’s material, but that was cpu- and memory-consuming in my case. Instead, I modified the splitMesh-method to change the parent of those triangles that where cut. The split-util is quite slow for large meshes, so it freezes the player for a while. Unfortunately I’m not an expert on splitting for-loops into chunks, so I have to live with that for now. Added a waiting-screen instead.

As with the terrain, the sea texture is a composition of several planes and materials put in different viewport layers for z-sorting and blend mode effects. The first plane contains the diffuse color. You can also use a reflection of the sky instead of the color value (this makes the sun reflect in the surface ). With BitmapData.draw() I create a bitmap which in turn get the alpha channel from a transparency map, in this case a gradient fill where we set the alpha (water transparency) and range (z-depth). The terrain under sea level becomes visible, and the cut become less sharp. The details below sea level is so flat and small, so I don’t bother using a displacement map to simulate light refracting through water.

The waves is generated by, can you guess? Perlin Noise. Just as with the clouds a bevel-filter adds a kind of volume to it.

Geometry above sea level is also cloned with inverted vertices. Then a displacement-map based on perlin noise is added on the viewport. There you got some nice reflections.

water demo

Future improvements:
- More realistic bump map.
- Sun reflections in waves (glitter). I tried a similar lightmap as the terrain uses but I can’t make the tiling correct.
- Foam ( along beach lines it would be easy to use the heightmap and a modify the paletteMap with transparent and white colors ) to create white waves around it.

2010
03.15

Last time I showed you the sky rendering process. I will now add a simple and common atmospheric effect, fog. There is not any objects other than the terrain and sky yet, so this post is quite short.

By adding a gradient fill to the  terrain texture I get a very simple fog effect. The sky and the sea gets a gradient fills based on the fog color and distance. Other objects, like vegetation, get a color tint to simulate the density of air between the camera and the object. I’m not quite there yet with getting it right. When there is only terrain and sky visible everything looks good, but when splitting the mesh and adding vegetation the tint has to be exact for every object to fit seamlessly in the picture. And this version must use a camera looking at the horizon. Otherwise I have to calculate the angle to the ground and adjust the texture-gradient.

The horizon-line gets its own gradient. The sky-sprite is outside the 3d-scene, so I first need to get the position on screen where the grid meets the sky. To do that I add a empty DisplayObject3D at the position of the furthest point/vertex on the grid with y set to 0. Then I calculate the position on the screen with calculateScreenCoords and get the y-position.

Fog demo

Thanks for listening, next time I will get some water into the scene.

2010
03.12

The sky is just a plain sprite with gradient fills. Wanted to keep the polygon-count lowest possible and render process fast. One layer for the sky and one for the sun. A more accurate way of solving this would be a regular sky-box, but I used a fixed angle with the camera, so I thought that was overkill. And maybe hard to create the sky texture dynamically.

The cloud layer is put inside the sky sprite with rotationX set to 80. This was my first time trying out the perspectiveProjection in Flash 10. I found it quite problematic to get it right, especially when  I tried to draw the sprite. But I’m sure that’s only my lack of experience. Maybe I should have added the clouds as a material on a PV3D-plane to get the correct perspective.

The clouds is, once again, a Bitmap with Perlin noise, with a custom paletteMap assigned to it. This time the alpha value was the key to create the clouds.

I found a simple way to add volume with a bevel-filter on the cloud container. Move the sun to see the effect. I still look for a better way to render nice volumetric clouds.

sky demo

Future improvements:
- Volumetric clouds
- More than one cloud layers.
- Cumulus-clouds along the horizon.
- Sun bursts

2010
03.11

In the previous post we got our mesh to work with. That has to be filled with colors, light, shadows and details to come to life with a texture. I’m using a few layers to create this and will explain them here.

Color

First a “base” layer with a color ramp mapped to a clone of the height-map with paletteMap. The range 0-255 of possible colors is a little bit low, so a blur-filter is applied to smooth it out as a quick interpolation. I’m not really sure it helps though, have to check that.

Color demo

Lightmap

While creating the example for the self-shadows below I rewrote it completely. And that trigged me to experimenting with a normalmap to get some volume and details to the texture. I found stok3d, a great library by David Lenaerts. I am so amazed of the people actually creating this stuff, and I salute him and the community for sharing their knowledge.

With the NormalMapUtil and the PhongNormalMapShader and 20 lines of code it was far simpler than I imagined to add a lightmap. (Or do I have to call it a bump-map?) It is powered by pixelbender, so it’s pretty fast, so this effect is applied even in edit-mode. To get the details I want, the size of the lightmap have to be huge. The solution to that was having different resolutions when editing and rendering, like with the self-shadows. And add a blur filter to smooth things out.

Here you can see how it works with a heightmap:

Lightmap demo

…and on the mesh. Select the shadow/light-tab, click and drag the sun around to see the sun affecting the light.

Lightmap on terrain demo

Self-shadows

One more way of adding volume to the terrain is to add shadows. Regarding self-shadows I found some code written in C++ that is based on a method called “the strider technique“. It’s a simple type of directional light ray-tracing (or raymarcher ) that compare the height on the terrain with the height of a ray traveling across the height-map. If an intersection is detected along the ray you got a shadowed pixel. I’m sure there is way smarter and faster techniques than this though. This code was only using a light-source from 0,45 or 90 degrees. But I made a little trick to set the direction of the light. I think that it would be to slow to calculate the angle of the ray (with interpolation and stuff). So I just rotates the heightmap before the calculation is taking place, and rotate it back afterwards. One downside is that the bitmap that is calculated has to be larger for the rotated image to fit and therefor taking more time to calculate. My optimization-skills is just terrible, so if anyone want to try to make it faster, here is the source.

I really miss the GPU-support and multi-threading on this one. On large maps it’s pretty slow. Is there a way to achieve a similar effect with pixelbender? To keep the editing-mode up to speed I use different sizes of the map in edit and render-mode.

Gamedev.net have a great resource of documents and examples: http://www.gamedev.net/reference/list.asp?categoryid=188

Here is a couple of examples of this:

shadows on terrain demo

Future improvements

- Better and faster algorithm, pixel bender maybe?
- Soft-shadows. Slower, but more details.
- Optimization

Details

A layer with a tiled BitmapMaterial is blended on top of the terrain in a second pass to get high resolution details. For first time a bitmap-asset is used. One idea is to select different type of bitmaps to get different characteristics. Or just use a regular noise-bitmap generated in flash. Will try that later.

The same asset is used once more in another layer, this time without tiling. This happens to add a kind of erosion to it. But I admit it’s wishful thinking, real erosion effects should be water-trails, wind, rain and such.

Texture details demo

All layers together

Lets see how it looks. Try to change colors, details, the amount of shadows and lightmap-blending. The high resolution texture is put on top of the grid in a separate viewportlayer, so that is only visible under the “Texture”-menu.

Texture combined demo

Future improvements:

- Refactor the pipeline for blending textures. Better control over the blending between different layers.
- More features to modifying the height-map. Different noise types for example.
- Load elevation data and textures from Google earth or other API:s.
- Slope detection
- Splat textures, use a alpha mask to reveal different textures at different conditions (like slopes or another Perlin-noise bitmap as mask)

2010
03.10

The first step was to create a terrain to play with. For that I needed a heightmap. There is lots of ways for creating them, like “The Diamond-Square Algorithm”, Fractals, draw by hand  or even use real world elevation from satellite data. But a simple and common way to get a procedural terrain is by using Perlin noise, a  feature built into flash. Generating a heightmap and apply it to a grid is pretty straight forward and there is a lot of examples around, so I wont explain it in depth here. Here you can find a list of excellent examples:

http://bruce-lab.blogspot.com/2009/01/terrain-rendering-in-flash.html

I wanted to make it simple to create and modify the terrain, without having to expose to much of the process. One of the great things about  procedural generation is that it’s completely parametrized, so you can save all the settings in a small format.

Try the following  example to see a example of a mesh with a heightmap attached. You can drag the mesh around to change the offset-parameter. The “rockiness”-slider is controlling the number of octaves used in the Perlin noise. By manipulate the height-map with filters, I can get various effects. I could add a much more features here, but I keep it simple for now, so I can continue with all the other features in the tool first.

Simple geometry demo

There are also different approaches for generating the mesh. I use a regular PV3D-plane, but I found a very interesting article about delaunay triangulation (read about it here). Maybe I look more into that later on.

Future improvements

- More features to modifying the height-map/geometry. Like masks, filters.
- Extend the  noise generation with more advanced features like voronoi, ridged noise, terrace and erosion.
- Loading of external height-maps maybe?
- Delaunay triangulation?

Basic stuff. Lets give the terrain some clothes in the next post about texturing.