Archive for October, 2008

Advanced Frustum clipping

|

Sorry i couldn’t come up with more appropriate title for this post, i chose advanced based on that its a quite improved version from the previous one.

Ok i will go straight to the problem that comes up with most frustum culling implementations, that its just a separate checking of multiple planes. Let me explain more, lets say you have 5 planes (skipping the far plane) defining a camera frustum and you need to check each face against them. Most engines, for example my latest demo on frustum culling or the latest Papervision3D frustum culling demo, check em one at a time and generate splits accordingly so if 1st plane splits the face and generate 2 new faces that are visible, you take those 2 faces and check em with the 2nd plane which may result in 4 faces for example so you took em and check em with the 3rd face… you get the point. This proves really inefficient when face is going to be clipped with 2 and more frustum planes, so if you are really close to some face you may end up with something like this:

So i’ve asked myself is there something we can do about this?

Yes we can indeed, i’ve come up with another method (i am sure someone already came with it before i didnt really check) where i try to avoid splitting into faces at all. Instead i am generating temporary polygon. Ok let me put some light in it, lets start as we always do we have a face that needs to be checked for visibility and we also have the 5 planes that define the frustum. We take the face and split it against the 1st plane, but here comes the diference, instead of generating multiple faces we will just generate a polygon so instead of 2 faces like in previous scenario we would end up with a quad, next step is to check this polygon against the 2nd plane and again generate a polygon which will be inside, then the 3rd plane… again you get the point. But there is a final step that needs to be done, after we went through all the planes we need to get triangles again, easy we will use triangle fan algorithm to triangulate the polygon since its always convex. This way we will generate always the best triangulation possible for the splitted parts. So lets go near the face really close like in the first scenario and tadaaa this is what we get

Demo where you can switch between these methods at runtime: DEMO

Frustum Clipping

|

It seems we made another step in our 3D engine for now known as Agile3D. :)

So whats Frustum Clipping, lets look at the Frustum, correctly it would be camera frustum, simply its a 3D space containing all the faces that we are going to see from a camera. So to avoid rendering unnecessary faces that are outside of such frustum and we are not going to see em either way its usefull to apply some kind of determinant when face is inside or outside of the frustum.

Frustum itself is nothing more than 6 planes even though the 6th one, far plane, is rarely used. The easiest solution, once we have the planes, that comes to mind is simply checking all vertices of a specified face against all planes and check if they are at the correct side. Once atleast one of the vertices is at the correct side of each of the planes we can say that this face will be visible and needs to be projected. Easy as it sounds, there will be problems with such solution, especially with faces that intersect the near plane, things will get messy and projection will be all over the place.

This is where the Clipping part of the title comes in. To correctly handle partially visible faces (those that have atleast one of the vertices inside but not all of em) we need to split em up and render only the visible part. I am not going to technical detail but its pretty simple triangle/plane intersection although it does provide quite a space for various optimizations ;)

Personally i would avoid using any kind of clipping beside near plane which is necessary, this ofcourse depends on various things (size of the faces, polycount, etc.) its sufficient to say that in most Flash scenarios you will simply use clipping only for near plane and use all the other planes just for discarding faces that are completely outside the frustum. Below is a full frustum culling demo, without the far plane that is really unnecessary anyway.

Full frustum culling demo: DEMO

Flash9 engine interface demo

|

Ok so i am back again after a tough week, I couldn’t get much done even though i implemented frustrum culling to our new F10 3D engine its still not finalized to release a demo. ;)

Back to this post, i was asked by some friends to post a demo from our old 3D engine which was working on Flash9 platform so i browsed our SVN for a while and decided to post this idea for a 3D gallery interface we did a year ago. Nothing too fancy, it was actually one of our first ideas working on our 3D engine which we never quite found time to finish it to match up to Papervision3D or Alternativa3D great flash 3D engines.

Anyway to explain why it’s iNSOMNia and not Flash-CORE its rather simple Flash-CORE (the name and even the domain) came like 2-3 months after we made this demo and i didn’t have the heart to change it, nostalgic i know. Maybe you are familiar with iNSOMNia after all we were quite popular if i may say so in the Demoscene atleast around here ;)

Back to the demo: Flash9 engine demo

BSP generation and depth sorting

|

Hi, i didn’t have quite the time i was hoping for this week but i found atleast one day to code BSP depth sorting for a 3D scene yay. One can ask why you need BSP for depth sorting since this is obsolete in modern 3D graphics for quite some time? Yes it is, but its just due to hardware Z-Buffer which can do pixel perfect depth sort, but unfortunately Flash doesn’t support Z-Buffer even though i was hoping for such a support in Flash 10 :( And since we don’t have the HW Z-Buffer we can either code it or find another solution for depth sorting. As i said Z-Buffer is pixel perfect method, so coding it in Flash is out of question, this means we have to go back to the old days and look for inspiration there. 10 years ago we were pretty active in demoscene with couple of DOS demos (nostalgic i know) this again reminds me of those days, got to dust off some old 3D skills.

Enough of my small talk without further ado here is a demo of BSP in action, as i said i’ve coded the BSP generation and sorting in couple of hours so there is probably a lot of things to optimize.

Demo: bsp demo

Calculating global Z position in Flash 10

|

Hi, so finally after a week i got to play with Flash 10 again, and i figured out the problem from my previous example, as you remember i said that even if we have Z coordinate in Flash 10 now the depth sorting isn’t taking into account, all the displayobjects are sorted according to their index as in previous versions. So basically nothing difficult, lets get their Z and sort their indices according to the Z right? Right but getting to global Z as you may need when nesting various displayobjects (as in the provided example before) isn’t as simple, even thou there are new functions like local3DToGlobal and globalToLocal3D as you can see they can’t help us in our problem. So i’ve tried to look whats new in Transform and there is our solution there.

Basically we will need to transform our Vector3D representing the position using matrices of all its parents, simple as that. Here as simple static function that i came up with to recursively get the global Z position of target instance of displayobject.

  1. static public function getGlobalZ(p_display:DisplayObject, v:Vector3D=null):Number
  2. {
  3.    // We need to check out if the matrix3D exists, displayobjects dont have it by default
  4.    if (p_display.transform.matrix3D==null) return v.z;
  5.    if (v==null) v = p_display.transform.matrix3D.decompose()[0];
  6.    var m:Matrix3D = p_display.parent.transform.matrix3D;
  7.  
  8.    // Again lets check the matrix3D otherwise there is no further parent transform
  9.    if (m!=null) v = m.transformVector(v);
  10.  
  11.    if (p_display.parent.parent!=null) return getGlobalZ(p_display.parent, v);
  12.    return v.z;
  13. }

As you can see its simple, we decompose the displayobjects current translation 3D vector from the matrix then transform it with parents transform matrix so we get it to parents space. We repeat it until there are any parents left ofcourse. One thing you need to know and thats why i am checking the matrix3D instance, the thing is that displayobjects don’t have matrix3D by default, they create an instance only after they need it (you explicitly set Z translation, or any kind of rotation, etc.)

I hope it will help you, anyway here is a working example of the previous carousel now with depth sorting based on this method, i even added some images so its not as plain ;) Dont forget that you need Flash player 10 beta atleast, to be able to play it.

Carousel: example