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.

Coding > Fog effect

#11289 - poslundc - Wed Oct 01, 2003 3:01 pm

So I'm thinking that I'd like to apply a fog effect to my background.

Naturally the easiest way to do this would be to use BLMOD and lighten/darken the background on each HBlank. I get the feeling that this is the way I will end up doing it... but then, of course, it ties up the effects register so I can't have any alpha effects wherever I've got fog.

I've tried coming up with some other ways of doing it... I thought about precalculating the necessary palette values when the background is loaded and blitting out the appropriate set with DMA on HBlank, but it would take an awful lot of precious, precious memory to do so. (256 colours * 2 bytes per colour *, say, 64 levels of fog = 32K of EWRAM.) Plus the DMA transfers alone would take 128 cycles, which is more than half my HBlank, and I don't so much like the idea of monopolizing my HBlank time with it. (I probably would not use all 256 colours for the background, so this would be improved upon, but it's still a lot fatter than I would like.)

Any suggestions?

Thanks,

Dan.

#11290 - tepples - Wed Oct 01, 2003 4:50 pm

What are you currently using blending effects for?

One thing you could try is a layer of supertransparency for your fog.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#11297 - poslundc - Wed Oct 01, 2003 6:33 pm

tepples wrote:
What are you currently using blending effects for?

One thing you could try is a layer of supertransparency for your fog.


As for the question what I'm using the blending effects for, I'm currently making my "status" layer semi-transparent (which is a luxury I can live without, I know, but I like it), and I'm planning on using it for some visual effects (which would displace the status layer when active, so no sharing problems there).

That supertransparency effect looks really neat... I might just use the alpha for the fog and then supertransparency for the other stuff. I'm not sure I quite "get it", though. If I understand the method correctly, you alternate every frame (ie. every 60 Hz) such that on even frames it displays even scanlines, and odd frames it displays odd scanlines. But if the GBA LCD is interlaced at a rate of 30 Hz, wouldn't that just display either the entire sprite or none of the sprite, depending on where the timing happens to fall?

Or is the strategy supposed to be to switch every other frame so that you switch from displaying even/odd scanlines every 30 Hz? (IOW, switch every "superframe", which means you're really switching every two regular frames?) This makes more sense to me, although it seems like it would be more likely to cause flicker at that rate, too.

Thanks,

Dan.

#11299 - tepples - Wed Oct 01, 2003 7:33 pm

poslundc wrote:
As for the question what I'm using the blending effects for, I'm currently making my "status" layer semi-transparent (which is a luxury I can live without, I know, but I like it)

I don't remember any Super NES game that had a truly semi-transparent status bar.

Quote:
and I'm planning on using it for some visual effects (which would displace the status layer when active, so no sharing problems there).

Which of these visual effects are you planning on running at the same time as fog? I may be able to help you figure out other ways to fake them.

Quote:
That supertransparency effect looks really neat... I might just use the alpha for the fog and then supertransparency for the other stuff. I'm not sure I quite "get it", though. If I understand the method correctly, you alternate every frame (ie. every 60 Hz) such that on even frames it displays even scanlines, and odd frames it displays odd scanlines.

Either that, or it displays even columns in one frame and odd columns in the next frame, or pixels that are red on a checkerboard in one frame and pixels that are white on a checkerboard in the next frame, or just two randomly error-diffused images, etc.

Quote:
But if the GBA LCD is interlaced at a rate of 30 Hz

Actually, the GBA LCD isn't truly interlaced. It just seems to draw every other row a bit darker on every other frame.

Quote:
wouldn't that just display either the entire sprite or none of the sprite, depending on where the timing happens to fall?

It seems that the technique as given would just make it a bit lighter than 50% or a bit darker than 50%.

Try supertransparency with two dithered fog images and see if you like the effect.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#11301 - poslundc - Wed Oct 01, 2003 8:21 pm

tepples wrote:
I don't remember any Super NES game that had a truly semi-transparent status bar.


Can't say I do either, but I'm expecting to have to bring up menus, map overlays, etc. on the field and having some translucency can help conserve screen real-estate.

tepples wrote:
Which of these visual effects are you planning on running at the same time as fog? I may be able to help you figure out other ways to fake them.


Mostly things like spell effects (lightning, ice, etc.) and possibly to have characters appear/disappear from the playing field with more than just palette fades.

tepples wrote:
Actually, the GBA LCD isn't truly interlaced. It just seems to draw every other row a bit darker on every other frame.
...
It seems that the technique as given would just make it a bit lighter than 50% or a bit darker than 50%.

Try supertransparency with two dithered fog images and see if you like the effect.


Hm, well, I'll be sure to give a try. I've got the extra space at the bottom of my backdrop to do it in (ah, the convenience of having 256x256 maps when the screen is only 160 pixels tall!), so I can just switch the backdrop's y-scroll when I get to the horizon to a value based on the pitch of the camera.

I kind of had my heart set on a more mathematical approach (I wrote this raycaster, after all), but I'll take "looks good and more efficient" over "accurate and less practical" any day of the week.

Dan.

#11302 - DekuTree64 - Wed Oct 01, 2003 9:58 pm

Hmm, so is this like an RPG battle system with a free rotating camera? Cool, that's exactly what my first GBA project was going to be. Unfortunately I never figured out how to position sprites on the mode7 ground, but still it will be nice to see something like it^_^
As for the transparency, I'd say use the blending regs for the meuns, since you'll be reading stuff on them, and any sort of flicker would be really irritating. For the fog, using 2 randomly dithered images and switching back and forth between them each frame would probably be noticable, but I think it might look more foggy than real transparency. For spell effects I'd just use regular flicker transparency, or maybe the super-transparency trick if it looks better and you have enough processor time for it. Or maybe 2 every-other-pixel dithered images if you have enough sprite mem.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#11308 - poslundc - Thu Oct 02, 2003 2:34 am

DekuTree64 wrote:
Hmm, so is this like an RPG battle system with a free rotating camera? Cool, that's exactly what my first GBA project was going to be.


Heh, I guess the cat's out of the bag... but I hate to extol too much about a project that is still very much on the ground floor. It's basically a normal, 2D-overhead RPG, but battles will take place on a pseudo-3D Mode7 landscape. And the battles are action-based, too, with a party of four characters (sometimes five, if it turns out the GBA can handle it!). Kind of like Star Ocean 2, if you've ever played it.

The camera is able to freely rotate, but it will probably actually be locked at a uniform pitch, rotation and distance throughout most of the gameplay. Rotation, zooming etc. will be more for special effects and such. I've written a nice little motion engine that lets me keyframe-animate effects combining pitch, zoom, rotation and movement. It's going to allow for some pretty sweet visual effects, like having the camera move in a circle around a fixed point, or swoop down and glide around an enemy for a closeup.

DekuTree64 wrote:
Unfortunately I never figured out how to position sprites on the mode7 ground, but still it will be nice to see something like it^_^


It's a bit tricky math... I probably made everything twice as convoluted as it had to be, all in order to avoid ever having to take the square root. :)

I basically figured that in order to get the correct length of the ray to a sprite, I needed to take the length of a ray from the camera to the point of interest, then either add or subtract the difference between that and the ray I wanted, which could be found using similar triangles. In order to get the length of one of the sides of the triangle, it was necessary to take the y-distance on the map between a sprite and the point of interest (after taking rotation into account). The rest is just trig... I was actually surprised that it worked as well as it did. :P

DekuTree64 wrote:
As for the transparency, I'd say use the blending regs for the meuns, since you'll be reading stuff on them, and any sort of flicker would be really irritating. For the fog, using 2 randomly dithered images and switching back and forth between them each frame would probably be noticable, but I think it might look more foggy than real transparency. For spell effects I'd just use regular flicker transparency, or maybe the super-transparency trick if it looks better and you have enough processor time for it. Or maybe 2 every-other-pixel dithered images if you have enough sprite mem.


I think I only need one image for the fog... it's mostly to add a lighting/shading element to the Mode7 perspective, really. Anyway, I'm still hacking at code but I will probably post a couple of screenshots if it works out okay.

Dan.

#11311 - DekuTree64 - Thu Oct 02, 2003 4:07 am

Hehe, mine was going to be turn based, but that's exactly the kind of stuff I wanted to do with it.
But just picturing it, you mean fog to show distance, right? I was thinking constant over the whole screen. That would be a lot nicer with blending, changing the transparency level on HBlank to fade nicely.
I guess you could have like 3 or 4 dither pattern tiles and have like one row of tiles solid fog color, one row dithered every other pixel, the next with an even more transparent pattern, etc. Then just scroll the dither layer on HBlank to where the right pattern is on the row that's being drawn. Then flash that off and on each frame and maybe randomize the X scroll so the patterns are harder to notice.
Hey, you could even 'dither' between patterns by like having one row show the solid pattern, the next row show the every-other-pixel one, then back to solid, back to every-other and so on and then switch over to fully every-other, you get the idea.

This is making me want to try again at it^^ But actually I think with my experience writing the tri-fillers for my demo I could make some fast enough that I might just make my RPG's battle system fully 3D, with sprites for the characters of course. That way I can just transform the sprites' positions like any other vertex.
The real problem will be drawing the sprites for all those characters and monsters from probably 8 directions. And non-animated monsters would look pretty boring in a 3D environment so that mutliplies the drawing a few more times.
Oh well, it's worth a try anyway, just to see if it would work^_^
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#11312 - poslundc - Thu Oct 02, 2003 5:18 am

DekuTree64 wrote:
But just picturing it, you mean fog to show distance, right? I was thinking constant over the whole screen. That would be a lot nicer with blending, changing the transparency level on HBlank to fade nicely.

Yeah, fogging is actually a technical term (well, technical as far as I know) for gradually fading your view to a certain colour (usually white or black, but not necessarily) the further you get away from the camera. It's usually a pretty cheap way to add some extra depth to your scene, and it's perfect for Mode7 since it just uses the distance values you calculate anyway.

Only problem is that unless I change the palette on every HBlank (which is quite resource-consuming), I need to tie up my alpha blending register in order to lighten/darken the background different values each scanline.

What I am now trying is instead of actually doing either of those, I instead overlay a single-colour image of a dithered gradient (solid at the top, transparent at the bottom), and position it at my horizon. Make it 50% transparent using supertransparency, and it should have a similar visual effect that actual fogging would. As the pitch of the camera goes down (and the background loses perspective), this image is then shifted up so that less of the gradient is visible, and it appears as though there is less fog.

It's not perfect, but if it works it will save me the alpha blending and be a heck of a lot less computationally expensive than swapping palettes every scanline.

DekuTree64 wrote:
This is making me want to try again at it^^ But actually I think with my experience writing the tri-fillers for my demo I could make some fast enough that I might just make my RPG's battle system fully 3D, with sprites for the characters of course. That way I can just transform the sprites' positions like any other vertex.
The real problem will be drawing the sprites for all those characters and monsters from probably 8 directions. And non-animated monsters would look pretty boring in a 3D environment so that mutliplies the drawing a few more times.
Oh well, it's worth a try anyway, just to see if it would work^_^

Despite all the work I'm doing on this Mode7 stuff, I'm not that big a fan of 3D. I like Mode7 because it's an easy, hardware-friendly way of adding a twist of 3D to liven things up without bogging down the gameplay or the processor (one of the reasons I'm keeping the gameplay largely 2-dimensional in nature). 3D games have come a long way, but IMHO the GBA just isn't really well-suited to the task. Even if you could get apps like Yeti running at 60 fps, and have memory enough to animate really sophisticated models, the screen is too small and the controls too simple to make a game that could really take advantage of what a fully 3D environment has to offer.

That's why I'll stick to my Mode7 + raycasting for all kinds of nifty visual effects, layered on top of what is fundamentally a 2D game.

To each his own, though; I would love to be shown how wrong I am.

Dan.

#11384 - poslundc - Fri Oct 03, 2003 8:54 pm

Well, I tried overlaying a fog background that used diffusion dither and one that used pattern dither... regrettably they both looked like crap, even with the supertransparency.

(Which, BTW, I could not get to work reliably on hardware... not that it would work on software, but at least on software I saw the flickering patterns. On hardware I would see a somewhat-flickery supertransparent image for about the first 40 columns or so, then the background would mysteriously disappear entirely for the remaining 200 columns. I hope I can figure out what I did wrong, because it's an effect I am sure I will want to use at some point later on.)

<sigh> I think I will just have to concede that if I want my fog, I'm going to have to eliminate alpha effects from the rest of the game (except where I can use supertransparency, assuming I can get it to work properly.)

The only other option I can think of is to DMA0 200 palette entries or so every HBlank, and while that WOULD solve my problem for now I have a strong suspicion it would come back to bite me in the ass when I want to do other stuff in HBlank later on; not to mention the memory consumption needed to maintain a palette for every level of fog.

If anyone has any more ideas, I'm listening.

Thanks,

Dan.

#11385 - tepples - Fri Oct 03, 2003 11:38 pm

Super NES games that used distance fog on their Mode 7 backgrounds, such as F-Zero, typically used the blending registers.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.