not sure why projectVector != projectVectors result but its close enough… wasted too much time trying to find out why they are not the same so any ideas on why that is – let me know!
In the demo above there are 3 buttons.
The first button arranges the content in a hbox style with a padding of 5
The second button arranges the content in a vbox style with a padding of 5
The third button arranges the content in a grid style with fixed number of columns (in brackets) and a padding of 5
So what happens when you click one of those buttons is the above function is called with a parameter “layout” based on which button was clicked.
The sprite “container” holds 5 simple display objects and the functions hbox/vbox/grid all operate automatically on the children of the 1st parameter.
To to arrange display objects horizontally or vertically or in a grid only takes one line of code…
Event functions
//adds a listener to the stage for Event.RESIZE and calls the onResize function when triggered
addListener(stage, Event.RESIZE, onResize);
//adds a listener to mc1 for MouseEvent.CLICK and calls the handleClick1 function when triggered
addListener(mc1, MouseEvent.CLICK, handleClick1);
//notice how no event parameter is needed in the functionprivatefunction handleClick1():void{trace("handleClick1");
}//adds a listener to mc2 for MouseEvent.CLICK and calls the handleClick2 function when triggered//but also passes mc2 in as a parameter
addListener(mc2, MouseEvent.CLICK, handleClick2, mc2);
privatefunction handleClick2(mc:Movieclip):void{trace("handleClick2", mc);
}//adds a listener to mc3 for MouseEvent.CLICK and calls the handleClick3 function when triggered//but also passes mc3 as a parameter and tells it to also return the event as a parameter//thanks to the return event flag (the true after mc3)
addListener(mc3, MouseEvent.CLICK, handleClick3, mc3, true);
privatefunction handleClick3(mc:Movieclip, e:MouseEvent):void{trace("handleClick3", mc, e.ctrlKey);
}//adds a listener to mc4 for MouseEvent.CLICK and calls the handleClick4 function when triggered//but also passes an array containing mc4 and an alpha value
addListener(mc4, MouseEvent.CLICK, handleClick4, [mc4, 0.5]);
privatefunction handleClick4(array:Array):void{
array[0].alpha = array[1];
}//adds a listener to mc5 for MouseEvent.CLICK and calls the handleClick5 function when triggered//but also passes the parameters mc5 and 0.5 in sequence thanks to the apply parameters flag (the true at the end)!
addListener(mc5, MouseEvent.CLICK, handleClick5, [mc5, 0.5], false, true);
privatefunction handleClick5(mc:MovieClip, alpha:Number):void{
mc.alpha = alpha;
}//adds a listener to mc6 for MouseEvent.CLICK and calls the handleClick6 function when triggered//but also passes the parameters mc6 and 0.5 in sequence and also sends the event though
addListener(mc5, MouseEvent.CLICK, handleClick5, [mc5, 0.5], true, true);
privatefunction handleClick6(mc:MovieClip, alpha:Number, e:MouseEvent):void{
mc.alpha = alpha;
trace(e.ctrlKey);
}//notice how no event parameter is needed in the functionprivatefunction onResize():void{//aligns this centrally on the stage (using the align function included in bwhiting.swc)align(this, stage);
}
This has real potential to save some typing it is also pretty powerful to if you use your imagination.
i.e.
//quick dragging! - not the best example but shows what it can do
addListener(box, MouseEvent.MOUSE_DOWN, box.startDrag, [false, newRectangle(0,0,stage.stageWidth-box.width, stage.stageHeight-box.height)], false, true);
you can also clear a listener or remove all registered listeners with one call (must have been registered with “addListener”)
i.e.
//remove single listener
removeListener(box, MouseEvent.MOUSE_DOWN);
//remove all listeners attached to box
removeAllListeners(box);
How many times have you typed something like this to centre align a display object?
child.x = (parent.width-child.width)/2;
Well no more!
introducing align.as!!!
This is a class I have been using for years and always meant to share but never got round to it.
Here is how it works:
//to centre align a display object with its parent:align(child);
//to top-right align a display object with its parent:align(child, null, [1, 0]);
//to bottom-right align a display object with its parent:align(child, null, [1, 1]);
//to centre align a display object with respect to the stage:align(child, stage);
//to top-centre align a display object with respect to the stage and offset it by 25 pixels in the y direction:align(child, stage, [0.5,1], [0,25]);
Why it works:
parameter 1 – the display object to align
parameter 2 – the object to align against (if null it will use the child’s parent)
note: this can be a display object or an array of length 2 (element 0 being width and 1 being height) comes in handy if you want to align against some values not relating to a specific display object
parameter 3- the alignment in array form! element 0 is the alignment in x-direction and element 1 is the alignment in the y-direction… [0,0] = top left, [1,1] = bottom right, [0.5,0.5] = middle centre (also the default if you pass in null)
parameter 4 – an optional offset array in pixels i.e. an array here of [50,-100] would offset the display object by +50 in the x direction and -100 in the y direction, after the object has been aligned!
Its not perfect but I use it all the time!!! Brilliant in resize event handlers:
i.e.
just a small snippet from a resize handler in one of my projects… really really speeds things up when it comes to aligning
please use it and please feedback, especially if it breaks/dies/explodes
I plan to add support for detecting bounds as at the moment it is geared at top left aligned display objects only (although you can use the offset to overcome this if you wish)
let me know what you think
b
EDIT: the following link has been updated to include the features as described in the next post, ensure you download the latest version number
the download link —-> bwhiting v1.1 <—-
This was actually pretty easy to achieve, it basically involves rendering the scene 6 times with a wide angle lens each time rendering to a side of a cube map.
This cube map can then be used as a basis for a reflection shader.
Noteworthy observations:
this will be slow for complex scenes as there could potentially be 7 times more draw calls!!
forgetting to convert degrees to radians can be a pain in the but (doh)
frustum cull with each face render to reduce the number of draw calls
to get it to reflect another reflective object will really start to complicate things..so avoid like hell
could probably get away with rendering to really small textures, as perfect reflections can look less realistic anyway.
there is something wrong with my reflection math as those of you with keen eyes will have noticed the reflected cubes are moving backwards – will fix this soon I hope.
All this was achieved in a very short space of time, about 30 mins of coding and about 2 hours to realise I forgot to convert degrees to radians.
example code:
publicfunction rendertoCubeMap(cubeTexture:CubeTexture, exclude:Object3D = null):void{this.exclude = exclude;
var cameraPositionCache:Vector3D = camera.position.clone();
var cameraTargetCache:Vector3D = camera.target.clone();
var fovCache:Number = camera.fov;
var aspectCache:Number = _aspect;
camera.fov = cubeFov;
_aspect = 1;
camera.position.setTo(0,0,0);
context3D.setRenderToTexture(cubeTexture, true, 0, 0);
camera.target.setTo(camera.position.x-1, camera.position.y, camera.position.z);
update();
renderAll();
context3D.setRenderToTexture(cubeTexture, true, 0, 1);
camera.target.setTo(camera.position.x+1, camera.position.y, camera.position.z);
update();
renderAll();
context3D.setRenderToTexture(cubeTexture, true, 0, 2);
camera.target.setTo(camera.position.x, camera.position.y+1, camera.position.z+0.001); //get some NaNs if z = 0 here
update();
renderAll();
context3D.setRenderToTexture(cubeTexture, true, 0, 3);
camera.target.setTo(camera.position.x, camera.position.y-1, camera.position.z-0.001); //get some NaNs if z = 0 here
update();
renderAll();
context3D.setRenderToTexture(cubeTexture, true, 0, 4);
camera.target.setTo(camera.position.x, camera.position.y, camera.position.z +1);
update();
renderAll();
context3D.setRenderToTexture(cubeTexture, true, 0, 5);
camera.target.setTo(camera.position.x, camera.position.y, camera.position.z -1);
update();
renderAll();
context3D.setRenderToBackBuffer();
_aspect = aspectCache;
camera.fov = fovCache;
camera.target.setTo(cameraTargetCache.x, cameraTargetCache.y, cameraTargetCache.z);
camera.position.setTo(cameraPositionCache.x, cameraPositionCache.y, cameraPositionCache.z);
this.exclude = null;
}
Controls:
Mouse to move camera
Mouse wheel to zoom
Space bar to toggle mouse movement
check box to turn the post processing on or off
number 0-9 on keyboard to try some preloaded filters (emboss, blur, edge detection etc…)
slider to control the sample offset
you can enter your own values into the matrix if you like, but be nice as there isn’t any error checking
let me know if it works for you!
will need flash player 11 to view get flash player
video of it running if the demo fails:
So what is a convolution filter and how does it work?
Basically a convolution filter (with regards to images) is where for each pixel to be sampled, a set of surrounding pixels is also sampled. The influence of the surrounding pixels is controlled by a matrix.
i.e.
[0,0,0,
0,1,0,
0,0,0]
The current pixel is represented by the middle value.
The 1st value in the matrix is a sample taken from the pixel North-West of the current pixel
2nd is North
3rd is North-East
4th is East
…
i.e.
[NW, N, NE,
W , x, E
SW , S, SE]
x = the current pixel
so the positions in the matrix determine where the samples come from and the values in the matrix determine their influence.
in the matrix
[0,0,0,
0,1,0,
0,0,0]
all the surrounding pixels will have no (0) influence on the output
with the following matrix
[1,1,1,
1,1,1,
1,1,1]
they all have equal weighting effectively blurring the image
various effects can be achieved by using difference weight combinations such as edge detection and sharpening.
where output is the destination register
where sample is a temporary register for storing the modified uvs
where texture is the texture to sample from
where uv is the current uv coord of the sample (usually passed from the vertex shader)
where offset* is the value to offset the samples by (you will need to calculate this with something like 1/viewportWidth)
where matrix** is the convolution matrix
*at the moment the same offset is used for x and y when in reality there should be two (one for each axis) will add this in at a later date as it hasn’t caused an issue so far.
**
sample code to upload a matrix of 9 values from a vector of numbers called “_filter” into fragment constant 0 – 2:
Super busy at the moment but would like to smash out a new post.
Will be one of the following:
1. Rendering a Depth Texture with molehill
2. Applying Convolution filters with molehill (blur, edge detection, sharpening)
3. Will update the AGAL helper with some examples (diffuse shading, specular shading, rim shading, etc..)
Any preferences? If not ill just do whichever one I have time to do.
Right I have tried a few ways to do this each with its advantaged and disadvantages, so what I will do is run you through how I approached this and how to implement it (leaving some bits down to you).
So what is depth of field?
Depth of field is an effect whereby object viewed at a particular focal distance (distance from camera) are sharper and those that are further from this point look blurrier.
(images from wikipedia)
What we want to do is emulate this effect in our 3d environment (molehill woo)!
To do this we need to consider a couple of things, the effect will be applied as a post process which requires additional depth information and a way to blur stuff.
Post processing:
These are effects applied to a scene AFTER it has already been rendered, and is achieved by doing the following.
Rendering to a texture instead of the backbuffer.
Performing some kind of effect (the post process) using the scene texture as an input and then outputting the result.
This resultant texture is then used to colour a screen aligned quad (pretty easy to set up) and then this is rendered to the back buffer.
Depth information:
This is information that describes the depth of each pixel relative to the camera from 0-1 (black to white) based on the near and far planes.
Normally one has access to the depth buffer, sadly we do not, happily we can make one
All you got to do is render you whole scene again to a new texture with one depth material for every object. (this is a pretty fast process as the depth material has a pretty simple shaders and there is no program swapping between models as they all share)
I will probably not describe how to produce one of these in this article.
(thanks again wikipedia)
Blur:
To simulate being out of focus we can use a blur, this is a large area in graphics and there are at least 6 zillion ways to do it. I will share a couple and you can decide what you want to use.
1. render the texture again to another target but this time use a smaller one (maybe 1/16th the size) then when this is stretched back up it will be blurred.
2. some kind of of simple fast blur in the pixel shader (i.e. for each pixel sample 8 pixels around it and take an average)
3. gaussian blur, more complex and slower but produces nice results, must be rendered a few times (x, then y and maybe repeat)
Now we should have ourselves 2 or 3 textures, one scene render, one depth render and maybe a blur texture… now what?
Here is the fun part
we take our textures in as parameters to our DOF post process then use a sprinkling of magic to get the result we want.
the magic:
use the depth information compared against the focal point to determine a blur factor.
this factor can be used in two ways depending on your approach.
a. use the factor as an interpolation ratio to lerp (interpolate) between the original and the blurred texture
b. use the factor to determine the blur amount in your blur pass.
its that simple
(the tough bit is setting up the textures correctly and the blur shaders can get complex)
so when you run this shader you end up with a nice sharp areas (those near the focal point) and more blur as objects get further away from this point.
there is however much more to consider, like bleeding of blurred areas into areas that should be sharp which can be fixed but it involves sampling the depth buffer a lot more to ensure that blur samples are only taken from pixels that are a similar detph.
also worth considering the “factor” mentioned before and how it can be used to produce smoother falloff and falloff that scales nicely.
see this image:
Right I have run out of time, but if you want anything else or don’t understand any of my ramblings let me know and I will try and acomodate.
(live demos to follow when I get some time)
here is a quick fraps capture showing some integrated physics (bullet flash*) and some post processes
post processes are pretty easy to implement but I am still looking to make them chainable so they can be used together.
have got some simple ones like invert, sepia… and some more complex ones like convolutions and depth of field as well as DOF with depth based bleed reduction which works quite well.
materials work by stacking various techniques together such as texture, fog, rim, reflection, refraction, diffuse..etc. which makes building the materials really quick! also supports a few blend modes for blending these techniques.
Having enjoyed playing with adobe flash’s new molehill API I though I should share some demos.
I’ve written quite a few and being a lazy boy never really uploaded many of them. So that’s what this page is for .
I will start upload the demo’s from time to time to this post with a little description of what’s going on.
note: you need the incubator version of flash to view these download here