dcsimg
A Flash Developer Resource Site

Results 1 to 8 of 8

Thread: Z-buffer: possible?

  1. #1
    Junior Member
    Join Date
    Jul 2004
    Posts
    11

    Z-buffer: possible?

    We're trying to ascertain whether or not it would be feasible to implement a z-buffer for a 640x480 isometric game. (Technically it's an oblique perspective rather than isometric, but this shouldn't matter -- the main point is that the graphics are sprite-based rather than "real" 3D).

    I should note that we DO have a working solution for depth-sorting our scene, I'm mentioning this in order to avoid replies such as "sort by screenspace y", "sort by grid position", etc: none of these simple solutions works for our scene, and our current solution is so complex and costly at runtime that I'm trying to determine if a z-buffer would be a better solution. Hence this post -- I'd like to make sure I'm not I'm not doing something very stupid with my initial foray into z-buffering.

    Our scene is composed of primarily static shapes, with several dozen small moving objects circulating between them. This means that rather than having to redraw the entire z-buffer and framebuffers from scratch each frame, we can instead "bake" the static scene (graphics and z-buffer) into two 640x480 bitmaps and blit those into the frame-buffer and z-buffer instead of clearing them to black at the start of each frame.

    Since the graphics are sprites, their z-image (relative to some point in objspace) can be precalculated and baked into a bitmap (a "z-sprite"). At runtime the depth of a given pixel in the sprite is simply the depth of the objspace point + the depth stored in the z-sprite, so that all we need to do to draw the object is to loop over the z-sprite testing each pixel vs the corresponding pixel in the z-buffer, and conditionally writing the sprite's depth and colour info into the z- and frame-buffers (respectively) if the sprite's pixel passes the z-test.

    The two above simplifications to general z-buffering is what leads me to believe that a z-buffer should be feasible at game rates (a few ms/frame): we only need to do per-pixel work for maybe 50 16x32pix sprites, which is ~50k pixel reads/writes per frame (counting both z- and frame-buffers).

    From what I've been able to find online, this seems at least somewhat reasonable -- there are many examples of flash processing hundreds of thousands of pixels at 30hz, i.e these posts and many similar examples:
    http://blog.joa-ebert.com/2009/04/03...d-pixelbender/
    http://webr3.org/blog/haxe/bitmapdat...-optimization/


    My problem is that none of my tests come anywhere close to the performance I would expect from the above example!! For instance, just using getVector/setVector to iterate over all the pixels in the framebuffer is taking about 100ms.

    So, my question is: What would be the best way to implement a sprite-based z-buffer?

    I'm aware that moving to haXe would probably be a good idea; AFAICT there's no way to implement a z-buffer via Pixel Bender, but I'd love to be proved wrong about that. Basically I'm clueless about all the new-fangled stuff like byteArrays, flash.Memory, etc. which means I'm not sure how to use it properly.

    There's also a chance that I'm crazy and that a z-buffer is not going to be feasible

    Any help/suggestions or useful links would be much appreciated!

    thanks,
    Raigan

    p.s - thanks very much to anyone who managed to read this far -- I really tried to keep things as brief as possible as per the forum rules, but I felt that some background was warranted since i.e a z-buffer for a proper 3D scene at 640x480 is obviously not going to be feasible.

  2. #2
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    getVector/setVector over 640x480 shouldn't take anywhere near 100ms, I don't think. You are getting the entire bitmap as a vector.<uint> right, and not iterating with getPixel32 or getPixel?

    Unfornutately AS3 has no direct access to flash.memory even though it is supported by the virtual machine. Haxe does. Pixelbender does.

    I believe there's a poster in games named Rachil0 who has done a lot of work on z-buffer implementations. Here's the thread I was thinking of:
    http://board.flashkit.com/board/showthread.php?t=749263

  3. #3
    Junior Member
    Join Date
    Jul 2004
    Posts
    11
    Quote Originally Posted by 5TonsOfFlax View Post
    getVector/setVector over 640x480 shouldn't take anywhere near 100ms, I don't think. You are getting the entire bitmap as a vector.<uint> right, and not iterating with getPixel32 or getPixel?
    Yep, here's the code I'm using:
    Code:
    //framebuffer is a 640x480 Bitmap attached to the stage
    framebuffer.bitmapData.lock();
    var pixel_rect:Rectangle = new Rectangle(0, 0, 640, 480);		
    var pixels:Vector.<uint> = framebuffer.bitmapData.getVector(pixel_rect);
    var num_pixels:uint = pixels.length;
    for (var i:uint = 0; i < num_pixels; i++)
    {
       pixels[i] &= 0x00FF0000;//example pixel operation
    }
    framebuffer.bitmapData.setVector(pixel_rect, pixels);
    framebuffer.bitmapData.unlock();
    I wasn't able to find a definitive reference for what exactly the deal is with the pixel values though; the docs talk about premultiplication but then suggest that this shouldn't make a difference (since they're presented as non-premultiplied), however other sites have suggested that this is a problem.. I feel like I'm a total noob since I haven't been programming in Flash since AS1/Flash5 days!


    Quote Originally Posted by 5TonsOfFlax View Post
    I believe there's a poster in games named Rachil0 who has done a lot of work on z-buffer implementations.
    Thanks for the heads-up! I came across that thread yesterday, but I'm not sure if it helps me; my understanding is that gradientfill is used to generate the z-buffer, and some clever blending+thresholding to composite two images together. Sadly I don't need to solve the former problem, and the latter problem won't let me test moving objects vs each other (i.e I need to composite many small objects onto one large one).. and also my scene will definitely require more than 8bits of precision

    Basically it seemed like a much simpler solution should work for me, however my tests were woefully far from performant.

    I didn't bother reading the russian thread linked off of that discussion yesterday, I guess I'd better get google-translating. Thanks for your help!
    Last edited by raigan; 08-24-2009 at 06:16 PM.

  4. #4
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    You're creating a new rectangle each time through that. If you're calling it each frame, that could be a minor, but real, delay. Try keeping pixel_rect in a class level variable, or just using framebuffer.bitmapData.rect. Of course, that may not actually be the case in your code.

    The ability to use the memory directly as in haxe or pixelbender would help you a lot here. There's a lot of memory copying and behind the scenes object allocation going on.

  5. #5
    Junior Member
    Join Date
    Jul 2004
    Posts
    11
    Quote Originally Posted by 5TonsOfFlax View Post
    You're creating a new rectangle each time through that. If you're calling it each frame, that could be a minor, but real, delay. Try keeping pixel_rect in a class level variable, or just using framebuffer.bitmapData.rect. Of course, that may not actually be the case in your code.
    That's the actual code; there is already other game code running (which runs at about 10ms/frame) so I figured it wouldn't make much of a difference.

    Quote Originally Posted by 5TonsOfFlax View Post
    The ability to use the memory directly as in haxe or pixelbender would help you a lot here. There's a lot of memory copying and behind the scenes object allocation going on.
    I guess I'll have to give haxe a try; I just wanted to wait until things were working before porting everything to haxe. I still feel like I'm missing something big, since performance is about an order of magnitude slower for me than it should be..

    Also, if anyone knows of a more suitable forum or list I could post on, I'd appreciate it -- as I mentioned it's been several years, and Flashcoders/Flashkit were the only resources I could remember! If there's some new most-popular place let me know
    Last edited by raigan; 08-24-2009 at 07:07 PM.

  6. #6
    Senior Member joshstrike's Avatar
    Join Date
    Jan 2001
    Location
    Alhama de Granada, España
    Posts
    1,131
    Excuse me, but what is the advantage to doing it this way? I'm trying to picture it and I don't understand why it would be superior to any other kind of sorting loop... The bitmap just seems like an awful lot of overhead for something that could be done just as well with a 2-dimensional array and some bitmath, isn't it? Given that you know the width and height of the array and all its vectors have a fixed length, wouldn't it be faster to implement some kind of x/y iterators to perform an operation on a straight array within the chosen rectangle and avoid the bitmapdata overhead altogether?

    Must be missing something...

  7. #7
    Junior Member
    Join Date
    Jul 2004
    Posts
    11
    Quote Originally Posted by joshstrike View Post
    Must be missing something...
    No, I might just be really stupid -- all my experience with Flash is 5 years old, so I have no idea what the best practices are these days

    You're absolutely right, the z-buffer could just be a linear array of numbers (again, I have no idea how to represent this -- would vector<uint> or byteArray be better?!). I was just basing my tests off of this post http://webr3.org/blog/haxe/bitmapdat...-optimization/

    The only reason I'd want to use bitmapData is, as far as I can tell, if I want to use the rendering functions to do my comparisons for me as in the thread suggested by 5Tons: for each sprite I could generate a mask of pixels which pass the z-compare test by using subtractive-blending and thresholding on a couple of temporary bitmaps. Conceivably this would be faster than pixel-by-pixel operations, but sadly it only allows for 256 depth values.

    Please let me know if there is an obvious best way to approach this, I'm hopelessly out of touch with performant Actionscript. The last time I was making games in Flash, each function call (even empty ones) had significant overhead!

  8. #8
    Junior Member
    Join Date
    Aug 2010
    Posts
    1
    Raigan.

    Did you happen to find a suitable solution to your z-buffering technique? I am working on a similar solution and thought we might do a knowledge share.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center