Page 1 of 1

How 3D on the 3DO really works... ?

Posted: Fri Jan 27, 2017 5:27 pm
by blabla
For a long time, i was wondering how the heck can you do 3D on the 3DO...
Looking at the documentation, everything seemed to imply that the CEL Engine inside the 3DO was 2D hardware, rather than 3D...
I saw absolutely no references to it supporting polygons in hardware.
At first, i thought that all 3D games were software-rendered but the documentation seems to imply framebuffer access is very slow
so it can't be that.
Then i saw this video on the Sega Saturn (turn on subtitles, he's taiwanese) :

At some point, he explains that the fact the Saturn is using quadrilaterals rather than triangles was due to its sprite architecture.
He also explained that the 3D polygons are in fact, distorted sprites.
The 3DO is also using quadrilaterals and its CEL engine is also capable to distorting sprites (scaling, transparency...) just like the Sega Saturn.

So there, 3D games on the 3DO are using distorted CELs in order to create the illusion of 3D.
When you look at other consoles of the era, you can now finally understand why the PS1 was a revolution :
it was the only piece of hardware that was capable of rendering polygons with dedicated hardware without weird tricks,
other than using affine texturing and lacking perspective-correction of course.

So 3DO and Saturn were using distorted sprites/CELs and the Sega 32X was just a dumb framebuffer with two powerful CPUs...
Amiga CD32, FM Towns Marty, PC-FX, Virtual Boy : all of them had no 3D hardware and had to be entirely CPU-rendered.
The only other console with special 3D hardware was the Atari Jaguar :
its "Tom" chip had some instructions for 3D graphics but it's just more powerful than a SuperFX chip...

If it turns out not to be the case though then i don't see how 3D is rendered on the 3DO...
the doc does not help lol

Re: How 3D on the 3DO really works... ?

Posted: Sat Feb 04, 2017 7:49 am
by blabla
Optimus, though unable to register here, contacted me on DIngoonity and he reacted to my post.
We had a very long discussion and after a while, he agreed to post the source code to his 3DO demo :

It can be seen in action here :

I'm still not that knowledgeable about the 3DO so my comments may not be accurate.
Optimus, bug me if you have an issue.

3D Graphics

I got the confirmation that the 3DO is indeed Quad-based.
However, he dislikes the term "Distorted sprites" that many people adopted when talking about the Sega Saturn's VDP chips and how they work.
In his own words :
Because at the end, even the triangles on PS1 are 2D interpolation in the final stage. It's just that quads fit better for sprites too, while you would need two triangles in PS1 to draw a quad for a 2d sprite.
As i suspected, the CEL engine (GPU) only takes care of the drawing : the transformation/distortion/rotations is entirely done on the main ARM60 Cpu.
The 3DO has a math co-processor but it's unknown if the official libraries are even using it or if it even exists (the include headers don't talk about it in length).

He explains how drawing 3D graphics works :
So, anyway the whole process is to rotate/translate 3d points, and in a final state project it back to 2d coordinates on screen. This can be usually done on the CPU...
Now, the quad rasterizer of 3DO takes some vectors. When I have to draw sprite, either zooming/rotated or simple, I have different cases, where I need to calculate less for the vectors needed. So, it's faster to do simple sprites, than zoom than rotate, as I prepare and calculate much less and then prepare my cell quads with the sprite bitmap for rendering. In 3D there is more, I might waste time on CPU, I could invest better ways, but the whole thing is the CPU is used for 3d rotation/transformation, then projection on 2D, my geometry only uses only uses quads instead of triangles, so I have 4 projected 2D points for each quad of the geometry, just have to calculate some vectors for the interpolation
Because the CPU might be bottlenecked by expensive transformation/rotations, Optimus told me he had to resort to fixed-point.
in my demo I used fixed point math to be as fast as possible, because the 3DO is quite slow even for that.
So, the quad rasterization is all on hardware so it's fast enough, no software rendering needed, but to rotate/translate and prepare the cells each frame is on CPU much slower.
I would invite everything to look at his repo he want to know how it is actually implemented.
I'm honestly surprised by how short it is.

3DO Doom

Then we talked about Doom and wondered how the framerate could be improved...
Optimus suggested some ways to improve it :
Doom is drawing the walls using cells, but drawing floors/ceilings with software rendering directly on the videobuffer...
Also, even the walls are drawn as columns, but with many square cels with width 1 and height the height of the column
3DO Doom is partially software rendered, as Bucker didn't have enough time to make the cellings/floor fully hardware rendered.
She did have the time to accelerate the walls though. (she even explained in her livestream how she did it, via ARM assembly)
Also, even the walls are drawn as columns, but with many square cels with width 1 and height the height of the column.
I would expect the most optimal would be to find the rectangle that fits the linedef wall on screen coordinates and only render a single cell per linedef. But interestingly enough, even good ports like PS1 did it like that, many thin triangles as columns, instead of drawing two triangles for a wall surface.
According to Optimus, the walls are drawn very inefficiently using multiple CELs.
However, 3DO's own documentation seems to contradict this :
Huge Cels Draw Slowly
Q: I have a 16-bit, 320-x-440 cel. I'd like to spin it, zoom it, and scroll it over the screen, but when I use DrawCel() to display it, the screen update rate seems to be only 5 to 10 frames per second. If a cel is less than one third the size of the screen, updates seem to occur at 30 frames a second. Do you think I'm doing something wrong?

A: Nothing's really wrong; you're just trying to render a boatload of data. 320 * 400 * 16 bits/pixel == 256000 bytes that the cel engine must crunch through.
Though it's possible i'm wrong or that it does not matter anyway...
Because he admits he does not know Doom's true bottleneck :
But anyway, maybe that's not the bottleneck of Doom (I have to compile and profile). I was talking with Rebecca Heinman on youtube, what she thought needed to be done to optimize Doom, and she was talking about visibility and drawing order, and generally big changes to the flow and structure of Doom might have to be done for speed improvements. Most ports, even PS1 which used the GPU, still rendered many individual stretched columns for each wall surface.
So it seems that even the PS1 port may have been rushed... lol

A while later, he may understood why the walls were drawn like so :
I was kinda thinking what I said about Doom, where you have a single wall and you could fit a single quad to rasterize it, but in 3DO they use many quads with width 1 to simulate column rendering like the original Doom (and even PS1 turns to be doing that, surprisingly, which seem wasteful to me). But I know think there would be technical problems doing it without columns. Maybe they can be overcome with more memory or tricks.
It's no wonder Becker did not bother to optimize Doom's rendering of walls when she had little time to do it.
The thing is, a linedef in doom (it's the 2d line in the map that will be an individual wall) has offsets for U,V, which you can change, and many linedefs don't start from 0,0 and don't end at the end of the bitmap. It's very arbitrary. And from what I see from CELs, they stretch a whole bitmap and I didn't found a way to offset the U,Vs (I don't see such flags for this in the CEL structure. Which is a pitty because there are other effects one could do, like envmapping, by offseting the UVs, but it seems the 3DO will stay in pure texture mapped, not even gouraud shaded, just texture mapped with faded pals to darken a whole quad). I could think of some tricks but it seems it made sense to do column rendering with multiple quads.
I honestly thought the 3DO was able to do gouraud shading but alas it can't.
Good bye potential Mario 64 port.

I wish i could post everything he said but :
- His account did not get approved
- He posted a huge wall of text

He also mentioned how we can achieve faster software rendering (at 320x120) by drawing 2 pixels at a time with a 32-bits int,
the fact that the official 3DO API has functions for 3D and faster routines like fasterMapCels...
Then you could see what I am doing on the 3d engine code. The function fasterMapCels is something I found somewhere in the source code of the official API. I coppied it. They had this and then another funciton which was slower. I don't understand everything from it yet. It takes an arbitrary 4 point Quad and creates the CEL vectors that are needed to be fed. For every quad (which will always change shape in a 3d rotating ojbect) I have to call this everytime, it must be a waste for many polygons. I wish I can find even faster ways.

Re: How 3D on the 3DO really works... ?

Posted: Sun Feb 05, 2017 12:16 am
by Versus
Thank you for the info and 3DOld source! I'll check this in detail later. :arrow:

Re: How 3D on the 3DO really works... ?

Posted: Thu Feb 09, 2017 8:03 pm
by Versus
blabla, is it possible to display current use of VRAM/RAM during the game?

Re: How 3D on the 3DO really works... ?

Posted: Thu Feb 09, 2017 10:49 pm
by Versus
He posted a huge wall of text
Can you upload it?

Re: How 3D on the 3DO really works... ?

Posted: Fri Feb 10, 2017 9:39 pm
by a31chris
Can you just invite him here?

Re: How 3D on the 3DO really works... ?

Posted: Sat Feb 11, 2017 1:59 am
by blabla
a31chris wrote:Can you just invite him here?
Dude, i would like to but Optimus is still waiting for his account to be approved.
Versus wrote:Can you upload it?
Will do it later.

btw, Optimus made a 3D game for the 3DO !
It's very simple gameplay-wise but it looks pretty cool.

Check it out

Re: How 3D on the 3DO really works... ?

Posted: Mon Feb 13, 2017 10:48 pm
by Versus
Cool! Downloaded! 8)

Re: How 3D on the 3DO really works... ?

Posted: Sat Feb 25, 2017 12:02 pm
by Optimus
Hello all!

I managed to approve my account finally.
Thanks for posting the link to my entry btw.

It's very exciting for me to come back to 3DO coding. I have few plans for that future. One is to try to understand everything about the Cel structure, make some performance benchmarks I have in mind, and post some docs about it. The other is to try to make a game. I am really curious to see what's possible with 3D. In my last demo, the grid of quads where 256 and already dropping under 50fps, which is ok keeping in mind most 3DO games have slower frame rate, but I want to investigate because the theoritical is 3000 quads at 50fps (150000 per sec) although those theoritical specs don't reflect reality, so I will be happy if I reach 500-1000 (and you don't need much per scene if you design 3d models cleverly, a lot of cool oldschool games have 200-300 on screen at once). Generally, I want to really dive into how to push up more polygons and try to make a first person walk through some 3d scenes, maybe design a game from that. I might also try some setups for 2D games (I was discussing with blala about tile rendering in evil australians, and I have some ideas I want to try)

Also I am very excited recently when I managed to compile Doom and started doing some performance tests. It was a bit messy to get everything working, with burgerlib, the data files, everything (there are some conflicts of some typedefs and structs with 3DOlib) but the one button compile project from Versus helped (thanks!). Right now I just added a frame counter and use two buttons to enable/disable floor/ceiling or wall rendering, just to see how it affects performance. The game is locked at 30fps (but on emulators it shows 60fps) but of course usually it's much less, from 15-20 to 7-10 at worse cases, starting at the default screen size. I can't make up my mind if floors or wall surfaces are more costly (I walk the player at various positions and checked), depends on how much it's covered, but none of them seemed to eat more speed than the other. In some cases where the camera is looking at far distances, disabling the rendering of both would still go from 7fps to 12fps, this means even the visibility and preparation for rendering takes time. So, maybe a lot of different parts take equally time, nothing spends much more than the others, so optimizing it would be a hard task, because one has to do a little bit of work on many different places, while optimizing for example only the wall rendering will not necessary improve overall. It's gonna be an interesting task and I will also use my other performance profiler tool, which is a bar with colored times for different parts, so I can see the overall percentage of wall rendering, floor/ceiling rendering, BSP calculation, preparation, rendereing of sky/bar, and more, and see visually which is taking what percentage of the overall time.

Anyway, that's just to say high and what I am working with. I might resume discussion at some point in some other threads.

Re: How 3D on the 3DO really works... ?

Posted: Sat Feb 25, 2017 11:16 pm
by Versus
Welcome aboard, Optimus! I'm adding a new types of monsters and other objects in Doom. I think that at some point RAM became full (some freezes and frequent CD reading occurs). Could you make some kind of progress bar for RAM? It will be very helpful.
Now I'm thinking how to use sounds quickly without loading all of them to RAM (now they are all loaded in while startup)... Do you have any suggestions?

Re: How 3D on the 3DO really works... ?

Posted: Sun Feb 26, 2017 4:27 am
by blabla
Phew, finally !
I personally have a hard time with the CEL format, as they are quite unconventional.
You could have 10 cels and have the game run at 60 fps... then you add another one and it drops to 25 fps :/
I'm guessing it should run faster if you're using 6-bits CELs (according to 3DO it should) but perhaps you are already doing that.
Versus wrote:Now I'm thinking how to use sounds quickly without loading all of them to RAM (now they are all loaded in while startup)... Do you have any suggestions?
You could compress the sounds to AIFC and stream them off the CD. Of course, it will most likely destroy your drive in the long-term.
You could also decrease the quality to 8-bits 11khz... but i think 3DO Doom already does that.
Looking at the documentation, it seems to be possible to decode ADPCM 4-bits sounds but it sounds so horrible, you should avoid it.

Re: How 3D on the 3DO really works... ?

Posted: Sun Feb 26, 2017 12:35 pm
by Versus
blabla wrote: You could compress the sounds to AIFC and stream them off the CD. Of course, it will most likely destroy your drive in the long-term.
I think, that's the only way to make it... As for CD-drive, the original game streams music from CD very hard even when volume slider is set to 0. I sovled that issue, so it will increase the CD life. But streaming sounds from CD will turn that bonus back, actually... ) Before sound starts, it must be read from CD, so the game will freeze sometime.

Re: How 3D on the 3DO really works... ?

Posted: Sun Feb 26, 2017 2:47 pm
by Optimus
Versus wrote:Welcome aboard, Optimus! I'm adding a new types of monsters and other objects in Doom. I think that at some point RAM became full (some freezes and frequent CD reading occurs). Could you make some kind of progress bar for RAM? It will be very helpful.
Now I'm thinking how to use sounds quickly without loading all of them to RAM (now they are all loaded in while startup)... Do you have any suggestions?
I think I could make a bar showing the used memory. I have displayed the memory in one of my old codes, I have found a Meminfo object in the API, it returns a struct with four variables, one is the free memory and the others I don't totally understand, but I think it helped knowing how much memory is free in my own projects. I could easily use this I think to display visually with a bar in Doom. Doom is very tight on memory and it's good to know how much is left. Even my own optimization attempts will need some additional memory possibly. Ok, when I get back into it I might try to make one and share some code.

Btw,. it's quite easy to get it:
MemInfo *mi;
mi = malloc(sizeof(MemInfo));
AvailMem(mi, MEMTYPE_ANY);

MemInfo holds these:

I am not sure what some of these are, the numbers don't necessarily make sense. But one of them does.
But I will make a bar. It's easier than printing fonts (although for my frame counter I have a set of number bitmaps that I draw in a cell, I could use this to print the values of memory too).

Re: How 3D on the 3DO really works... ?

Posted: Sun Feb 26, 2017 2:59 pm
by Versus
Thank you, Optimus! I'll wait your bar. If you need help with some textures/sprites/fonts, I wrote all the converters. Also I made a small font in 3DO Doom format. Maybe it will be useful for you.

Re: How 3D on the 3DO really works... ?

Posted: Tue Feb 28, 2017 9:32 pm
by Optimus
Btw, the code I posted about memory, won't report anything in Doom. The reason is, another memory manager is used in Burgerlib that cancels the one from the system.

But the good news is there is also a function to get the available memory in Burgerlib. And it's much easier. You only need to add two lines of code to get a single bar, in the UpdateAndPageFlip function on threedo.c, after WipeDoom and before DisplayScreen you add this:

DrawARect(0,200-48, (GetTotalFreeMem() * 320) / (3 * 1024 * 1024),2, MakeRGB15(31,31,31));

I divide by 3 * 1024 * 1024 because I assume the max memory of 3DO is 3MB (2MB and 1MB Vram that can also be used as regular memory). The bar seems ok. I tried to increase some array in code and it corresponds, at least you will be sure if it reaches zero length you are toasted.


p.s. I am also doing some tests, managed to put the benchbar (I will post this later, maybe in another thread) and I have some interesting results. The BSP calculations and sprite preparation for rendering are minimal, maybe 10%. The majority of performance is lost in three things. Preparation of columns for wall rendering, preparation and software rendering of floor/ceiling spans, and a code that I think from wall columns calculates the visplane edges for floor/ceiling rendering, but also calls for sky rendering. At some moments these take equal time, most of the time walls are more expensive (especially near stairs, many new upper/lower walls columns to prepare). I understand why these have to be drawn as columns (if I go and fill whole surfaces with single quads, I will lose the smooth shading and also maybe the texcoords offsets will be hard or impossible) but I have some ideas I will try in the future. And for now, something slightly easier would be to prepare/render half columns and double scaled on X, so halfRes on X, I made a simple test but there are bugs but there seemed already to be some improvement on emulator just like that. I could maybe do the same on floor/ceiling. So, this won't be an optimization but lowres settings. Anyway, I am thinking to open a dedication forum thread discussing optimizing Doom, maybe the very next time I have something.

Re: How 3D on the 3DO really works... ?

Posted: Tue Feb 28, 2017 10:25 pm
by Saffron
Hi, I just want to try to explain the 3D rendering.

First of all, you must forget current technology, the way 3D is done today has nothing to do with the early 90s. PSX, Saturn and 3DO were designed as what you would consider 2D render machines.

Wait! I'm not crazy! :P we've all seen 3D games in those platforms. Yeah, but they were not "modern 3D" games, that didn't happened until N64, which was the first mayor console featuring a modern GPU, with Z-buffer and such.

PSX had a incredible (for the time) co-processor for math operations. Much better than what 3DO or Saturn had. But the way 3D was created was in fact very similar:

In early days of 3D graphics, quads were an alternative to triangles, and some machines like 3DO or Saturn used them for 3D. PSX used triangles, but the actual way of drawing them was very similar. Neither of them had a z buffer, texture correction, or anything that modern GPU have.

At that time, 3D had to be calculated with fixed point math, and normally only affine texture correction was used, which means that you can't use big polys, but instead any big object like a big wall must be broken in sections of quads or polygons so the texture perspective doesn't seems broken.

so games had to deal in software with any sort of z-buffer algorithm, frustum culling, etc... get the projection from the 3d scene to the 2d scene, and then drawing the quads or polygons in the frame buffer with the help of the hardware.

PSX with the math co-processor could work a lot faster and in a easier way. 3DO in theory can do a lot better than the current SDK, which was abandoned so early, but still has a weak CPU and the two GPUs are still no match for PSX. And Saturn has problems of its own, which I think escapes this general explanation.

so to try to resume:

with current hardware, you define a 3D scene, with camera, etc, and send all info to the GPU to render it.
with early 90s hardware, you had a 3D scene, had to calculate the 2D projection of the camera, and then send that 2D quads/polygons projection to the GPU.

so in a way, those consoles were still 2D hardware, compared to what we understand as current 3D hardware. It wasn't until N64 was released that you could work in 3D like you do with opengl or direct3d.

hope this explanations helps!

Re: How 3D on the 3DO really works... ?

Posted: Wed Mar 01, 2017 10:43 pm
by Versus
Thank you, Optimus! I'll post the results here :arrow: ... 5&start=30
That thread is more suitable I think.

Re: How 3D on the 3DO really works... ?

Posted: Sat Nov 17, 2018 1:59 am
by Optimus
I just released my new video explaining the basics about how the 3DO CEL vectors work out to stretch a bitmap to produce from basic zoomrotating sprites to quad polygons to obscure shapes. There is later some footage on the use of a flag called CCB_MARIA which will disable the texel fill and only render the CEL grid with dots. It was used to give the impression of exploding dot enemies in Total Eclipse, but I also enabled it for fun in Doom 3DO on this video.