A test molehill screen capture

August 22nd, 2011

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.

*bullet flash

Molehill examples (source added)

May 25th, 2011

update: this was built to run on the incubator version of the flash player so will not work on the standard fp11
I will update this demo today to run on the release version.

YO!!!

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

Demo 1 (click image or link below)
rar

glassy dinosaur demo


The shader in this demo uses a combination of reflection, refraction and cubemap sampling.
mouse wheel to zoom in and out

Shader Code:

AGAL-

VERTEX SHADER:

//vc0 is worldViewMatrix
//vc4 is worldMatrix
//vc8 is camera position
//vc9 is just a [1,1,1,1] (and yes I coulda just used the w of the position)

m44 op va0 vc0
m44 vt0 va0 vc4
m33 vt1.xyz va1 vc4
sub vt2 vc8 vt0
nrm vt2.xyz vt2
mov v0 vt1.xyz
mov v1 vt2
dp3 vt3 vt2.xyz vt1.xyz
sub vt3 vc9.w vt3
mov v2 vt3

FRAGMENT SHADER:

//fc0 is [0.9, 0.81, 0, 1].. which was roi and roi squared I think… been a while 🙂

dp3 ft0 v1 v0
add ft0 ft0 ft0
mul ft0 v0 ft0
sub ft0 v1 ft0
neg ft0 ft0
nrm ft0.xyz ft0
dp3 ft2 v1 v0
mul ft2 ft2 v0
sub ft2 ft2 v1
mul ft2 ft2 fc0.x
dp3 ft1 v1 v0
mul ft1 ft1 ft1
sub ft1 fc0.w ft1
mul ft1 fc0.y ft1
sub ft1 fc0.w ft1
sqt ft1 ft1
mul ft1 ft1 v0
sub ft1 ft2 ft1
tex ft0 ft0 fs0
tex ft1 ft1 fs0
sub ft2 ft0 ft1
mul ft2 ft2 v2
add ft2 ft2 ft1
mov oc ft2

now if you think that looks scary…. please compare it to

AGAL.m44(“op”, “va0”, “vc0”) + //output
AGAL.m44(“vt0”, “va0”, “vc4”) + //world space pos in vt0
AGAL.m33(“vt1.xyz”, “va1”, “vc4”) + //world space nrm in vt1
AGAL.view(“vt2”, “vt0”, “vc8”) + //view in vt2
AGAL.mov(“v0”, “vt1.xyz”) + //normals in v0
AGAL.mov(“v1”, “vt2”)+ //view in v1
AGAL.fresnel_inv(“vt3″,”vt2″,”vt1″,”vc9.w”)+ //fresnel in v2
AGAL.mov(“v2″,”vt3”); //output

and

AGAL.reflect(“ft0”, “v1”, “v0”) +
AGAL.refract(“ft1”, “v1”, “v0”, “ft2”, “fc0.w”, “fc0.x”, “fc0.y”)+
AGAL.tex(“ft0″,”ft0″,”fs0″,”cube”,”clamp”,”linear”)+
AGAL.tex(“ft1″,”ft1″,”fs0″,”cube”,”clamp”,”linear”)+
AGAL.lerp(“ft2”, “ft1”, “ft0”, “v2”)+
AGAL.mov(“oc”, “ft2”);

(see how much better that is…go agal helper go)

more to come 🙂

jslf change publish settings

May 3rd, 2011

a little jsfl snippet to publish the swf with a new name

will add it to google code at some point as a file and with some other bits, but it will have to do till then

note: the code is a mash up of stuff I have found online and my own bits

 
var tempFileURI = "file:///C|/profile.xml";				//a temp file to store settings in
document.exportPublishProfile(tempFileURI);			//store the buggers
 
var settings = FLfile.read(tempFileURI);				//read em in
var backupSettings = settings;					//backup incase you only want a temp publish settings alteration
 
var ffnOpen = "<flashFileName>";
var ffnClose = "</flashFileName>";
var ffnOpenLength = ffnOpen.length;
 
var swfName = settings.substring(settings.indexOf(ffnOpen)+ffnOpenLength,settings.indexOf(ffnClose));
 
var newSwfName = prompt("update swf name", swfName);	//doesnt have to come from input box could be hardcoded or derived
if (newSwfName == null || newSwfName.length == 0)
{
	newSwfName = swfName;
}
 
settings = settings.split(swfName).join(newSwfName);	//replace the name	
 
//voodoo section to make it work
var from = settings.indexOf("<defaultNames>");
var to = settings.indexOf("</defaultNames>");
var delta = settings.substring(from, to);
 
settings = settings.split(delta).join("<defaultNames>0");
 
from = settings.indexOf("<flashDefaultName>");
to = settings.indexOf("</flashDefaultName>");
delta = settings.substring(from, to);
 
settings = settings.split(delta).join("<flashDefaultName>0");
//end voodoo
 
 
FLfile.write(tempFileURI, settings);					//write it back to the file now its updated
document.importPublishProfile(tempFileURI);			//import that biatchhh
 
document.testMovie();							//optional publish

Molehill AGAL helper/wrapper… contributions welcome

March 31st, 2011

NEW UPDATE COMING SOON (09.09.2011)- a few more functions and will proper code hints
UPDATE 19.05.2011
helper is now on google code
>>AGAL<<

these static functions ideally can help you build shaders in a more readable and more reusable way.
they are an incomplete set and require additions and improvement.

so feel free to post additions and alterations if I have cocked up somewhere (a good chance of that as I boshed this out in a rush)
and Ill see that they get worked in.

 
//util functions (this section is the one I would like to see grow)
 
//same as 'mix'
public static function lerp(target:String, source1:String, source2:String, ratio:String):String
{
	var code:String = "";
	code += sub(target, source2, source1);
	code += mul(target, target, ratio);
	code += add(target, target, source1);
	return code;
}
 
//should return the length of the source vector
public static function length(target:String, source:String):String
{
	var code:String = "";
	code += dp3(target, source, source);
	code += sqt(target, target);
	return code;
}
//calculates the reflection vector based on a view direction and a normal (formula:  r = V - 2(V.N)*N)
public static function reflect(target:String, view:String, normal:String):String
{
	var code:String = "";
	code += dp3(target+".w", view+".xyz", normal+".xyz");
	code += add(target+".w", target+".w", target+".w");
	code += mul(target+".xyz", normal+".xyz", target+".w");
	code += sub(target+".xyz", view+".xyz", target+".xyz");
	code += neg(target+".xyz", target+".xyz");
	return code;
}
 
//generic helpers (usefulness debatable)
 
//unit vector from Light to the Vertex position
public static function light(target:String, light:String, position:String):String
{
	var code:String = "";
	code += sub(target, position, light);
	code += nrm(target, target);
	return code;
}
//unit vector from Vertex P to the View position V
public static function view(target:String, position:String, camera:String):String
{
	var code:String = "";
	code += sub(target, camera, position);
	code += nrm(target, target);
	return code;
}
//unit vector halfway H, between L and V, used for Blinn simplification
public static function half(target:String, light:String, view:String):String
{
	var code:String = "";
	code += add(target, light, view);
	code += nrm(target, target);
	return code;
}
 
//wrappers for inbuilt functions (incomplete)
public static function mov(target:String, source:String):String
{
	return "mov " + target + " " + source + "\n";
}
public static function add(target:String, source1:String, source2:String):String
{
	return "add " + target + " " + source1 + " " + source2 + "\n";
}
public static function sub(target:String, source1:String, source2:String):String
{
	return "sub " + target + " " + source1 + " " + source2 + "\n";
}
public static function mul(target:String, source1:String, source2:String):String
{
	return "mul " + target + " " + source1 + " " + source2 + "\n";
}
public static function neg(target:String, source:String):String
{
	return "neg " + target + " " + source + "\n";
}
public static function sqt(target:String, source:String):String
{
	return "sqt " + target + " " + source + "\n";
}
public static function nrm(target:String, source:String):String
{
	return "nrm " + target + " " + source + "\n";
}
public static function dp3(target:String, source1:String, source2:String):String
{
	return "dp3 " + target + " " + source1 + " " + source2 + "\n";
}
public static function pow(target:String, source1:String, source2:String):String
{
	return "pow " + target + " " + source1 + " " + source2 + "\n";
}
public static function m33(target:String, source1:String, source2:String):String
{
	return "m33 " + target + " " + source1 + " " + source2 + "\n";
}
public static function tex(target:String, coord:String, texture:String, type:String, wrap:String, filter:String):String
{
	return "tex "+target+" "+coord+" "+texture+" <"+type+","+wrap+","+filter+">" + "\n";
}

🙂

as an idea for some of the functions what I could do is add and optional boolean parameter called normalize and if its set I could automatically normalize the output.

would like to see the following functions added:
refract (tried to do this one myself but got scared and ran away)
smoothstep (see wikipedia about this one… the problem is that it requires the use of a constant or two and ideally these wouldn’t have to be passed in as parameters.. any idea if that is possible?)
..and anything else anyone can think of that the api is currently misisng
and I’ll soon be putting in some lighting methods for helping people get diffuse and specular lighting.

Culling scene objects in flash

January 27th, 2011

Not being satisfied with my current methods for object culling I set out on a new adventure in actionscript.

The most common method is culling spheres against the view frustum in world space, and from what I have seen in implementations in other engines it is not very efficient.
(you can be checking the spheres against up to 6 planes in 3d space)

The current technique I was using was to project all my objects bounding box vertices to screen space then from there it is a very trivial check to see if any of those points are in the viewport and if so, then render the object. The downside to this method is that it requires all the bounding boxes vertices to be projected into world space then on to the screen, that means that an individual matrix is required per object and must be regenerated whenever the object moves.

My latest efforts get round the need for these matrices, here be the demo(s).
(still a few kinks in it but the idea is solid I think)

500 cubes
1000 cubes
5000 cubes beware it may destroy your machine
(if you could report any frame-rates with specs that would be ace and appreciated)

all the cubes are rendering perspectively correct textures too.

mouse wheel to move camera in/out CAUTION: the further out you go the more work it’s gotta do to render so be gentle!!

if people are interested how I did it, be sure to ask, and once I have worked it out myself (some crazy hacky math in there) then I can explain 🙂

will also up some other demos that better showcase what is going on… have tested this with over 20,000 cubes and still hit 30fps as long as only a minimal number are required to be rendered.

b

holy stromboli

October 25th, 2010

http://www.youtube.com/watch?feature=player_profilepage&v=m053MqzstVg

http://www.youtube.com/watch?feature=player_profilepage&v=tgwi0lWgX8w

go flash player go!!

looks like our sissy little platform is getting some bigger guns!!

some great demos there from the Alternativa boys and Mythos Labs!

awesome stuff… and its about time too 😉

all thanks to project “molehill”

http://labs.adobe.com/technologies/flash/molehill/

Occlusion Culling in 3D

October 25th, 2010

POW!

this is the semi-result (its not quite finished yet) of some of my research into occlusion culling.

screenshot:

link to demo: (click the big red button to toggle the magic)

http://dev.bwhiting.co.uk/b3d/occlusion/

the big red planes are marked as occluders and are semi-transparent so you can see what is going on behind em 😉

If you want to know more about this just let me know, have half written 2 posts about the inner workings of this but lack motivation to finish them.

Object creation

October 20th, 2010

I was busy comparing my custom Vector3D class with the flash.geom.Vector3D one when I noticed something. While my classes seemed to perform almost as well as the flash version there was one method where my implementation was much much slower.

This was the cross product method. The only thing different in this method was that it returns a new instance of the Vector3D class. So how was flash able to instantiate its own class much faster than I could?

How they did it I don’t know, but I did some tests and it would seem that setting variable values in the constructor is slow when you do it in your own classes. i.e.

var point3D:Point3D = new Point3D(x,y,z);

Funnily enough the above is a slower in my tests than:

var point3D:Point3D = new Point3D().init(x,y,z);

The init function is simply a direct replacement of what was in the constructor:

public function init(x:Number, y:Number, z:Number):Point3D
{
	this.x = x;
	this.y = y;
	this.z = z;
	return this;
}

Note that the init method returns the instance too and a speed up is only gained if the constructor is empty.

I think speed up is only noticed in the release version of the player.

Click the button below to try it out: (Point3DX is the one using init)

[swfobj src=”http://blog.bwhiting.co.uk/wp-content/uploads/2010/10/CreationTest1.swf” height=”400″ width=”400″]

I find the init method to be anywhere up to 2 times faster averaging 1.5 times speedup.

Its more marked on larger numbers but I don’t want to explode anyone’s machine now do I.

Also note that it’s a teeeny bit faster again (in some circumstances) if you set the properties directly on the object once it is created as a 3rd alternative but its not always possible (private attributes) and its more lines of code 🙁

booo adobe

August 20th, 2010

Just wanted to share a few of my frustrations with as3, in particular the apis added to aid 3d development.

My reason for voicing these is really to find out if its me miss understanding things or if other people share my opinions.

My main issue is the restrictions of the drawtriangles/projectVectors/transformVectors methods.

These methods work well and are pretty fast but the parameter format drives me nuts!

everything has to be in vectors of numbers i.e.

var verts:Vector.<Number> = new Vector.<Number>();

verts.push(0, 0, 0, 10, 0, 0, 0, 0, 10);

the vector verts now contains a representation of three 3d vertices (that make up a triangle) in the format the flash wants them in.

is this format easy to manage/maintain…no.

is it easy to debug…no.

is it faster for non-native methods…no.

is it the format flash demands…yes.

is it a pain in the arse…yes.

directly referencing a vertex like this is impossible and accessing it will require a minimum of 6 vector index operations, 3 to get the numbers out and 3 to put them back (slow slow slow).

🙁

I find things so inflexible that I run two systems in parallel, just to take advantage of the new methods resulting in wasted time and memory.

You often end up just having to repopulate these lists every frame, which although works its just plain craziness.

I am sure there are good reasons for this but what are they?

Why couldn’t they have given us a few interfaces instead i.e. IVector2D and IVector3D. Would it really be much slower?

Let us manage things our own way, give us freedom to implement things how we like!

Another thing that has been bugging me is drawTriangles, it isn’t currently flexible enough to be fully taken advantage of. Say for example you had a cube, and you decide to use 8 vertices to define it, one for each corner, drawTriangles is great because it lets you define which of the vertices makes up each individual triangle but it wont let you specify individual uv-coordinates per triangle-vertex. booo. Ideally a vertex shouldn’t need to be tied to one uv and one uv only because if that vertex is also part of another face it make have a different uv-coord.

Given that adobe are supposedly working on new 3d shiznit that are gonna blow our minds, I really really hope they consult the community and ask the people who are going to be using it most for input, ideas and suggestions!

Backface culling method

July 30th, 2010

In 3d one needs to cull back-facing triangles before the render process so as not to render triangles that will never be seen by the observer.

There a couple of ways you can do this and at various stages in the pipeline.

Dotting:
One way is to take the dot product of the triangle’s normal with the vector from the camera’s position (transformed into object space) to the polygon.
(this can be sped up a little by using the vector of the camera’s position to the mesh, then you don’t have to recalculate it for each triangle).

Winding:
this can only be done once all points in a triangle have been projected into screen space (x and y coordinates) and works by determining if the points are in a clockwise or counter-clockwise order.

Pros:
dotting can be done at an earlier stage thus potentially reducing the number of points that need to be projected in the projection stage.
winding is easy to implement and involves very few mathematical operations.

Cons
dotting is slower, well it seems to be in actionscript anyway.
winding, done at a later stage in the pipeline so it potentially misses an opportunity to cull early and save some operations at other stages.

Conclusion:
I have always opted for the winding method because of its ease and speed. Even though have to project EVERY point in your scene before hand, this has never proven to be an issue as projection of many thousands of points seems to be a very quick and easy task. (and I have tried using my own matrix classes, the inbuilt ones and even a pixel bender implementation….all of which laugh at such a task).

Sub-conclusion:
I still think there is room for improvement so time to invent some methods to help speed it up even more.

Result of sub-conclusion:
I was thinking about different ways to speed this up and had a thought while looking at the bounding box around my meshes. With any given mesh you can only ever see at most 3 of its 6 sides and a minimum of 1! So I figured if I could find a simple way to assign each triangle to one of those sides then maybe I could cull whole groups of triangles.

What resulted was a method run after a mesh is created to loop through each of the triangles and assign them an integer id (1, 2, 4, 8, 16, or 32 for bitwise usage later) based on which bounding box side they are most facing.

Then when it came to culling all I had to do was project the bounding box of the mesh, loop through its faces to check their visibility and build a bit mask. Once this is done I could loop through the triangles and before doing a winding check I could use a simple bitwise AND operation: if(triangle.id & mask) == 0), and if it passes that skip the winding check.

Now this worked but the speed up gained was sooooo small it was almost not worth my time 🙁
This is because the current technique will only give the triangle the id of the BB side it is MOST facing, this does not guarantee it is not also facing another side, so it cannot be used to disregard triangles but only skip the winding check. (and only for on average 1/6th of the triangles).

I have tried dotting the face normals with the BB side normals to produce a broader cull but didn’t get it working 🙁

Anyone else got any amazing ideas to help speed up a process that probably doesn’t actually need it?

edit:
here are some images of the culling produced by this method alone (without additional winding culling)