• Advertisement

Archived

This topic is now archived and is closed to further replies.

SNES "Mode-7 effect" theory

This topic is 5096 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I really wanted to know this... I wanted to understand the principle behind that pseudo-3D thing you see at some classical console RPGs, or in Mario Kart/Top Gear/etc. I know it has to do with scaling the 2D image line per line. and I also know it is possible to create a relation between the height of the "camera", it''s angle, and thew way the image is disrorted. And I wanted to know exactly how to do it... I tried really hard, but I can''t find any materials on the internet that talk about this... could somebody point me to a document, tutorial, etc. that explains this technique in detail? thanks a lot

Share this post


Link to post
Share on other sites
Advertisement
The SNES had custom hardware that provided the Mode7 effects. I remember reading an atricle that said you could get some very good effects by simply experimenting with differant value in the PPU registers (if you want to search this may be a good strating point).

To do the same thing on a PC you should probably look at OpenGL or Direct3D (direct draw does not let you rotate 2D images which was a part of many mode7 effects). Scaling and rotating a textured quad should provide something approximating what you are looking for.

Share this post


Link to post
Share on other sites
I read that article, but it didn't help me much... it used a method where you used pixel-by-pixel drawing, and this unfortunately does not suit me... -_- I need something more theorical.

Also, I'm using a 2D engine to do this. If I could, I'd simply do it by mapping the 2D map into a 3D surface and positioning it on the screen... but I'm stuck with 2D scaling.

[edited by - Lord Alexion on March 5, 2004 11:21:45 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Lord Alexion
I really wanted to know this... I wanted to understand the principle behind that pseudo-3D thing you see at some classical console RPGs, or in Mario Kart/Top Gear/etc.
You mean 2.5D?

You basically have a sprite-based 2D system, but every sprite also has a z-coordinate. (You can choose whether larger or smaller z values represent being closer to or further from the viewing plane - whether the z-axis points into or out of the screen.) When it''s time to render your objects, you sort them by z and scale them linearly. Presto!

This is what Wolfenstein 3D did for the character sprites, after it had performed the raycast for the environment.

Share this post


Link to post
Share on other sites
Yea, but I needed to know HOW to scale things... and I needed to know more about the environment.

I know you achieve that by scaling the 2D map, but I needed to know the relation between camera angle, geight, and scale factor...

Share this post


Link to post
Share on other sites
quote:
Original post by Lord Alexion
Yea, but I needed to know HOW to scale things... and I needed to know more about the environment.
Scaling a sprite down is a question of averaging pixel values. Say you have a NxM-pixel sprite that you are scaling down by a factor of two. The new dimensions will be (N/2)x(M/2) (which you can determine is 4 times smaller). Consequently, you will need to process your sprites two horizontal pixels and two vertical pixels (4 pixels square) at a time, averaging their color values and rendering the result. It''s similar to anti-aliasing.

Scaling up is the inverse. Rather than averaging, you replicate pixels. Done raw this rapidly makes the image blocky, so you also anti-aliase the edges to improve blending.

quote:
I know you achieve that by scaling the 2D map, but I needed to know the relation between camera angle, height, and scale factor...
If you want arbitrary camera angles, it''s probably better to employ billboarding - place your sprites on polygons (which are naturally scaled, along with the polys that make up the environment) that always face the camera.

Share this post


Link to post
Share on other sites
erm,... OK, but... my problem is not with the sprites, but with the environment. And I''m using a 2D engine to achieve this, so I can''t use polys or surfaces. I want to render the ground as a "mario-kart/early final fantasy overworld map" clone.

Share this post


Link to post
Share on other sites
I''ve never gotten a full mode7 effect going before, but you might want to check out www.gbadev.org, as the GBA has a similar graphics mode and is thusly used to do the mode7 effect pretty frequently. There''s a couple of tutorials on it in the docs section, the one by DarkFader explains a method for calculating the screen coords by raycasting, although he doesn''t explain it too clearly so I haven''t managed to implement it myself. The easiest method is to simply divide the scale by (screen height - current line) and use that. Haven''t figured out how to calculate sprite positions with that method, but it does do the ground. I think you need a more mathematical method like the raycasting to really use in a game. Or a bigger brain than mine to better understand the dividing method.
Also http://www.taswegian.com/TwoHeaded/mode7.html has some theory on it, although I didn''t find it very useful.

Share this post


Link to post
Share on other sites
quote:
Original post by Lord Alexion
I read that article, but it didn''t help me much... it used a method where you used pixel-by-pixel drawing, and this unfortunately does not suit me... -_- I need something more theorical.

Also, I''m using a 2D engine to do this. If I could, I''d simply do it by mapping the 2D map into a 3D surface and positioning it on the screen... but I''m stuck with 2D scaling.

[edited by - Lord Alexion on March 5, 2004 11:21:45 AM]


And which kind of 2D engine is this one of yours, that doesn''t involve per-pixel drawing?

The SNES and the GBA (and the Saturn, for that matter) do the mode7 in the hardware, and they essentially do what is described in that article. A per-pixel operation, in which it reads the tilemap, and determinates which pixel from the tile map should go in there, based on scroll, rotation and scaling.

A GBA/Snes tutorial on mode7 will probably only tell you which registers to mess with to activate the effect. That article tells you how truly it works.

What do you really want?

Share this post


Link to post
Share on other sites
I use a 2D engine called Sphere. It''s not well-known, I suppose, you can get info on it by going to http://sphere.sourceforge.net . That engine CAN realize pixel-by-pixel drawing, but it''s a really REALLY slow method to do that, and I also couldn''t pull it off using that article, maybe because it doesn''t handle fixed-point math very well. The engine can, however, grab slices and lines of the screen, and scale them (and about any image the engine had obtained) with only providing a zoom factor (for uniform scaling) and the XY coordinates of the 4 corners of that image (for non-uniform scaling). So, what I really want is an explanation on how calculating the SCALING FACTORS and OFFSET VALUES of the lines-to-draw.

Share this post


Link to post
Share on other sites
could you then help me with an algorythm that produces this effect using scaling factors instead of pixel-by-pixel drawing please?

Share this post


Link to post
Share on other sites
I made a few builds from my Mode7 Engine(8 months old project).

Here you all go: MindWipe's Mode7 Engine Builds

Try it out to see what's possible.

BTW. I won't check this forum in a week (heading back to the army) but I will check my mail allmost every day.

/MindWipe



[edited by - MindWipe on March 7, 2004 11:55:51 AM]

Share this post


Link to post
Share on other sites
I achieved a similar effect by just using several 2D surface and blitting them to ''imaginary trapezoids'' on the primary surface. I didn''t get too far with it because of time... but it was a start.



I know only that which I know, but I do not know what I know.

Share this post


Link to post
Share on other sites
You need to implement a rotation function on top of your 2D engine. You did say your engine would scale right? I can''t find much info on google, but some of Michel Abrash''s stuff is posted on gamedev, and he explains pixel rotation.

If your engine doesn''t handle pixel blitting very well, as you have suggested, you may want to switch to DX7 since the SNES programmers were masters of pixel operations.

Share this post


Link to post
Share on other sites
quote:
Original post by Lord Alexion
I use a 2D engine called Sphere. It's not well-known, I suppose, you can get info on it by going to http://sphere.sourceforge.net . That engine CAN realize pixel-by-pixel drawing, but it's a really REALLY slow method to do that, and I also couldn't pull it off using that article, maybe because it doesn't handle fixed-point math very well. The engine can, however, grab slices and lines of the screen, and scale them (and about any image the engine had obtained) with only providing a zoom factor (for uniform scaling) and the XY coordinates of the 4 corners of that image (for non-uniform scaling). So, what I really want is an explanation on how calculating the SCALING FACTORS and OFFSET VALUES of the lines-to-draw.


Ah, I see. The engine handles sprites (contained image objects), right? You simply position, rotate and adjust their corners, right?

So, what you want is *not* "mode7". That exact effect could only be done if you were plotting pixels yourself, or of the 2D engine provided such per-scanline control.

With your engine you'll need to perform actual 3D transformations. You need to create a plane grid in 3D, using vectors, transform the vertices into screen coordinates, and place your distorted quads accordling. It's plain 3D graphics using distorted quads, not a scanline zoom hack like mode7.

Take a look at the tutorials here at gamedev. There are some handful of them on software-based 3D graphics, that contain all information in how to setup vectors, matrices and transform 3D space into 2D space.

[edited by - M3d10n on March 8, 2004 6:19:43 AM]

Share this post


Link to post
Share on other sites

  • Advertisement