3D software rendering in Rust
This is a project I started working on literally yesterday. This aims to be a fully fledged 3D renderer powered entirely by the CPU.
This basically means you can run this on a hardware that doesn't have GPU, or on a PC that lacks drivers.
Currently it can only draw 2D triangles, but eventually this would take shape as a 3D renderer, complete with a shader system.
166 Replies
what's the second image for?
That was a polygon gap test that got borked
My triangles weren't rendering there because the scanlines' begin and end X coords were swapped around
that is fixed now
polygon?? why not beginning with a cube?
I mean maybe you already have the cube...
Polygons are made out of triangles
that's how GPUs render them
So for now I am focusing on 2D triangle rasterization first, then I'll do 3D projection, texture mapping and everything
yes
everything 3d is triangles
alright
Finally, affine mapping
I'm gonna do 3D stuff later
like I have no idea how these graphics APIs even workI've done quite a lot of work with OpenGL and Vulkan. But now for anything graphic and game based I use Raylib Graphic APIs are a doozy though, what are you currently using for rendering? I can't imagine this is very cross platform Looks very nice for something done within a day I'm impressed!
Very Nice
Is it an image or a lot of triangles?
SDL2
The triangles are software rendered entirely
Well I was following a tutorial though so it's not really that impressive
The only thing I personally did is a bit of refactoring
2 triangles making up a textured rectangle, you can see the effects of affine mapping here
ok that's cool!
@polyzium does your engine have a name already?
Yeah
Necromancy Engine
lol I didn't think about that, this is kind of fancy
Do you have an explication?
Explanation you mean?
I mean is there a reason?
Why this name
Like I said this all started from a Minecraft mod
sorry that wasn't very clear ^^'
yep
and his mod's name has "Necro" in it
and necromancy means communicating with the dead
Though the project kinda carries this name because this field of programming (software rendering and overall engine from scratch) is dead
Like it's some sort of black magic thing
rasterizing triangles manually
yeah I see, that's a nice name then ^^
I am doing perspective projection now, should be finished soon
For mine (in a near future), I think i'll call it "Dust Engine", firstly inspired from my pseudo and my name, and secondly as you say, all of that is quite dusty
and idk I find that a bit fun
oh really? You don't seem to struggle that much, do you?
I am following a C++ tutorial on software 3D rendering
making a 3d engin from "scratch" is not something said easy
but I am translating the code into Rust and doing some code readability refactoring while I am at it
3D graphics is honestly one big pile of maths
what is it? It could help me too
It consists of 4 videos
do you want me to send them all?
Idk, if it's yt videos you can send the link
I mean as you want
This is the first one https://www.youtube.com/watch?v=PahbNFypubE
Bisqwit
YouTube
Texture Mapping & Polygon Rasterizing Tutorial (1/2) [C++20]
Textured polygons are the foundation of nearly all 3D games in existence. Used before even 3D-capable GPUs were a thing, they were rendered using nothing but software. How was that achieved? Let’s explore an easy and intuitive method. We create an extensible 3D polygon rasterizer using nothing but standard C++20 (and libSDL for 2D graphics).
Be...
alright, i'll find the rest thank you!
they should pop up in suggested on the right
also, for your MC project, what do you want to do?
Like, making entire minecraft in today's version is without a doubt a huge and tough work
I am aware, but this is not up to me
This is up to a friend of mine who wants to make such a game
But most likely it is NOT going to be minecraft from scratch
As for the MC mod itself, his mod is a part of a WIP server network that I am a part of
They could use some help, so if you are interested, DM me and I'll explain everything
ok!
so do you have a project for your Engine?
Define "project"?
Like a file structure or theoretical project?
Something you want to do using your engine, so basically a game or an application using it
My plan is to make an entire scene
like a game level thing
For now I am gonna test my perspective projection with a simple cuboid
as shown in part 2: https://www.youtube.com/watch?v=hxOw_p0kLfI
Bisqwit
YouTube
Texture Mapping & Polygon Rasterizing Tutorial (2/2) [C++20]
Textured polygons are the foundation of nearly all 3D games in existence. Used before even 3D-capable GPUs were a thing, they were rendered using nothing but software. How was that achieved? Let’s explore an easy and intuitive method. We create an extensible 3D polygon rasterizer using nothing but standard C++20 (and libSDL for 2D graphics).
Be...
nice
Btw you have to see something so cool:
jdh
YouTube
Why I use Wave Function Collapse to create levels for my game
this was so much work i'm about to (wave function) collapse
sorry I used the terms "element", "cell", and "pixel" interchangeably :c
they all mean the same thing!
SEE THE CODE (utilities, etc. coming soon!)
https://gist.github.com/jdah/ad997b858513a278426f8d91317115b9
Oskar Stålberg's visualization tool:
https://oskarstalberg.com/game/wave/wa...
that's really cool imo
and I'll add that to my engine
Yikes... I've heard that WFC is slow as a snail
I mean that's the plan, tehcnically I can't say if I will succeed...
idk, I guess it depends, a game often cited is Bad North; I have it and It runs very well on my portable potato!
(very nice game btw)
Hm
not sure if RTS is my thing
Oh look, Steam Deck Verified
could pick it up
you have a steam deck?
Yeah, OLED 1TB
with that anti glare glass
-5000 $
XD
no apparently it's 570 €
I thought it would be much more
It's less than 1k USD/EUR
Well you know what costs more?
ROG Ally, Legion Go, etc
These things have better hardware, but worse software and a Windows license lmfao
Steam Deck is the ideal balance between hardware and software
yeah
but why not playing on pc?
I do mostly coding on PC now
and only thing I play on PC is Minecraft
or console
the Steam Deck allows me to kill some time and play on the go/vacation, especially after working hours I can just fall on my bed and play til midnight
It completely changed the way I play games
oh ok that's fair
Because yk I am not feeling like playing on PC after working hours, especially considering that I sit at a PC at my work all day
(I am employed as a webdev)
Anyway back to perspective projection
xd yeah
Not at all! Huge communities of people still do this.
Let's be honest nobody ships a software renderer and an inhouse engine these days anymore
Sure maybe not in the modern games you see on steam but there is still huge communities of people that still do this kind of stuff.
Me included
Then I wonder what for
Fun
...I meant in practice
Holy fuck quaternions are hard to deal with
what are you even doing with that 💀
I didn't know there is something after complex numbers honestly
The tutorial for some reason uses quaternions for rotations
and then it uses these quaternions to calculate the projection matrix
This shit is hard to understand ngl
no wayyyyyy
I don't even know what it does, i'll search that
I think it's mostly related to projection matrix anyway
don't tell me they used quaternions in the 90'
Quaternions is just a much harder way to represent rotation\
and it's 4 dimensional for some reason
You got Euler angles and quaternions
that's a f*cking joke
😂
I don't even know how it's possible
sounds fun to do lmfao
I am 100% sure quaternions relate to the projection matrix
Um... well...
Black screen at the end = crash
Better now, but still crashy
Trying to implement Z buffer stuff
Hm I think I got that fixed
I figured I'd go back to square one
I am having so much trouble doing perspective correction
Finally, perspective correct textures
Dithering
OK now the only thing left is clipping
But clipping is for some reason hard asf
It isn't as trivial as it seems
which is very very sad
@polyziumThe rasterization makes everything pixelized right?
is it possible to avoid that? Like if we add some antialiasing, will it make it look smoother?
also I recommend this website which explain all the steps to make software rendering. I find it very well explained:
https://medium.com/@aminere/software-rendering-from-scratch-f60127a7cd58
yeah btw could you tell me what's you're file structure? I'm a bit lost on how I should do that, i'm not used to it and it looks different than a standard project
Yeah if you're doing nearest neighbour texturing
Here I am doing dithering though to hide the large pixels
I could do bilinear filtering, but A it does not fit the retro aesthetic I am going for and B all software renderers I've seen they all use either nearest neighbour (Doom, Quake) or dithering (Unreal, Deus Ex)
Tbh not even I know how to structure this kind of project properly
In the coming days I'll be refactoring this proper
But for now I put all the stuff in their respective files
Alright thanks!
That may help you:
https://github.com/SFML/SFML/wiki/Tutorial%3A-Basic-Game-Engine
GitHub
Tutorial: Basic Game Engine
Simple and Fast Multimedia Library. Contribute to SFML/SFML development by creating an account on GitHub.
@earth's goose This is what I have now if you are curious
what do you have on your main?
also I think it could be good to make subdirectories like:
On main I have the actual graphics plotting and SDL2 initialization + camera control stuff
But it is wise to put everything under one
Rasterizer
class or something like that
which is what I am going to do later after I finish dealing with clipping
this is annoying nglYeah so here it’s more like a standard project, like a game or something you’d do rather than an actual engine
I know
This project is currently at a proof of concept stage
I need to do refactoring so badly
But I am stuck with clipping
Alright good luck then
There is a vscode extension called Draw.io, which allows you to make sketchs and mind maps. I started to make a map representing the engine, so if you want we can make it together to help each other, or at least me...
Lmao you're just in time
here's what I already did
I just came back from work
lol xd
perfect timing
and on my free work time I finally implemented clipping
oh nice!
I probably need to optimize it further
Also I need to figure out wtf do I need to do to make it "stick" to the camera
because my rotation is just quaternions, this is not good
I made the basic directories I think there should be, and for the graphics I put some ideas and system I have to implement. For now I don't know what I should put in same file or just just if I should make everything very modulable and separated
Here's the clipping video
why does it disapear?
there's a wall simulated?
Because I cba to figure out how to stick it to the camera
I need a look vector and I have no idea how to make one from a quaternion
oh that' why, ok
But basically
once it sticks to the camera
this won't happen:
I can't help you with that, I just learn it existed because of you xd*
oh wow looks like you entered the matrix
The transformation matrix yeah lmao
Because I want to have a clear idea of the global structure and start making the graphics once I have a functional engine
Clipping, the final frontier
Oh Nice! It’s seems totally working now
As a bonus, here is the renderer in 720p
Really nice!
Isn’t it a bit laggy tho?
Though in 720p it is quite slow
Yeah
with even 4 triangles this thing reaches like 15fps... maybe less
I must investigate that ngl
Is that a normal behaviour?
Well for a POC yes
this engine just seems to be unoptimized
Lemme try affine mapping and see if I get perf boost from that
Yeah probably
Just tried, it's not any better
need a profiler
Or actually maybe parallelize the entire thing?
I just realized Rust compiles with no optimizations in dev mode. Here's the release build with -O3
Much better!
If you don't put any timing stuff in, it runs plenty fast
I didn't implement any type of ΔT stuff in this
so if I remove the 60fps limit the camera moves super fast
that's what I expected from 2 panels, that shouldn't be that greedy
yeah I don't think it's useful for these things
Also
I was curious how would it perform at 1080p
TLDR it doesn't, crashes due to stack overflow
It's using 136 megabytes of memory though lmao
No sorry 98 megs actually
136 megs is VIRT memory according to my htop output
Release build takes about 40%-45% CPU
I wonder how fast could this be if I parallelize this
wdym about parallelization?
Make this run on all of your CPU's threads
ow ok
Currently this thing is singlethreaded
this could be very efficient then
Do you have texturing yet?
No, well tell me if I'm wrong but you only have colored triangles there. So I meant: can you apply a picture on whatever surface you have?
You can
But here I am generating a texture
What you are seeing is a custom version of the Munching Squares texture
The original looks like this
Yes ok, I see
so are you planning on adding this?
Planning adding on what?
Texturing?
It is already done
oh, ok
that being said, once you have I guess you can just upload a picture and set it to the right position and the rest is done?
Well yea
but I have to implement the code for that
Currently my texture is 256x256
I have no code that loads from a PNG or something, the texture is generated straight into the bitmap
alright!
Here's a very crude conversion to Shadertoy compatible GLSL
this is the code I use to generate the munching squares texture
ok thank you!
I wonder how to deal with hypercomplex numbers in programming, i'll see that
after
I did some refactoring yesterday
I realized that my projection method should take a projection matrix instead of camera position
but for some reason it just screws up my rendering entirely
Well, I think I am gonna stop right here
That was a fun project while it lasted, but unfortunately I am not able to parallelize the renderer
I am tempted to rewrite everything to OpenGL now
would it actually change something or make things work?
It would use the GPU
and thus make rendering faster
Because I cba to parallelize the software renderer properly
I only did this as a stepping stone to 3D graphics programming
Oh, that's sad...
At least it's still not a waste
every unfinished project is a step up
so maybe I should do try to make it with OpenGL from beginning
If you don't know how quaternions and matrices work it would be hard for you
But of course this is only part of the whole ordeal
Anyway do you guys need the source code? in Rust
I know the basics of matrices, but I think I can make it with some digging
I wouldn't say no!
Also if you want, you could help me on a game engine system thing i'm wondering
#💻┃cpp
I think you could understand well chat I mean here since it's the same project
Here you go
thx
wop nevermind: as SFML uses OpenGL, there is GPU management
Btw I left some junk code in there because I released the thing as-is
didn't bother getting prepared
But it has a very basic OBJ parser
Alright
Coming back to this project months later. I wanna see if rewriting it to use fixed point numbers would make it faster
Ping?
oh I thought my internet was dead
I looked at my perf data
Barycentric coords my beloved
I think I have to do it the old scanline way again because doing this barycentric division stuff is yikes for performance
Especially per pixel
I need to minimize divisions as much as I possibly can
For the past several days I've been doing optimisations on the renderer. I got rid of allocations in several places as well as iterations and divisions (some of them only need to be calculated once per triangle). With the test scene I have currently I got 50 fps. Will try to push the thing even further.
I am hesitant on doing the fixed point rendering thing yet
Fixed the rounding errors (which cause gaps between polygons). I am back at 36 fps.
God damn it
At this point I am really considering switching to fixed point
@polyzium what are you doing exactly ? Where do you start from ?
I mean do you make lines and triangles and rasterisation all that stuff? Or do you have access to triangles with whatever lib you are using, and manipulating coordinates to make 3D stuff
I made a core rasterizer that draws triangles
2d triangles
Then I use a math library like glm to project 3d triangles into 2d
and then I draw the projected triangle
alright
and how many things are you drawing to get low fps?
Idr
5000 triangles?
lemme count
oh
Could you show a screen shot?
OK it is far above that
78k triangles
it's a map
The textures are wobbly because it's using affine mapping, I temporarily turned off perspective correction
ok
and the white areas is due to the bugged texture mapping
You're making the textures yourself using triangle ritght?
like you told me
Not sure what you mean
the texture is procedurally generated
at least here
yes
Then it may be less consuming to just use pictures as textures
I don't know but that will reduce the amount of triangles for sure and maybe improve fps
No
The texture is not generated in real time
it's generated beforehand
and is a bitmap
so loading from a picture would not make it any faster
How would using a different texture reduce the amount of triangles?
That... doesn't make sense
well
I thought you were drawing triangles to make the squares
No that's not how it works
the squares are a bitmap
which is rendered on top of the triangles