Der Schmale – David Lenaerts’s blog

Flash Platform Experiments

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 ;)

Leave a comment (12 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

Leave a comment (35 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.

Leave a comment (18 comments)

Cloth simulation modifier in AS3Dmod

Tags: , , , , , , , , ,

 

flagI was recently invited to create a cloth modifier for AS3Dmod by Bartek Drozdz, similar to the 2D version I did earlier. In the unlikely case you haven’t heard about it before, AS3Dmod is a cool modifier library compatible with the most popular 3D Acionscript engines (Papervision3D, Away3D, Sandy and Alternativa3D). To put it simply, it takes existing 3d meshes and changes its shape on a per-vertex basis, and also allows you to animate them without needing an animated model. Lucky for me, as I was interested in doing a 3D version, and this was the perfect setup to do it in :)
 
The cloth modifier provides some methods and functions to adjust its behaviour (rigidity, air friction) as well as to apply external forces such as gravity or wind. You can also set boundaries to act as fake walls or floors. This modifier works best with meshes that have a flat edge, such as planes, boxes/cubes, cylinders, … This so they can be locked in place at an edge and actually give you something to look at instead of having a mesh that gets blown out of the view straight away :)
One last remark is that the cloth should be the first in the modifier stack. It needs its previous state, and any prior modifiers changing its state will not have any effect.
 
On to the demos!
  • Flag sim with parameters to play with (Papervision3D, 600 triangles): Demo | Source
  • Hanging cloth with fake floor and wind (Away3D, 450 triangles): Demo | Source
  • Strange cube being blown about (Away3D, 1200 triangles): Demo | Source
Get AS3Dmod on Google Code.
Leave a comment (13 comments)

Verlet + Newton + FP10 = Cloth Simulation

Tags: , , , , , , ,

clothA project I’m currently involved in inspired me to completely rewrite my old Curtain class into something more stable and versatile. Using a character physics method based on Verlet integration, and adding some properties for friction and gravity, it resulted in a 2D cloth simulation (at least after some updates I just did since I needed to get away from work for a bit). The curtain itself is drawn using the new drawTriangles API for Flash Player 10.

Anyone interested in Verlet integration (or scripted animation in general) should check out Keith Peters‘ book AdvancED ActionScript 3.0 Animation.

On to the demo! Right-click to view source. Not commented due to lack of time, but it shouldn’t be too hard to figure out :)

Leave a comment (13 comments)

Flash watercolour simulation (using PixelBender)

Tags: , , , , , , , , , ,

farbe-watercolour

Something I’ve been thinking about doing for a long time is imitating real artistic media, in particular watercolours. Not because I’m an avid watercolour painter (last time I’ve touched them was in kindergarten), but because I think it’s an interesting dynamic. Since it is mainly fluid dynamics, the idea resurfaced after my previous fluid sims. And luckily, with Pixel Bender, I can finally do this kind of thing! This paper by Cassidy J. Curtis et al was great, tho it also caused me to loose some time figuring out some errors. Finally I came up with something, dubbed Farbe (simply German for ‘colour’). One thing I dropped was the interaction between different strokes, because that would kill the cpu easily enough.

For a change, there’s no source of this, and for a few reasons. First of all, it’s a mess and needs to be optimized. Apart from that, I might just add on to this before I release anything (hence the project name ‘Farbe’).

The picture on the left is my poor imitation of Joan Miró’s Barcelona ‘92 poster (Strepie, this one’s for you ;) ), so ignore that and create your own :)

See Farbe in action

Leave a comment (24 comments)

Smoke/fluids simulation using Pixel Bender – part III

Tags: , , , , , , , ,

smoke-v3The third pass at smoke/fluids simulation again looks quite different from the previous two attempts, but this time it’s stable both when keeping still as while moving. Not surprisingly, as the current approach is more like Stam’s fluid solver. The downside is that it’s much less processor-friendly: every new step (adding forces, diffusion, advection, updating boundaries, …) needs the previous step to be completed over the entire velocity or pressure field. As a result, this simulation is using 9 different Pixel Bender kernels. In total, 49 pixel bender filters are executed per frame, some more intense as others, along with some BitmapData methods. Consequently, the grid size needs to be scaled down a lot  (64×128 in the example). All in all, I’m still surprised that it doesn’t slow down to a crawl!

The FluidBitmap class has some properties such as timeStep, buoyancy and viscosity, which can influence the look and tempo of the fluid, but can affect the stability of the solver due to precision errors using BitmapData. There is support for forces, encoded in a BitmapData, similar to the velocity field (red = x, green = y). Maybe some day, I’ll make working with these forces a bit easier, but for now I’ll focus on other things than fluids ;)  

The demo – A smoke simulation using positive buoyancy. Click to show the red and green channels representing the velocity field.

The source

Oh, and a happy new year! :)

Leave a comment (18 comments)

Smoke dynamics in Pixel Bender – part II

Tags: , , ,

Last time, the results of simulating smoke were a bit instable and the visual result was a bit bland. Since then, I’ve been irked constantly by spotting smoke everywhere in the – real – world. And sadly, I have to admit I’m a smoker, so there’s no escape from that! :D So back to research! Stam’s work proved a great inspiration, but his approach needed about 20 iterations over both the density and velocity field. When using BitmapData, you might as well give up right there. Trying something quite different, I decided to combine this approach (I knew I made that blog post for a reason!) on these equations. More or less; I took some “artistic license” (which is a euphimism for not knowing my physics properly :D ) . The result is something that looks quite horrible when keeping the smoke source in the same position, but it’s much more interesting when moving it about.

Demo and source (proof of concept style, beware!)

Still not exactly there yet, so the quest continues!

Leave a comment (1 comment)

Pimpin’ Lava curtains

Tags: , ,

The curtain class has been in the Nascom AS3 library for a while now, but I never felt quite happy with it. Now, after a few updates, it’s easier to get some curtains on stage and the texture and some quality settings can be changed after instantiation. And, who knows if it’s useful, it now supports animated movieclips, video, … In case of animated assets, they need to be on the stage. I’ll probably get back to it to fix that in some later stage.

To morph the images, it’s using my old DistortBitmap class, which can also be found in the Nascom library.

Check out the demo to see what it’s all about! ;)

(and there… www.derschmale.com is now public ;) )

Leave a comment (1 comment)

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

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