Der Schmale - David Lenaerts’s blog

Flash Platform Experiments

More Stok3d: Parallax mapping & Water shading

Tags: , , , , , , , , ,

waterToday’s update on Stok3d is perhaps not as useful as the previous post, but I certainly had fun working on it. Or as we say in Dutch with a word blatantly stolen from German: it’s “spielerei”.

Demos:

I’m going to post the demos first this time. Saves you some scrolling effort, because the explanations below are rather boring ;)

  • Parallax Mapping : Move and turn towards the edges of the screen to see the extrusion of the texture best. A PhongFilter is added as a second filter, making it slower but the effect becomes more obvious.
  • Water Shading 1 - Ocean : Reflects or refracts light depending on the view angle and the surface relief. It animates a perlin noise filter to generate a water heightmap.
  • Water Shading 2 - Ripples : Same thing, but with a simple drawn ripple effect. The difference between refracted and reflected light is more obvious here.

Edit: Even if you have Flash Player 10, you still might get an update request. That is because these demos require the version of 10.0.22 concerning recent Pixel Bender bugfixes.

The source code for these demos can also be found on Google Code.

Useful updates

Some updates I did involved some bugfixes and performance-related updates. I also added a NormalMapUtil class, which provides a basic API to generate and manipulate normal maps. The main features are the generateFromHeightmap and drawFromHeightmap methods. Since height maps (or bump maps) are generally easier to come by (and to make), these methods generate a normal map for you. generateFromHeightMap creates a new BitmapData, drawFromHeightMap uses an existing BitmapData that you provide (useful if you need to generate one on every frame). The NormalMapUtil class furthermore allows you to invert the components of the normals, in case a normal map reflects the light in the wrong directions.

Water Shading

A new shader filter that was added is the WaterShadingFilter. If you remember your high school physics, depending on the view angle, the surface either reflects the light or lets it pass through and refracts it (which is called the fresnel effect).  To put it simply, when looking at water at a shallow angle, it seems like a very reflective surface, but when looking straight down into it, you can see through it but it’s a distorted view. The reflection uses a combination of environment mapping and phong shading, while the refraction is a simple displacement mapping technique. The DisplayObject to which the filter is applied is used as what’s underneath the surface, ie: the refracted light. The ripples seen in the demo are not made by the filter, but are custom written to manipulate the normal map.

Parallax Mapping

Another new filter is the ParallaxFilter, which performs (you guessed it) parallax mapping. It’s a technique like bump and normal mapping, in the sense that it tries to give more depth to a 2D texture. It does so by displacing texture coordinates based on a height map and view direction to the coordinate that it would normally have in 3D space. This causes the texture to look extruded and more detailed. For more (and better) information, check the article on wikipedia. Stok3d implements an iterative variation. It’s a bit slower but takes care of overlap issues and can handle sharp edges.

That’s it! For now, it’s back to Farbe, and… some other things :)

Share and Enjoy:
  • Digg
  • TwitThis
  • del.icio.us
  • Facebook
  • Reddit
  • Netvibes
  • Technorati
  • Google
Leave a comment (9 comments)

Introducing Stok3d - More FP10 3D+Pixel Bender shading

Tags: , , , , , , , , ,

stok3d-envmapphongLast week I posted an example of Environment Mapping using FP10’s native 3D and Pixel Bender. The reactions were quite positive, which motivated me to push the concept a bit further and create more shaders using Pixel Bender. These new additions all work in the same fashion, ie. as Filters which need to be updated whenever the target object (or if provided: light position) changes.

I created a project on Google Code for this, dubbed Stok3d (as I was positively stoked at that specific point in time). It’s a mini-library at this point, but in the future there’s potentially more to it than shaders; Z-sorting for instance: although it has been done already, it wouldn’t be a bad idea to create something specifically for Stok3d and have more functionality in one place. But… zat’s for ze futuah! At least for now, it will be easier to commit bugfixes and updates.

Demos

In the order from low cpu usage (and less visually interesting) to high cpu usage (and more interesting):

* Although Stok3d is distributed under the GNU GPLv3 license, the textures are NOT covered by this license. In particular, the blast door and hangar door textures, normal maps, and specular maps are made by Florian Zender (http://www.florianzender.com) and are used with his kind permission. Check out his work, it’s quite impressive! :)

Source

The source for the examples as well as the library can be found on Google Code. It’s available over svn or as a downloadable archive.

Share and Enjoy:
  • Digg
  • TwitThis
  • del.icio.us
  • Facebook
  • Reddit
  • Netvibes
  • Technorati
  • Google
Leave a comment (12 comments)

Spice up your postcard 3D with environment mapping

Tags: , , , , ,

envmapSince Flash Player 10 introduced native 3D functionality, the world of “postcard 3D” rejoiced as doing simple 3D tasks became much easier… Just as long as it did not involve z-sorting or shading effects.

The z-sorting has been tackled before, and here’s an attempt at implementing the second idea. Partly out of boredom and partly because I needed it as a first step towards another experiment, I created a simple cubic environment map effect, just in case you’d want your surfaces to be reflective. The filter itself is using Pixel Bender - what a surprise!

There’s some other possibilities I’m thinking of (phong shading for example), but it’d be good to know if there actually is any interest in stuff like this. I don’t want to be wasting my time either ;)

Cubic Environment Maps

Environment mapping is essentially a fake but relatively fast way to give the illusion of surface reflection. There are two common approaches: spherical and cubic mapping. The first maps the environment texture surrounding the scene on a sphere before mapping it onto the surface, the latter does it using a cube. Spherical mapping is usually faster and easier to use (it only requires 1 or 2 textures instead of one for every face of the cube), but sadly it doesn’t look very natural on a flat surface. Cubic mapping, on the other hand, looks better and is more commonly used these days. For more information, check this article on wikipedia.

So what do you need? Basically, you need to find a cube map and divide it up into 6 seperate images as illustrated below. You can assign these images to the EnvMapFilter class constructor.

cubemapWhen changing the surface position, scale or rotation, be sure to call the update method and reassign the filter to the target DisplayObject. All this is shown in the source.

Normal maps

It’s not a requirement, but if you want, you can assign a normal map to the filter. For every pixel, normal maps indicate the slope of the surface at any point and cause the reflections to be distorted. This gives the surface the appearance of having relief. A quick search on google or some texture libraries should yield plenty of them :)

Blabla yeah whatever!

Okay okay, enough chatter.

  • Demo - just follow the instructions (FP10.0.22 required, so you might get an upgrade request)
  • Source

Enjoy!

Share and Enjoy:
  • Digg
  • TwitThis
  • del.icio.us
  • Facebook
  • Reddit
  • Netvibes
  • Technorati
  • Google
Leave a comment (7 comments)

3D smoke: taking Pixel Bender to the next dimension

Tags: , , , , , , ,

smoke3dOne final thing I wanted to achieve with smoke effects is to port the 2D simulation to 3D. Early results in pure AS3 were pretty disappointing, so again I turned to Pixel Bender and its speedy goodness. Still, the main obstacle was of course performance. The first step was to optimize the original 2D version by doing more in a single filter, throwing out some repetitive calculations performed per pixel, etc. And obviously, adding an extra dimension means more calculations. This system is grid-based, so the amount of nodes increases a lot! As a result, the grid size is reduced to 18×32x12 , which is leaning dangerously close to the realm of visual crud. Still, as an experiment, I consider it acceptable, and it’s using some tricks that might be worth sharing. Perhaps someone can do something better with this :)

I’ll explain a bit on how it works since I usually forget that part (if you’re not interested, just scroll down a bit). The actual fluid solver is based on the work of Jos Stam, and a lot has been written on the subject already.

3D textures

Pixel Shaders for 3D graphics such as GLSL have support for 3D textures. Since Pixel Bender is made for 2D, we have to find a different way to map a 3D grid to work with Pixel Bender. The solution is so straightforward that it’s hardly worth mentioning, but since I haven’t seen it done before, I will explain it anyway. All slices of the texture/grid along the z-axis are simply placed next to eachother, as pictured below:

smokeslices
Analogous to the representation of a 2D texture in a 1D array, the 2D coordinates are simply found by coord2D(x,y,z) = (x+gridWidth*z, y), or in a 1D array as coord1D(x, y, z) = (x+y*gridWidth*gridDepth+z*gridWidth). Told you it’s pretty pointless :)

Rendering

My first thought was to consider the grid as a set of voxels and use a raymarching algorithm to render it, although I knew that would end up being way too slow. Luckily, I found a much simpler solution that worked well enough. Depending on the world axis that is closest to the view vector, the grid is sliced up in bitmaps aligned to the grid’s local axes. Looking at the “box” head on, it’s simply divided in planes (parallel to the local XY plane) from back to front, when looking more from the left, it’s divided from left to right (parallel to the local YZ plane) and so forth. Using these slices, they’re simply placed on the stage as Bitmap objects using FP10’s 3D functionality. Luckily, the lack of depth sorting does not seem like such an important issue to create the illusion of a volume filled with smoke.

Finally

I’ll close up with some good news: I think I’m done with smoke for now! It’s not a promise, though… Moving on:

  • The demo - The box is invisible at first, in the middle of the screen. Fill it up with smoke and it’ll become visible.
  • The source - To get performance up a bit, there’s some guerilla-style coding. Enter at own risk!

Thanks to Joa for running his AS3V-tool on it - I can’t wait for it to go public! I don’t think I caught all violations, tho ;)

Share and Enjoy:
  • Digg
  • TwitThis
  • del.icio.us
  • Facebook
  • Reddit
  • Netvibes
  • Technorati
  • Google
Leave a comment (12 comments)

One year later: a short retrospective

Tags: , , ,

birthdaypieThe first post on this blog dates from May 4th, 2008, so I thought it fitting to look back at the year that has passed since then.

Over the time I’ve done some experiments/projects that, when I look back at them, make me think “What was I thinking?!”. On the other hand, there are luckily a few of which I’m actually proud, or at least content with how they turned out - whether they were practically useful or not (which is not exactly always my goal). A lot of the things I did, I did as a way to learn. As such there was Wick3d, a (now defunct) basic 3d engine to rehash my algebra (actually, I worked on it some more after the last update without comitting anything to svn). And of course Pixel Bender came along, giving me a whole new area to explore, as did Alchemy.

I do feel I learned quite a bit, but at the same time it seems with everything I learn, there’s twice as much I still need to study. Feels like a constant battle against ineptitude, especially when talking to those who actually seem to know what they’re talking about ;)

Lastly, I’d like to pass some more updates on Farbe. I recently made some updates implementing oil paint and airbrush. There’s still so much work to do before it can go public, but soon it will be time to look for a Flex UI-designer/skin artist. If you know or are anyone with experience, send me a hoot with some examples! AS3/MXML/CSS experience is a must of course :) Just keep in mind, the project is free and will likely be open-sourced eventually (which is also a cheap way of saying: no money involved ;) ). If you follow me on Twitter, you might have seen some demo pictures being tweeted. Those that haven’t: here’s some previews of Farbe simulating pencils (1, 2), oil paint and airbrush.

Off towards another year! Thanks to all you readers!

Share and Enjoy:
  • Digg
  • TwitThis
  • del.icio.us
  • Facebook
  • Reddit
  • Netvibes
  • Technorati
  • Google
Leave a comment (2 comments)

Return of the ripples! Shallow water simulation with Pixel Bender.

Tags: , , , , , , , ,

shallowwater

When looking at my blog stats, the most popular post by far is the old Ripple effect I did some time ago, which was based on an old demoscene trick. For a while, I’ve wanted to do a more physically correct version based on shallow water equations. Since the watercolour effect I did was based on a similar variation (as well as the image bleeding in the previous post), I decided to throw together a quick test to see if it could be turned into a new iteration of the old ripple effect. It’s mainly done for sake of experimentation, and if you really want a ripple effect I suggest using the prior one. Although the dynamics are more interesting, this one is slower, but I’m pretty happy with the performance considering the amount of calculations and the grid size (the demo has a grid of 200×200).

  • Demo
  • Source - There’s a few parameters to play around with, but take care: the simulation might just blow up with extreme settings ;)

Some day I might try out a sim with the real shallow water equations, just in case you haven’t gotten violently sick from all the fluid simulations lately (I haven’t, as seems) :D

Share and Enjoy:
  • Digg
  • TwitThis
  • del.icio.us
  • Facebook
  • Reddit
  • Netvibes
  • Technorati
  • Google
Leave a comment (16 comments)

Image bleeding with water (Flash + PixelBender)

Tags: , , , , , , ,

Image BleedingThe last 2 months, I’ve been investing 99% of my free time into the next iteration of Farbe, turning it into a real Flex-based image editing tool simulating natural media. Although there’s nothing of the application itself that I can show yet, today I created another small proof of concept for it that I can make public.

One of the things lacking in the watercolour POC was that once a brush stroke was made, nothing could be done with it. I thought it’d be nice to still be able to add water once the paint was rendered and have the colours bleed out. Using much of the same physics as for the watercolours, I figured out an algorithm that was both adequate in speed (real-time) as visually effective enough to water down the image. As usual, much Pixel Bender was used. The multi-threaded nature of ShaderJob really proved its worth in this case. You can keep adding water without the simulation slowing down the interaction, even if the simulation itself gets slow when there’s a lot of wet areas to cover.

To get the most realistic results, settings such as “ink speed” and “water amount” should be kept low while slowly rubbing over the image. Higher levels are not natural and will look caricatural (reminding me of Kai’s Power Tools of old! ;) ).

So check it out! :)

Note that, even tho Farbe is not an open source project (or not yet at least), I’m providing the source for this POC - consider it a late Easter present ;) But do remember, it IS poc-style code!

In closing, I’ll leave you with a few updates on Farbe. First of all, the watercolour paint is quite a bit faster (unless, of course, you’re working on much bigger canvas sizes than the cheaply upscaled old version) and so far it seems it’s pretty bug free! Secondly, I recently finished a pencil and eraser tool which are looking alright. The rest of the time has been spent mainly on the user interface and typical paint tool functionality. I’m starting to feel quite overworked at the moment, but the app is shaping up so it’s worth it! I hope I’ll be able to give out some more tangible updates on all that soon :)

Share and Enjoy:
  • Digg
  • TwitThis
  • del.icio.us
  • Facebook
  • Reddit
  • Netvibes
  • Technorati
  • Google
Leave a comment (6 comments)

Strange visual results, pseudo generative art?

Tags: , , , ,

Last night, I had the idea to take part of the previous fluid solver, but instead of placing the “ink” in a grid, I’d replace it with particles and have those move according to the velocity grid. It would give a stronger impression of detail.

It didn’t look all that great from a realistic point of view, but I discovered that when I added permanent trails, things started to look more interesting, even tho I was moving further and further away from my initial idea. After some more experimentation, the result is some interesting pseudo-art (”pseudo” since I’m not an artist, and never will be ;) ).

I like how some of them turned out, but that’s coming from a guy who likes to look at pictures of strange attractors and spends too much time staring at his cigaret smoke :D

All of these were generated in Flash using Alchemy.

 

Share and Enjoy:
  • Digg
  • TwitThis
  • del.icio.us
  • Facebook
  • Reddit
  • Netvibes
  • Technorati
  • Google
Leave a comment (11 comments)

Experimenting with Alchemy: of Smoke, Milk, and Ink

Tags: , , , , , ,

Smoke and Milk simulationThanks to Ralph Hauwert’s blogpost pushing a baffling >300.000 particles using Alchemy, I finally got the much needed motivation to try out Alchemy myself. To be able to get started asap, I decided to return to something I’ve done before: fluid and smoke dynamics, but with a different algorithm (see Mike West’s article on Gamedev). It took me a while to figure it out, but it’s up an running! It’s a faster algorithm, but less physically correct.

While I typically would do most of these kinds of calculations in Pixel Bender, for the examples below, I decided to try it all in C and see how far Alchemy can be pushed. The grid is bigger than before, while the framerate is steady around 20 on my machine. Ralph has suggested some improvements for the rendering step already (thx! ;)), so I’ll have some more experimenting to do :D

It was great to return to C, especially since it’s been 8 years since I’ve written my last line in that language. Quite a rush of nostalgia!

Source is included with the demos, tho it’s not the most reusable I’ve ever written :)

The HiRes FPS counter is done by Mr. Doob.

Share and Enjoy:
  • Digg
  • TwitThis
  • del.icio.us
  • Facebook
  • Reddit
  • Netvibes
  • Technorati
  • Google
Leave a comment (13 comments)

Flash Player 10 on the big screen!

Tags: , , , , , ,

durfontdekken

On a rare occasion, instead of posting code and experiments, I like to post some things I’ve done at my job. Especially when it illustrates a practical use of some of my earlier experiments. So here we go!

For a project for the University of Ghent at Nascom (via Saatchi & Saatchi), I had to create a front-end application to be displayed on a big 12m² billboard, placed in Ghent. Without going into too much detail of the whole concept (which you can read at the official blogpost), it consisted out of a set of mini-applications allowing people to text mobile messages and interact with the display (show messages, a poll, …). being all booked up, I had to sacrifice some free time to be able to work on it. The reason I did was the same reason I decided to use Flash Player 10: a perfect excuse to work on the earlier 2D cloth simulation and turn it into stage curtains on a whopper public screen. Blatant self-exposure? Nah :p

Below, you can see a video recording showing it in action. The curtains open up after someone sends a text to the service, showing a random picture or video. Apologies for the low quality, all we had was a photo camera, and led lights don’t like to be filmed :)

Thanks to Jan Nikolaas Gijsen for editing the video! And I promise, this will be the last cloth-related post - at least for some time :D

Share and Enjoy:
  • Digg
  • TwitThis
  • del.icio.us
  • Facebook
  • Reddit
  • Netvibes
  • Technorati
  • Google
Leave a comment (2 comments)

© 2009 Der Schmale - David Lenaerts’s blog. All Rights Reserved.

This blog is powered by Wordpress and Magatheme by Bryan Helmig.