gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS Misc > Two pass 3D rendering demo

#65236 - ecurtz - Sun Jan 01, 2006 5:17 am

Here's the promised two pass 3D demo, it took me longer than I expected to get it finished. Unfortunately, I still can't get it working with only one bank of VRAM - I'll send a shiny new DS game to anyone who can get that going...

Two Pass 3D

And a link to the old two screen one since that thread is aging

Dual 3D

#65263 - FireSlash - Sun Jan 01, 2006 5:57 pm

ecurtz, do you mind if I write up a tutorial on using the capture method for dual screen 3d?

I'll of course give you credit. I just feel a written tutorial might be a bit more helpful than a chunk of code.
_________________
FireSlash.net

#65266 - ecurtz - Sun Jan 01, 2006 6:51 pm

Go nuts, no credit necessary. It would be nice if you wanted to try and test exactly what a few of the bits do. For instance there's a change in one stage of the two pass flags so that it doesn't capture the BG layers on that frame, only the 3D. I unfortunately wasn't very methodical, just messed with stuff until it did what I wanted.

#65378 - bluescrn - Mon Jan 02, 2006 6:33 pm

I've taken the 2-pass demo and hacked it into a proof-of-concept bloom effect demo:

www.bluescrn.net/dsbloom.zip

The idea was to take the captured frame, extract the bright bits, blur it, and add it over the top of the original frame. Like so many PC/console games do these days with shaders...

To do it on the DS, it takes 1/4 of the captured frame (a 128x96 buffer), converts from RGB555 to an 8-bit intensity value. Then it blurs this buffer in 2 passes (horizontally then vertically). Then blends this additively over the original 3D scene (using BLEND_CR and a scaled 2D layer)

(Hold the right shoulder button to see the glow buffer on it's own)

It's rather hacky, and in this version the glow is a frame behind the 3D. Ideally, I'd overlay the glow as blended/scaled 8bpp sprites - the sprite palette could give good control over the glow effect. (But today I was too lazy to set up the sprites and swizzle the data into sprite tiles...)

In theory, this could be done at 60fps - as I'm triple-buffering the VRAM banks (one is being captured into whilst a 2nd is being processed and a 3rd is being displayed). But that would need super-fast blurring code/algorithms... Anyone got any clever ideas?

Does the DS not have the equivalent of the GBA's fast internal RAM? - because putting the blur buffers in faster memory should give it a big boost.

Not sure this would ever be particularly practical for a game due to the rather large CPU and VRAM overheads.. But maybe for demo effects?...

#65388 - tepples - Mon Jan 02, 2006 8:32 pm

bluescrn wrote:
Does the DS not have the equivalent of the GBA's fast internal RAM? - because putting the blur buffers in faster memory should give it a big boost.

The DS has something called "cache".
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#65404 - Durandle - Mon Jan 02, 2006 10:16 pm

wow thats rather nice... homebrew is really getting rather good. Looks more advanced than commercial games - would be nice to see all the good demo ideas applied to a full size game.

Couldn't similar methods be used to create anti-aliasing?

#65405 - bluescrn - Mon Jan 02, 2006 10:38 pm

tepples wrote:
bluescrn wrote:
Does the DS not have the equivalent of the GBA's fast internal RAM? - because putting the blur buffers in faster memory should give it a big boost.

The DS has something called "cache".


Yeah... annoying, isn't it :) It was fairly easy to optimize for the GBA as you could count cycles...

The horizonal blurring should be pretty cache-friendly, but not so much for the vertical blurring. Although the buffer is pretty small. Maybe the whole thing could be optimized by reading/writing 32bit chunks (4 pixels) instead of bytes? Trivial for the vertical blurring, a bit more tricky for the horizontal. I think the 2-pass (horizontal/vertical) approach is probably the best way to do it, that's pretty much how I'd do it with shaders on the PC - but there might be other options?

One that I've experimented with is keeping the 'bloom buffer' from frame to frame, building up a cumulative bloom/blur over a few frames. But it's tricky to get right, and leaves trails that might not always be wanted...

And I think ARM code would probably do the job better than thumb.

Has anyone done any profiling of memory reads/writes to different areas - is VRAM the same speed as main memory - or are there performance penalties to be aware of?...

Edit: After reading up on blur algorithms, I think 60fps may be a very acheivable goal :)

#65408 - bluescrn - Mon Jan 02, 2006 11:05 pm

Durandle wrote:

Couldn't similar methods be used to create anti-aliasing?


Yes :)

If you were willing to run at 30fps, you could acheive 2xAA (supersampling) by rendering the screen in two passes - rendering either 512x192 or 256x384, and downsampling to 256x192 using the CPU

However, you would only be left with one VRAM bank for textures, as you'd need to triple-buffer (one for display, one for capture, and one for processing - building up the final image)

So in practice you're probably better off having larger textures, using the edge antialiasing, and running at 60fps, as IMHO just running at 60fps can hide aliasing quite well, when compared to the same thing at 30fps

But it'd be nice to see it done, if just as a tech demo...

#65434 - The 9th Sage - Tue Jan 03, 2006 6:45 am

bluescrn wrote:
I've taken the 2-pass demo and hacked it into a proof-of-concept bloom effect demo:

www.bluescrn.net/dsbloom.zip

The idea was to take the captured frame, extract the bright bits, blur it, and add it over the top of the original frame. Like so many PC/console games do these days with shaders...

To do it on the DS, it takes 1/4 of the captured frame (a 128x96 buffer), converts from RGB555 to an 8-bit intensity value. Then it blurs this buffer in 2 passes (horizontally then vertically). Then blends this additively over the original 3D scene (using BLEND_CR and a scaled 2D layer)

(Hold the right shoulder button to see the glow buffer on it's own)

It's rather hacky, and in this version the glow is a frame behind the 3D. Ideally, I'd overlay the glow as blended/scaled 8bpp sprites - the sprite palette could give good control over the glow effect. (But today I was too lazy to set up the sprites and swizzle the data into sprite tiles...)


Wow...this is really quite impressive looking. O_O I hope some commercial games try effects of this nature, maybe in the 'next generation' of DS games? You figure, it seems like the stuff that really really pushes the system doesn't come out until later in the lifetime of the system.

Either way, this is pretty interesting.
_________________
Now with 20% More Old Man from Zelda 1 than ever before!

#65488 - olimar - Tue Jan 03, 2006 5:20 pm



Last edited by olimar on Wed Aug 20, 2008 10:03 pm; edited 1 time in total

#65491 - bluescrn - Tue Jan 03, 2006 5:41 pm

olimar wrote:
tepples wrote:
bluescrn wrote:
Does the DS not have the equivalent of the GBA's fast internal RAM? - because putting the blur buffers in faster memory should give it a big boost.

The DS has something called "cache".

The fastest would be to place code/data in TCMs (and use ARM code, of course). You also have shared ram to play with (faster than main memory).


I'll have to look into that - I've spent the afternoon optimizing the C version, and got it up to 60fps, with a much nicer blur after a change of algorithm :)

I'm also using BG3 as an 8bpp bitmap for the glow overlay (also solved the issue of the glow lagging behind the 3d) - and the palette gives lots of control over the glow colour, looks quite pretty with a firey orange glow :)

So I'm guesstimating that a fully-optimized ARM version (using 32bit reads/writes wherever possible) could probably do this in around half a frame - might be more practical than I first though...

I'll clean it up and hopefully upload a new demo later...

#65507 - bluescrn - Tue Jan 03, 2006 7:12 pm

I've updated the demo, and started a new thread in the development forum, here:

http://forum.gbadev.org/viewtopic.php?t=7983

#65516 - M3d10n - Tue Jan 03, 2006 7:33 pm

Looks amazing. This gives us a glimpse of what we might see in future commercial DS software. I see this technique could be used to do a simple, but effective, fake field-of-view blur like the one in GC's Wind Waker, where objects further than a certain distance become blurred.

#65862 - LunarCrisis - Fri Jan 06, 2006 7:57 am

M3d10n wrote:
Looks amazing. This gives us a glimpse of what we might see in future commercial DS software. I see this technique could be used to do a simple, but effective, fake field-of-view blur like the one in GC's Wind Waker, where objects further than a certain distance become blurred.

That would be tricky, since you'd need to have some sort of depth buffer. Perhaps you could render one by colouring everything monochrome and using some sort of fog, but that would take an extra frame away from your fps. =(
_________________
If a tree falls in the forest and no one is there to hear it, why the heck do you care?

#65939 - M3d10n - Fri Jan 06, 2006 11:12 pm

Depth buffer? No need for that:

1) Adjust the camera near-clipping plane to a value close to where you want the things to get blurred.
2) Draw the scene
3) Capture and blur the scene
4) Setup the camera near clipping to normal, and the far clipping plane to a value just slightly greater than the "blur distance".
5) Draw the scene again, using the blurred capture as a background behind the 3D.

The scene will become blurred from a certain distance on. The only issue is that the transition between blurred and sharp will be very hard. But if you have extra CPU time left after all this... there is a way.

Ford Racing 3 uses "alpha fog". Instead of fading to a color, the polygons fade to a background image. Since polygons with the same polygon ID do not blend against each other, this creates a very nice effect with a consistent blending, and could be used to blend the sharp scene into the blurred scene.

#65950 - Darkflame - Sat Jan 07, 2006 12:32 am

I may be wrong, but didnt Majoras Mask on the N64 have depth of field? (at the very last bit, on the moon/field....I am sure I remember there being a lovely blur towards the horizon).

Figure they might have been using a simerla techique.

#65955 - M3d10n - Sat Jan 07, 2006 1:02 am

I didn't make it that far in MM to tell... but since it does some framebuffer tricks here and there, I wouldn't be surprised if it really did it.

#65972 - mntorankusu - Sat Jan 07, 2006 2:23 am

Darkflame wrote:
I may be wrong, but didnt Majoras Mask on the N64 have depth of field? (at the very last bit, on the moon/field....I am sure I remember there being a lovely blur towards the horizon).

Figure they might have been using a simerla techique.

I don't think so. There was a really nice motion blur in that area, and many other areas, though.

#136222 - a128 - Mon Jul 30, 2007 8:33 am

ecurtz wrote:
Here's the promised two pass 3D demo, it took me longer than I expected to get it finished.

I just did some bugfixes of the above method for 3d rendering on both screens.....so this demo works with the latest libnds

BTW you see the 3d teapot on both screens...

Screenshot:
copy the link to your broweser so you can see this image
http://a128.atspace.com/twopass.jpg

Download source:

http://a128.atspace.com/twopass.tgz

#161043 - Meduusa - Sat Jul 26, 2008 10:33 pm

How do I get z-axis to work with this?

Code:
glTranslatef(0.0f, 0.0f, -6.0f);


and

Code:
gluLookAt(0.0f, 0.0f, -6.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);


doesn't seem to have any effect.