Header image

I found some time to add a little bit more “D” to ND2D. Besides the regular “rotation” property which rotated around the z-axis, all nodes now have  rotationX, rotationY, rotationZ properties and are displayed via a perspective projection. It works similar to the Flash 10 2.5D API (Planes in space), could be useful for some fancy transition effects.

Second, I added a few properties to change the appearance of textures. You can strech textures now and define how they should be sampled. The API let’s you choose how the texture is filtered, if mipmapping should be used and how the mipmap filtering should be. I created four predefined quality settings: LOW, MED, HIGH and ULTRA. Have fun:

I never really introduced the TextureRenderer of ND2D and what possibilities you have, when using it. The TextureRenderer does what the name suggests: It renders a display object (Sprite2D, etc.) and all subsequent objects onto a Context3D texture. The cool thing is, that you are able to draw your entire scene to a (fullscreen) texture and add some post processing effects, by writing a new material / shader and displaying it via a standard Sprite2D.

Here’s the plain scene without post processing:

… and here with a small “dizzyness” post process shader:

I’ve added this test to the examples incluced in the ND2D sources. You can see the live running example here (test #18).

ND2D – Stage3D Masks

September 2nd, 2011 | Posted by lars in Actionscript | Molehill / Stage3D | ND2D | Source - (6 Comments)

Another feature I really wanted to implement in ND2D were masks. Just like the setMask() method in flash. In Stage3D (OpenGL), there is no such thing as a mask. You can display textured triangles, that’s it, but you know that nearly everything is possible with a pixel shader. So let’s start:

The idea of masking in a fragment shader is to grab the pixel color of your texture, then grab the pixel color of your mask, multiply the two colors and display the result. But how do we find the correct pixel in the mask? Our task is to find the right UV coordinates for the mask texture.

If you look at the above image, the mask is rotated and overlaps the sprite we want to mask. How do we find the correct pixel (UV coordinate) of the mask, that overlaps this orange pixel in the sprite? Somehow we have to map the position of the pixel in the sprite to the pixel in the mask and we can do that by transforming it between the different coordinate systems. In a vertex shader we calculate the final pixel positon from local space to world space. The idea is to map this pixel in world space back to the local coordinate system of the mask. This way it’s pretty easy to find the correct UV coordinates. Let’s do a simple actionscript test:

// this is the top right corner of our sprite quad.
var v:Vector3D = new Vector3D(128, -128, 0, 1);
 
// this is the sprites matrix, translated a bit
var clipSpaceMatrix:Matrix3D = new Matrix3D();
clipSpaceMatrix.appendTranslation(100, 0, 0);
// this is the masks matrix, it's in the same position as the sprite
var maskClipSpaceMatrix:Matrix3D = new Matrix3D();
maskClipSpaceMatrix.appendTranslation(100, 0, 0);
// this is the masks size
var maskBitmap:Rectangle = new Rectangle(0, 0, 256, 256);
 
// invert the matrix, because we want to map back from world space to local mask space
maskClipSpaceMatrix.invert();
 
// transform our vertex from local sprite space to world space
v = clipSpaceMatrix.transformVector(v);
[trace] moved to clipspace: Vector3D(228, -128, 0)
 
// transform world space vertex back to local mask space
// the result is the same vector of course, because the positions of mask and sprite are equal
v = maskClipSpaceMatrix.transformVector(v);
[trace] moved to local mask space: Vector3D(128, -128, 0)
 
// calculate the uv coordinates from the local pixel position
v = new Vector3D((v.x + (maskBitmap.width * 0.5)) / maskBitmap.width,
                 (v.y + (maskBitmap.height * 0.5)) / maskBitmap.height,
                  0.0, 1.0);
 
// the result is what we expect, the top right uv coordinate:
[trace] local mask uv: Vector3D(1, 0, 0)

Porting this idea to a shader is pretty straight forward. Let’s code a PB3D Material Shader:

void evaluateVertex()
{
     interpolatedUV = float4(uvCoord.x + uvOffset.x, uvCoord.y + uvOffset.y, 0.0, 0.0);
 
     float4 worldSpacePos = float4(vertexPos.x, vertexPos.y, 0.0, 1.0) * objectToClipSpaceTransform;
     // maskObjectToClipSpaceTransform is the invertex clipspace matrix of the mask
     float4 localMaskSpacePos = worldSpacePos * maskObjectToClipSpaceTransform;
 
     // halfMaskSize.xy is maskBitmap.width/height * 0.5 passed as a parameter
     // invertedMaskSize.xy = 1.0 / maskBitmap.width/height passed as a parameter, because divisions are not properly working in the current pb3d release
     interpolatedMaskUV = float4((localMaskSpacePos.x + halfMaskSize.x) * invertedMaskSize.x,
                                 (localMaskSpacePos.y + halfMaskSize.y) * invertedMaskSize.y,
                                  0.0, 0.0);
}
 
void evaluateFragment()
{
    float4 texel = sample(textureImage, float2(interpolatedUV.x, interpolatedUV.y), PB3D_2D | PB3D_MIPNEAREST | PB3D_CLAMP);
    float4 texel2 = sample(textureMaskImage, float2(interpolatedMaskUV.x, interpolatedMaskUV.y), PB3D_2D | PB3D_MIPNEAREST | PB3D_CLAMP);
 
    result = float4(texel.r * color.r * texel2.r,
                    texel.g * color.g * texel2.g,
                    texel.b * color.b * texel2.b,
                    texel.a * color.a * texel2.a);
}

If you don’t want to use PixelBender3D and like to ‘torture’ yourself with AGAL, you can write the same shader this way:

/*
vertex shader:
 
vc0-vc3 = clipspace matrix of sprite
vc4-vc7 = inverted clipspace matrix of mask
vc8.xy = half mask width / height
vc8.zw = mask width / height
va0 = vertex
va1 = uv
*/
 
m44 vt0, va0, vc0           // vertex * clipspace
m44 vt1, vt0, vc4           // clipspace to local pos in mask
add vt1.xy, vt1.xy, vc8.xy  // add half masksize to local pos
div vt1.xy, vt1.xy, vc8.zw  // local pos / masksize
mov v0, va1                 // copy uv
mov v1, vt1                 // copy mask uv
mov op, vt0                 // output position
 
/*
fragment shader:
*/
 
mov ft0, v0                                // get interpolated uv coords
tex ft1, ft0, fs0 <2d,clamp,linear,nomip>  // sample texture
mov ft2, v1                                // get interpolated uv coords for mask
tex ft3, ft2, fs1 <2d,clamp,linear,nomip>  // sample mask
mul ft1, ft1, ft3                          // mult mask color with tex color
mov oc, ft1                                // output color

The result is visible here: ND2D – alpha masks (Move your mouse over the crates). I added one more feature: You can set the alpha of a mask, that means that you can specify how much the mask affects the sprite. In the demo above the alpha fades from 0.0 to 1.0. Since we’re using all four color components in our calculations (r,g,b,a), we can not only mask the alpha, but all color channels. I don’t know if this it’s a “nice thing to have” or if it will get annoying when you use sprites as masks in your game and need to provide an extra image for that. Just let me know :) Here is the example: ND2D – disco color masks.

Cocos2D Particle System Sources

March 21st, 2011 | Posted by lars in Cocos2D | iPhone | Particles | Source - (1 Comments)

Since I’m receiving questions about the particle system I used in my FluidToy 2 quite often lately, I thought I just release the sources here.

The particle system is based on a CCNode and works similar to the existing Cocos2D particle systems. The main difference is, that you can control the position and velocity of each particle. Please note that this system is not very optimized and lacks in flexibility since I just built it for FluidToy 2 and it was never meant to be more general. In other words: The code is a bit dirty! But feel free to play around with it, modify it and make use of it (and let me know what you’re making out of it).

There are two different systems: The SimpleParticleSystem, which draws points of any size or a point sprite using a texture. The second one is a LineParticleSystem, which will draw line particles. If you initialize the system with a size of 1000, you’ll have 500 lines, because a line consists out of 2 points (Wow, you never imagined that, did you? ;)). So if you loop through the particles, be sure to move only every second particle, the other one will follow with a small delay.

Download: Cocos2DSimpleParticleSystem

It works like every other CCNode:

particles = [SimpleParticleSystem node];
[particles initialize: 1000 width: size.width height: size.height];
[particles setTextureByString: @"particle_small.png"];
[self addChild: particles];
 
Loop through particles:
 
while(count < particles.particleCount)
{
   p = &particleAr[count];
   p->dir.x += CCRANDOM_MINUS1_1();
   p->dir.y += CCRANDOM_MINUS1_1();
   ++count;
   ...
}

Have fun!

New example by accident

February 18th, 2009 | Posted by lars in 3D | Experiments | Flash 9 | Source - (4 Comments)

This is what came out as I was testing to implement a custom renderer in my engine (The sources are available in the google code repository).



(space = fullscreen = more fun)

F10 Astro Blackhole

September 30th, 2008 | Posted by lars in 3D | Actionscript | Experiments | Flash 10 | Particles | Source - (4 Comments)

The Flash 10 beta player is out for a while and I found a few minutes to try out the new native 3D effects. You can get quite nice and fast results out of the new API if you only want to display flat 2D planes in 3D-space:


(Space = fullscreen, Download source, Flash Player 10 needed)

Good news everyone! I packed everything together, cleaned up a bit and created a google.code project for my 3D engine. Since it became popular under the name ‘nulldesign’s 3d engine’ I call it ND3D from now on ;). I will post additional infos, more examples and future developments here in my blog and on the project page. So long…

3d engine website

July 11th, 2008 | Posted by lars in 3D | Source | Talk - (2 Comments)

I just got a mail from Mr.Doob, he made a 3d line clock for the D///FEST 2008 website with my 3d engine. You can download the sources on the website:

Btw.: I’m planning to put the engine up to google code and continue working on it. It will stay lightweight, small and simple!

About some time ago I started to code my own 3D engine in flash. Derived from a small AS2 project, I challenged myself to built my own flash 3D engine. So I took out my good old Actionscript Animation Book and opened the 3D chapter. Very soon I could move a cube around. A few pages later I learned how to implement simple dynamic lighting. The next challenge was to get texture mapping to work. Since flash still can’t distort images, you need a workaround. After I found these great examples: Seb Lee-Delisle’s flash texture maps and Andre Michelle’s texture examples it was done. Somewhere inbetween I switched to AS3, which was quickly done. Meanwhile Papervision3D became very popular and I thought it didn’t make sense to continue evolving my engine. But since I came so far, I needed to find out how to implement a few effects like depth of field or additive rendering ;)

My engine shouldn’t and doesn’t compete with Papervision3D or Sandy3D, nor it has a very user-friendly API, no stunning effects or animation support, but I learned a lot while building it, understanding 3D to 2D rendering, optimizing the code for a few ms of extra speed (AS3 rocks!) or challenge problems with 3D rotations like gimbal lock and their solutions: quaternions. It’s just another 3D flash engine, at least I can say: I made it! ;)

It’s undocumented, there’s still a lot of work to do and it doesn’t have a cool name , but if you want to play around with it or just take a look how I set up this and that, feel free to download the sources (yes, the 3D ribbon example is included). And I’m always interested in what you think about it, so drop a comment or mail.

War of the fireflies

January 21st, 2008 | Posted by lars in Experiments | Flash 9 | Particles | Simulations | Source - (6 Comments)

Derived from one of my older experiments: Three different populations of fireflies are fighting for their survival. If a firefly encounters an enemy fly, it tries to convert it to their tribe. The converted fly looses lifepoints and eventually dies during conversion. For the “collision logic”, I used a slightly modified version of Grant Skinners AS3 Proximitymanager. You can download the source and play around with it here (but don’t expect beautiful code ;)).


(Space = fullscreen, as usual)

F9 Particles

November 23rd, 2006 | Posted by lars in Experiments | Flash 9 | Particles | Source - (8 Comments)


Sources available here.

AS3 particle system. 5000 particles with random motion based on a noisemap (Press any key to view the map) Click to change to another random map. Launch!