More Stok3d: Parallax mapping & Water shading

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

15 thoughts on “More Stok3d: Parallax mapping & Water shading

  1. Pls check your version checking, I have:

    MAC 10,0,12,36

    and I was told I needed to upgrade flash….

  2. I know it’s a bit confusing, but you need 10.0.22 . The filters all use Pixel Bender, which seems to have had some quirky bugfixes over the time :) I’ll edit it into the post.

  3. it really looks like… water?! Beats the old “Lake applet” by a long shot! Just wondering, would it be possible to somehow nest this sprite in another one and mask out the “edges”?

    In any case looking forward to trying out generateFromHeightMap() !

  4. The edges are quite annoying, but having PB check the boundaries for clamping is too much of a performance hit. Nesting sprites shouldn’t be a problem, but the one that has the filter assigned to it should be the one moved in 3D space (for now at least), so I guess the masking’s not going to help in that case. Now there’s something for a next update, support hierarchy ;)

  5. That’s good. Any thoughts on adding a floating/bobing object on the surface. I’m specifically researching ways to float objects in a water environment for an iPhone app.

  6. David ! Where is an girls and palms?! I want to drink a bit little wine )))
    Love this quardatique water )) David don’t stop!

  7. ok im awake again, the question now is how to use this as a MovieMaterial, i used the
    mysprite=new Background();
    bData= new BitmapData(mysprite.width, mysprite.height, true);
    bData.draw(mysprite);
    bmap = new Bitmap(bData);

    to use it as a BitmapData for awya3d material, but dint work.

    used the .swf as a movie material, no luck either

    trying to make the class inside of an away project i got the plane in the scene, but cant use it as a material, what im missing?

  8. Well, for one these weren’t made to be used as materials in 3D engines, just as filters for Flash 10 DisplayObjects in 3D space.

    You could place on stage an invisible version of a MovieClip with Stok3d filters assigned to it. Use that as the source for the MovieMaterial. Every time you change the target Away3D model, adapt the DisplayObject to match the position and rotation.

    If the 3D model is anything other than a plane, you’re out of luck because the lighting will make no sense at all. Aside from that, I must say that it will probably be way too much of a performance hit to be useable as such.

  9. no luck, btw what i was also trying to do is to set a .swf with the water, and tryin to put as the moviematerial to he plane, but it doesnt goes 3d :s, guess ill have to w8 to see if theres some progress on that. sniff sniff… broken dreams…

  10. Pingback: Fresnel reflective shading with Away3D | Der Schmale - David Lenaerts's blog

Leave a Reply

Your email address will not be published. Required fields are marked *