Testing out Pixel Bender

Use the mouse to position the lightsource.  This demo’s normal map was made by following an excellent tutorial on producing normal maps from photographs by Ryan Clark.  The shader is of my own design but is nothing special at all, and I think it’s slightly buggy still working correctly.

On my machine this runs at a capped 50fps, whilst trying to do the exact same pixel calculations ‘manually’ with bitmapData methods manages 2 to 3 fps.  I would post a SWF of the manual version too but it has a decent chance of timing out the flash plugin.

This is all thanks to the magic and wonder of Pixel Bender, which lets you write your own shaders/filters/blendmodes for use in a range of Adobe’s products – including Flash.  Basically it lets you write an operation that will be executed on every pixel in a given image.  The good bit is that the execution of that operation will take advantage of the parallel nature of the task and split its operation into threads, so showing a huge increase in performance from the single-thread bound Flash Player.  You may also read about how Pixel Bender pushes its calculations on to the GPU, but it actually doesn’t do that when executing in Flash.

Sadly a significant amount of its features are disabled for Flash, and there are still plenty of oddities and inconsistencies that even in my brief testing I’ve come up against.  Despite that, I think it’s worthy of investigation simply because of the huge increase in performance it can give – it’s also free and works fine without needing to use the Flash IDE.

Once I’m a little more certain that I’m doing things right I’ll write up an introduction tutorial for using Pixel Bender in Flash projects.

Edit: Here it is.

4 thoughts on “Testing out Pixel Bender

  1. This is one of the smoothest, most sublime implementations of Normal mapping using Pixel Bender that I’ve seen on the net. Would it be too much to ask for a link to your source code on this?

    • You’re very kind, although there’s no false modesty in my saying that there’s nothing special about the shader :)

      I think much of the effect is due to using a photographically generated normal map (although it does also cause some slight artefacts where there were shadows in the photo.)

      Here is the source for the shader in Pixel Bender to produce a “light map”, which is layered over the original unlit image to create the full effect.

      <languageVersion : 1.0;>

      kernel NormalMapper
      namespace : \"\";
      vendor : \"Salt\";
      version : 1;
      description : \"Produces a light map based on a light source\'s position and a given normal map.\";
      input image4 normalMap;
      output pixel4 result;

      parameter float3 lightPosition
      minValue: float3(-500.0, -500.0, 0.0);
      maxValue: float3(+500.0, +500.0, 200.0);
      defaultValue: float3(60.0, 60.0, 60.0);

      parameter float3 lightColour
      minValue: float3(0.0, 0.0, 0.0);
      maxValue: float3(1.0, 1.0, 1.0);
      defaultValue: float3(1.0, 1.0, 1.0);

      float2 positionHere = outCoord();

      float3 toLight = lightPosition;
      toLight.xy -= positionHere.xy;
      toLight = normalize(toLight);

      float4 normal = sampleNearest(normalMap, positionHere);
      float3 normalVector = (normal.rgb * 2.0) - 1.0;

      //if you trust that your normal map is already normalised you can skip this for a performance boost:
      normalVector = normalize(normalVector);

      float normalFactor = dot(normalVector, toLight);

      result.rgb = normalFactor * lightColour.rgb;
      result.a = 1.0;

      I’ve also just posted a tutorial on how I implement shaders in Flash.

  2. Thanks so much for this, finding it super useful! One question I have, how are layering the normal map over the unlit image? Are you multiplying the images?

    Nvidia’s normal map plugin for Photoshop (just google “nvidia normal map plugin”) is also quite useful for creating normal maps.

  3. Hi!

    I’ve varied between a few methods for applying what I refer to as the “light map” to the unlit image. The light map is an image that represents how each pixel is illuminated: black for no illumination, white for full illumination. In the above example the light map is greyscale as it’s using just a single white light source, but it could have varied colours.

    Using Flash’s built-in BlendMode.HARDLIGHT works quite well, although you may want to lower the brightness of the light map first to stop the result being blindingly white in places.

    In the example here I think I am just multiplying the colours. I do it in another custom shader to let me adjust the calculation so that a 0x7f7f7f pixel on the lightmap will result in no change to the base image.

Leave a Reply

Your email address will not be published.

* Copy this password:

* Type or paste password here:

16,849 Spam Comments Blocked so far by Spam Free Wordpress