small3dlib, public domain 3D software rasterizer

small3dlib, public domain 3D software rasterizer

Postby drummyfish » 02 Jul 2019, 15:32

Hello, I've written a small public domain software renderer that can be used for simple 3D games:

https://gitlab.com/drummyfish/small3dlib

Image Image Image Image Image Image

Why do this when we have OpenGL and a billion of fine-tuned super quality 3D renderers? It has advantages that can be useful to you.

It has zero dependencies, is written in pure C99 (compiles as C++ as well), in a single file, simple to use (KISS, suckless, no ugly API like OpenGL that you need to study for a decade), using only 32 bit integer math (no float), doesn't require any GPU or coprocessors (no HW hassle, easy debug), is AFAIK pretty optimized and tested on multiple devices. This means you can use this on PC as well as on small embedded gaming consoles or a toaster (I've tested it on my two embedded consoles, Pokitto and Gamebuino META). You don't need to deal with build systems, OOP, package managers, or similar bloat. It is still flexible, you can write practically any shader you could write in OpenGL. It is also completely public domain (CC0 + waiver of other IP like patents), there are exactly zero conditions on usage. Start selling it, use it for good or evil, I don't care about anything else other than that I am not able to sue you over it. Your behavior is your responsibility.

Simply copy-paste it and use it, modify it, hack it, do whatever you want.

Further info in the repo.

Also note I made it myself in my spare time over a few weeks and it's probably still buggy, so don't yell at me. Provided AS-IS, no guarantees.

If you like it, also check out my similar library for raycasting, raycastlib.
Last edited by drummyfish on 02 Jul 2019, 18:52, edited 1 time in total.
socialist anarcho-pacifist
Abolish all IP laws. Use CC0.
http://www.tastyfish.cz
User avatar
drummyfish
 
Posts: 226
Joined: 29 Jul 2018, 20:30
Location: Moravia

Re: small3dlib, public domain 3D software rasterizer

Postby fluffrabbit » 02 Jul 2019, 17:46

And it's single-header and a little over 2000 lines of code. Most of the demos seem to work without libm as well. With a Z-buffer. And it's smooth. You are a god.

Here is a makefile:

{l Code}: {l Select All Code}
CFLAGS=-std=c99 -Wall -Wpedantic -Wextra -g

all: city level modelViewer helloTerminal highPoly hqOffline test

city: city.c ; $(CC) $(CFLAGS) -o $@ $@.c -lSDL2

level: level.c ; $(CC) $(CFLAGS) -o $@ $@.c -lSDL2

modelViewer: modelViewer.c ; $(CC) $(CFLAGS) -o $@ $@.c -lm -lSDL2

helloTerminal: helloTerminal.c ; $(CC) $(CFLAGS) -o $@ $@.c

highPoly: highPoly.c ; $(CC) $(CFLAGS) -o $@ $@.c

hqOffline: hqOffline.c ; $(CC) $(CFLAGS) -o $@ $@.c -lm

test: test.c ; $(CC) $(CFLAGS) -o $@ $@.c -lm

clean: ; $(RM) city level modelViewer helloTerminal highPoly hqOffline test


That perspective-incorrect texture mapping brought back PlayStation childhood memories. It also felt at least as smooth as the PS1 did, despite the framerates, leading me to believe the PS1 was less powerful than it seemed at the time. That terminal demo is very Matrix-ish. This is the most exciting piece of software I've seen in months. Wow.

There is a list which I'm sure you're aware of. This should be on it. Either you can open an issue there for it or I will.

Intel Celeron dual core 2.16 GHz.

Performance in debug mode
14-16 FPS on city, 12 FPS on level, 17-39 FPS on modelViewer.

Performance when I replace -g with -O3
43-55 FPS on city, 31-49 FPS on level, 35-56 FPS on modelViewer.
fluffrabbit
 
Posts: 570
Joined: 11 Apr 2019, 11:17

Re: small3dlib, public domain 3D software rasterizer

Postby drummyfish » 02 Jul 2019, 18:43

Thank you :-) I'm not actually even sure what CPU I am using right now but with -O3 I have even some 130 FPS, but it all depends on the resolution, how big the objects actually are when rendered etc. I know about that GitHub list you linked, I actually wanted to make a PR but forgot to do it. Thanks for reminding me!
socialist anarcho-pacifist
Abolish all IP laws. Use CC0.
http://www.tastyfish.cz
User avatar
drummyfish
 
Posts: 226
Joined: 29 Jul 2018, 20:30
Location: Moravia

Re: small3dlib, public domain 3D software rasterizer

Postby fluffrabbit » 02 Jul 2019, 19:22

Thank YOU.

I use a program called hardinfo. My stats refer to the default resolutions of the respective programs (mostly 640x480). I think for performance and end-user-friendliness it may be desirable to render at half the desktop resolution and scale to fill with SDL or OpenGL.

At 1366x768, I will begrudgingly admit that software Mesa is close to twice as fast at comparable fill coverage (25 FPS vs 14-ish), likely due to assembly, but it looks like small3dlib keeps it simple by sticking to C, which is a desirable property for me. Also multithreading may have something to do with it. OpenGL uses a client-server model, so it seems likely that Mesa will spawn threads when software rendering, while AFAIK the small3dlib demos all showcase impressive single-threaded performance.
fluffrabbit
 
Posts: 570
Joined: 11 Apr 2019, 11:17

Re: small3dlib, public domain 3D software rasterizer

Postby drummyfish » 02 Jul 2019, 20:03

Yes, my library has to pay some performance for that portability, e.g. I think that using floats would actually be faster on platforms that have FP coprocessor than using integer (basically fixed point) math, because the integer way sometimes requires more operations. But we already have plenty of renderers that do that, I rather felt like creating something that was missing.

fluffrabbit {l Wrote}:PS1


Another thing that makes it PS1-like is the lack of subpixel accuracy :) I kinda like that in renderers, it feels real retro.
socialist anarcho-pacifist
Abolish all IP laws. Use CC0.
http://www.tastyfish.cz
User avatar
drummyfish
 
Posts: 226
Joined: 29 Jul 2018, 20:30
Location: Moravia

Re: small3dlib, public domain 3D software rasterizer

Postby fluffrabbit » 02 Jul 2019, 20:33

By subpixel accuracy I assume you mean bilinear filtering. While that would smooth things out more, the dicontinuity between triangle halves (I think that's what I'm seeing) would still create hard seams. The perspective seems to be applied on a sub-polygon level as far as I can see. There also appears to be a sort of quilting pattern to smooth out the edges of texels at certain angles, or maybe that's just a side effect. In any case, I really want to make a Spyro clone. I've got so many project already, and 3D takes more effort, but man, it's so tempting.

Also the GameBoy Advance's lack of FPU and crap-tastic display resolution sound like a good fit for this library. It's got an ARM processor, so I imagine performance would be comparable to other devices you've tested this on.
fluffrabbit
 
Posts: 570
Joined: 11 Apr 2019, 11:17

Re: small3dlib, public domain 3D software rasterizer

Postby drummyfish » 02 Jul 2019, 21:16

I've been dreaming about Crash Bandicoot clone for some time now, anyway I think we really need that oldschool PS1 feel.

By subpixel accuracy I mean the coordinates of triangles you rasterize are always rounded to whole pixels, which was the case on PS1. OpenGL coordinates are float -- the endpoints still have to be rounded to a nearest pixel, but the fraction part affects how the edges are rasterized. Here is an example:

Image (pixel accuracy)
Image (subpixel accuray)

Mostly you can't tell the difference, but the subconsciousness knows :)
socialist anarcho-pacifist
Abolish all IP laws. Use CC0.
http://www.tastyfish.cz
User avatar
drummyfish
 
Posts: 226
Joined: 29 Jul 2018, 20:30
Location: Moravia

Re: small3dlib, public domain 3D software rasterizer

Postby fluffrabbit » 02 Jul 2019, 21:31

drummyfish {l Wrote}:I've been dreaming about Crash Bandicoot clone for some time now, anyway I think we really need that oldschool PS1 feel.

Then it's my dragon vs your marsupial. Those two studios were by far the best western developers for the PS1.

drummyfish {l Wrote}:Mostly you can't tell the difference, but the subconsciousness knows :)

I do see it. Without subpixel accuracy it's slightly chunkier. An entire surface would be shifted to the nearest pixel rather than each texel edge.

Didn't the PS1 also guarantee that every polygon gets rendered to at least 1 pixel no matter how small? One of the Crash developers talked about it in a series of blog posts.
fluffrabbit
 
Posts: 570
Joined: 11 Apr 2019, 11:17

Re: small3dlib, public domain 3D software rasterizer

Postby drummyfish » 02 Jul 2019, 23:55

fluffrabbit {l Wrote}:Didn't the PS1 also guarantee that every polygon gets rendered to at least 1 pixel no matter how small?


Wow, you're right! found it

The PlayStation tended to render every polygon as a pixel, no matter how small it got. Had Crash’s pupils been texture, they might have disappeared when the got smaller than a pixel. But by making the pupil 2 polygons (a quad), they almost always showed up as long as the total eye, including whites, was more than a few pixels tall.


This is pretty interesting -- for the library I had to study rasterization rules a bit, because it is important to guarantee that adjacent triangles have no holes between them, but also don't overlap, which could cause flickering (and would also waste pixels). The usual approach is the so called "top-left" algorithm, which I also used, and in it it is not the case that a polygon would always have to be rendered at least as a one pixel. I can't see the "always at least one pixel" rule being a part of a rule system that doesn't cause pixel overwriting and flickering with adjacent triangles -- imagine a quad composed of two triangles, one red and one blue, so far away that they both map to one pixel -- they will have to fight for it and we can see red/blue flickering. I wonder if that was simply an imperfection of the early rasterizer, or if the devs just got the feeling it was so (this may be the case as they say "almost always"). Am going to investigate this.
socialist anarcho-pacifist
Abolish all IP laws. Use CC0.
http://www.tastyfish.cz
User avatar
drummyfish
 
Posts: 226
Joined: 29 Jul 2018, 20:30
Location: Moravia

Re: small3dlib, public domain 3D software rasterizer

Postby fluffrabbit » 03 Jul 2019, 00:27

PS1 is z-sorted rather than z-buffered, so my assumption was that Sony didn't care about overdraw and the triangle rasterization algorithm was zealous with how the edges were rasterized to MAKE SURE there were no seams. Some kind of naive mathematical solution or something like that.
fluffrabbit
 
Posts: 570
Joined: 11 Apr 2019, 11:17

Re: small3dlib, public domain 3D software rasterizer

Postby fluffrabbit » 10 Jul 2019, 03:40

I think I've found my first gripe with this otherwise amazing software.

{l Code}: {l Select All Code}
#define S3L_HALF_RESOLUTION_X (S3L_RESOLUTION_X >> 1)
#define S3L_HALF_RESOLUTION_Y (S3L_RESOLUTION_Y >> 1)

#define S3L_PROJECTION_PLANE_HEIGHT\
  ((S3L_RESOLUTION_Y * S3L_FRACTIONS_PER_UNIT * 2) / S3L_RESOLUTION_X)


Preprocessor code like this makes it impossible to resize the screen at runtime. Presumably this is for performance, but kids these days like automatic screen resolutions, or at least resolution selection. On DOS or something with a fixed screen size, no problem. Automatic screen sizes and multiple render targets at various resolutions would be problematic.
fluffrabbit
 
Posts: 570
Joined: 11 Apr 2019, 11:17

Re: small3dlib, public domain 3D software rasterizer

Postby Technopeasant » 10 Jul 2019, 04:22

This is pretty cool. I like the raycaster too. Do you have any pre-built demos available?
User avatar
Technopeasant
 
Posts: 34
Joined: 22 Feb 2017, 03:38

Re: small3dlib, public domain 3D software rasterizer

Postby fluffrabbit » 10 Jul 2019, 10:19

Technopeasant {l Wrote}:This is pretty cool. I like the raycaster too. Do you have any pre-built demos available?

Don't take EXEs from strangers. Install mingw-w64 or Visual Studio and learn how to compile C programs.

That said, I learned how to cross-compile for Winblows today. Yay! Here is the city demo.
Attachments
city_demo.zip
(1.09 MiB) Downloaded 18 times
fluffrabbit
 
Posts: 570
Joined: 11 Apr 2019, 11:17

Re: small3dlib, public domain 3D software rasterizer

Postby drummyfish » 10 Jul 2019, 10:33

fluffrabbit {l Wrote}:Preprocessor code like this makes it impossible to resize the screen at runtime.


Yes, this is on purpose, because of performance and simplicity, I mention this limitation in the readme. It is still a small 3d lib :) There is always this conflict between compile-time vs run-time, performance vs flexibility -- I tried to go with what seemed to suit the most likely scenarios, e.g. people using this on embedded devices, which mostly have fixed size screens and no windows. I also considered making e.g. the field of view a compile-time option, but with that I figured that could be too limiting.

That said, the philosophy of these libs I make is a bit different from the "big" libraries, which are not trivial to fork and modify. You're supposed to copy-paste my single file libs into your project repository and possibly modify them to suit your specific needs -- you can easily change the define to e.g. a global variable and change it at runtime. Yes, updating to newer versions will be more problematic, but as I say, there is plenty of libraries with the traditional philosophy that you can use if that is what suits you better.
socialist anarcho-pacifist
Abolish all IP laws. Use CC0.
http://www.tastyfish.cz
User avatar
drummyfish
 
Posts: 226
Joined: 29 Jul 2018, 20:30
Location: Moravia

Re: small3dlib, public domain 3D software rasterizer

Postby fluffrabbit » 10 Jul 2019, 11:33

Surely the various flags could be switched between defines and variables with further macros. The stb libraries are "big" and still generally applicable without modification. However, small3dlib is pre-1.0 so I won't resort to shrill shrieking just yet. ;)
fluffrabbit
 
Posts: 570
Joined: 11 Apr 2019, 11:17

Re: small3dlib, public domain 3D software rasterizer

Postby drummyfish » 10 Jul 2019, 13:18

Yes, macro switching between macros and variables is an option, I was considering it too, but decided it was getting too complicated and would be an extra thing to add to tests, but actually thinking about it it might be worth reconsidering. I'll put it on the TODO list. Thanks for this feedback.
socialist anarcho-pacifist
Abolish all IP laws. Use CC0.
http://www.tastyfish.cz
User avatar
drummyfish
 
Posts: 226
Joined: 29 Jul 2018, 20:30
Location: Moravia

Re: small3dlib, public domain 3D software rasterizer

Postby fluffrabbit » 10 Jul 2019, 20:15

:D
fluffrabbit
 
Posts: 570
Joined: 11 Apr 2019, 11:17

Re: small3dlib, public domain 3D software rasterizer

Postby smcameron » 10 Jul 2019, 22:41

Very impressive and cool.
smcameron
 
Posts: 313
Joined: 29 Oct 2010, 23:44

Re: small3dlib, public domain 3D software rasterizer

Postby drummyfish » 12 Jul 2019, 20:17

Thanks :)

@fluffrabbit, I did what you suggested. Now if you don't define S3L_RESOLUTION_X and S3L_RESOLUTION_Y, variables S3L_resolutionX and S3L_resolutionY are used instead, which can change resolution dynamically. I am also thinking about adding the possibility for other things like FOV.
socialist anarcho-pacifist
Abolish all IP laws. Use CC0.
http://www.tastyfish.cz
User avatar
drummyfish
 
Posts: 226
Joined: 29 Jul 2018, 20:30
Location: Moravia

Re: small3dlib, public domain 3D software rasterizer

Postby Technopeasant » 13 Jul 2019, 17:49

fluffrabbit {l Wrote}:That said, I learned how to cross-compile for Winblows today. Yay! Here is the city demo.



Very nice. I do wonder though, what is it about software rendering that tends towards that slight warping on the texture mapping? Certainly reminds me of a Playstation 1 game.
User avatar
Technopeasant
 
Posts: 34
Joined: 22 Feb 2017, 03:38

Re: small3dlib, public domain 3D software rasterizer

Postby drummyfish » 13 Jul 2019, 18:50

Technopeasant {l Wrote}:what is it about software rendering that tends towards that slight warping on the texture mapping? Certainly reminds me of a Playstation 1 game.


Here is a great answer:

https://retrocomputing.stackexchange.co ... le-so-much

In short it's usually multiple things like lack of perspective correction or its approximation, lack of proper near-plane culling, inaccuracy of fixed-point math etc. Mostly related to performance. I kind of like that look though :)

BTW small3dlib can be combined with raycastlib to achieve good performance -- you render environment with raycasting, plus small objects as true 3D -- here is a quick gif from Pokitto:

Image
socialist anarcho-pacifist
Abolish all IP laws. Use CC0.
http://www.tastyfish.cz
User avatar
drummyfish
 
Posts: 226
Joined: 29 Jul 2018, 20:30
Location: Moravia

Re: small3dlib, public domain 3D software rasterizer

Postby fluffrabbit » 14 Jul 2019, 01:32

Very nice. I do wonder though, what is it about software rendering that tends towards that slight warping on the texture mapping? Certainly reminds me of a Playstation 1 game.

lerp is less expensive than perspective-correct interpolation. lerp is mathematically trivial and involves only 3 variables, and in a batch it's simple enough to break lerp down into its constituent parts. When you're doing these calculations for every pixel it makes a difference.

What drummyfish said.

you render environment with raycasting, plus small objects as true 3D

But with mouse control the view skew would be different between renderers. small3dlib doesn't allow realtime frustum frombulation and raycastlib doesn't have a correct way to get that extra degree of rotational freedom. So the environment would be Marathon or Duke Nukem 3D while the foreground would be PS1. IDK how noticeable the dissimilar distortion modes would be.

I'm working on giving the city demo dynamic resolution. I do get one warning with Clang:

{l Code}: {l Select All Code}
./small3dlib.h:1289:7: warning: explicitly assigning value of variable of type 'S3L_Unit' (aka 'int') to itself [-Wself-assign]
    x = x;
    ~ ^ ~
fluffrabbit
 
Posts: 570
Joined: 11 Apr 2019, 11:17

Re: small3dlib, public domain 3D software rasterizer

Postby drummyfish » 14 Jul 2019, 02:43

the view skew would be different between renderers. small3dlib doesn't allow realtime frustum frombulation and raycastlib doesn't have a correct way to get that extra degree of rotational freedom.


What the heck is a frombulation? :D

Of course you're right, you become limited by the raycasting so you can't rotate the camera arbitrarily, so it's only valid for some types of games, and mostly interesting only on the really small consoles where that extra saved performance really shows. I can imagine the city demo done this way would be much faster (raycasted buildings and 3D cars).

Though I think camera skewing is compatible with small3dlib -- skewing simply offsets the center of the perspective from the center of the screen, which you can do by having a virtual screen bigger than the actual screen and presenting just a cropped version of the virtual screen -- skewing means just shifting the view crop. But I haven't tried this.

I do get one warning with Clang


Nice, I haven't tried another compiler yet, it's good to test clang as well. I'll try to get rid of that error.
socialist anarcho-pacifist
Abolish all IP laws. Use CC0.
http://www.tastyfish.cz
User avatar
drummyfish
 
Posts: 226
Joined: 29 Jul 2018, 20:30
Location: Moravia

Re: small3dlib, public domain 3D software rasterizer

Postby fluffrabbit » 14 Jul 2019, 04:15

"Frombulation" here means 4x4 matrix affine transforms. Of course, full frombulation isn't necessary for every game. Skewing works to a certain extent, though it's the mismatch between background and foreground that concerns me, unless the foreground view were skewed as well. Though I don't know what would happen to performance if you rendered to a larger viewport than the screen.
fluffrabbit
 
Posts: 570
Joined: 11 Apr 2019, 11:17

Re: small3dlib, public domain 3D software rasterizer

Postby Technopeasant » 15 Jul 2019, 03:45

drummyfish {l Wrote}:In short it's usually multiple things like lack of perspective correction or its approximation, lack of proper near-plane culling, inaccuracy of fixed-point math etc. Mostly related to performance. I kind of like that look though :)


Yeah, it certainly gives a game a recognizable look. ;)
User avatar
Technopeasant
 
Posts: 34
Joined: 22 Feb 2017, 03:38

Who is online

Users browsing this forum: Bing [Bot] and 1 guest