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.
No description
No description
166 Replies
Enceladus
Enceladus7mo ago
what's the second image for?
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
polygon?? why not beginning with a cube? I mean maybe you already have the cube...
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
yes everything 3d is triangles alright
polyzium
polyziumOP7mo ago
Finally, affine mapping
polyzium
polyziumOP7mo ago
I'm gonna do 3D stuff later
Dumb Bird
Dumb Bird7mo ago
like I have no idea how these graphics APIs even work
I'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!
Nick_Z
Nick_Z7mo ago
Very Nice
Enceladus
Enceladus7mo ago
Is it an image or a lot of triangles?
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
ok that's cool! @polyzium does your engine have a name already?
polyzium
polyziumOP7mo ago
Yeah Necromancy Engine
Enceladus
Enceladus7mo ago
lol I didn't think about that, this is kind of fancy Do you have an explication?
polyzium
polyziumOP7mo ago
Explanation you mean?
Enceladus
Enceladus7mo ago
I mean is there a reason? Why this name
polyzium
polyziumOP7mo ago
Like I said this all started from a Minecraft mod
Enceladus
Enceladus7mo ago
sorry that wasn't very clear ^^' yep
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
yeah I see, that's a nice name then ^^
polyzium
polyziumOP7mo ago
I am doing perspective projection now, should be finished soon
Enceladus
Enceladus7mo ago
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?
polyzium
polyziumOP7mo ago
I am following a C++ tutorial on software 3D rendering
Enceladus
Enceladus7mo ago
making a 3d engin from "scratch" is not something said easy
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
what is it? It could help me too
polyzium
polyziumOP7mo ago
It consists of 4 videos do you want me to send them all?
Enceladus
Enceladus7mo ago
Idk, if it's yt videos you can send the link I mean as you want
polyzium
polyziumOP7mo ago
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...
Enceladus
Enceladus7mo ago
alright, i'll find the rest thank you!
polyzium
polyziumOP7mo ago
they should pop up in suggested on the right
Enceladus
Enceladus7mo ago
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
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
ok! so do you have a project for your Engine?
polyzium
polyziumOP7mo ago
Define "project"? Like a file structure or theoretical project?
Enceladus
Enceladus7mo ago
Something you want to do using your engine, so basically a game or an application using it
polyzium
polyziumOP7mo ago
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
polyzium
polyziumOP7mo ago
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...
Enceladus
Enceladus7mo ago
nice Btw you have to see something so cool:
Enceladus
Enceladus7mo ago
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...
Enceladus
Enceladus7mo ago
that's really cool imo and I'll add that to my engine
polyzium
polyziumOP7mo ago
Yikes... I've heard that WFC is slow as a snail
Enceladus
Enceladus7mo ago
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)
polyzium
polyziumOP7mo ago
Hm not sure if RTS is my thing Oh look, Steam Deck Verified could pick it up
Enceladus
Enceladus7mo ago
you have a steam deck?
polyzium
polyziumOP7mo ago
Yeah, OLED 1TB with that anti glare glass
Enceladus
Enceladus7mo ago
-5000 $ XD no apparently it's 570 € I thought it would be much more
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
yeah but why not playing on pc?
polyzium
polyziumOP7mo ago
I do mostly coding on PC now and only thing I play on PC is Minecraft
Enceladus
Enceladus7mo ago
or console
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
oh ok that's fair
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
xd yeah
Dumb Bird
Dumb Bird7mo ago
Not at all! Huge communities of people still do this.
polyzium
polyziumOP7mo ago
Let's be honest nobody ships a software renderer and an inhouse engine these days anymore
Dumb Bird
Dumb Bird7mo ago
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
polyzium
polyziumOP7mo ago
Then I wonder what for
Dumb Bird
Dumb Bird7mo ago
Fun
polyzium
polyziumOP7mo ago
...I meant in practice Holy fuck quaternions are hard to deal with
Enceladus
Enceladus7mo ago
what are you even doing with that 💀 I didn't know there is something after complex numbers honestly
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
no wayyyyyy I don't even know what it does, i'll search that
polyzium
polyziumOP7mo ago
I think it's mostly related to projection matrix anyway
Enceladus
Enceladus7mo ago
don't tell me they used quaternions in the 90'
polyzium
polyziumOP7mo ago
Quaternions is just a much harder way to represent rotation\ and it's 4 dimensional for some reason You got Euler angles and quaternions
Enceladus
Enceladus7mo ago
that's a f*cking joke 😂 I don't even know how it's possible sounds fun to do lmfao
polyzium
polyziumOP7mo ago
I am 100% sure quaternions relate to the projection matrix
polyzium
polyziumOP7mo ago
Um... well...
polyzium
polyziumOP7mo ago
Black screen at the end = crash
polyzium
polyziumOP7mo ago
Better now, but still crashy
polyzium
polyziumOP7mo ago
Trying to implement Z buffer stuff
polyzium
polyziumOP7mo ago
Hm I think I got that fixed
polyzium
polyziumOP7mo ago
I figured I'd go back to square one I am having so much trouble doing perspective correction
polyzium
polyziumOP7mo ago
Finally, perspective correct textures
polyzium
polyziumOP7mo ago
Dithering
No description
No description
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
@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
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
Alright thanks!
Enceladus
Enceladus7mo ago
GitHub
Tutorial: Basic Game Engine
Simple and Fast Multimedia Library. Contribute to SFML/SFML development by creating an account on GitHub.
polyzium
polyziumOP7mo ago
@earth's goose This is what I have now if you are curious
No description
Enceladus
Enceladus7mo ago
what do you have on your main? also I think it could be good to make subdirectories like:
engine
graphics
sound
...
engine
graphics
sound
...
polyzium
polyziumOP7mo ago
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 ngl
Enceladus
Enceladus7mo ago
Yeah so here it’s more like a standard project, like a game or something you’d do rather than an actual engine
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
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...
polyzium
polyziumOP7mo ago
Lmao you're just in time
Enceladus
Enceladus7mo ago
here's what I already did
polyzium
polyziumOP7mo ago
I just came back from work
Enceladus
Enceladus7mo ago
lol xd perfect timing
polyzium
polyziumOP7mo ago
and on my free work time I finally implemented clipping
Enceladus
Enceladus7mo ago
oh nice!
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
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
polyzium
polyziumOP7mo ago
Here's the clipping video
Enceladus
Enceladus7mo ago
why does it disapear? there's a wall simulated?
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
oh that' why, ok
polyzium
polyziumOP7mo ago
But basically once it sticks to the camera
polyzium
polyziumOP7mo ago
this won't happen:
Enceladus
Enceladus7mo ago
I can't help you with that, I just learn it existed because of you xd* oh wow looks like you entered the matrix
polyzium
polyziumOP7mo ago
The transformation matrix yeah lmao
Enceladus
Enceladus7mo ago
Because I want to have a clear idea of the global structure and start making the graphics once I have a functional engine
polyzium
polyziumOP7mo ago
Clipping, the final frontier
Enceladus
Enceladus7mo ago
Oh Nice! It’s seems totally working now
polyzium
polyziumOP7mo ago
As a bonus, here is the renderer in 720p
Enceladus
Enceladus7mo ago
Really nice! Isn’t it a bit laggy tho?
polyzium
polyziumOP7mo ago
Though in 720p it is quite slow
Enceladus
Enceladus7mo ago
Yeah
polyzium
polyziumOP7mo ago
with even 4 triangles this thing reaches like 15fps... maybe less I must investigate that ngl
Enceladus
Enceladus7mo ago
Is that a normal behaviour?
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
Yeah probably
polyzium
polyziumOP7mo ago
Just tried, it's not any better need a profiler Or actually maybe parallelize the entire thing?
polyzium
polyziumOP7mo ago
I just realized Rust compiles with no optimizations in dev mode. Here's the release build with -O3
Enceladus
Enceladus7mo ago
Much better!
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
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
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
wdym about parallelization?
polyzium
polyziumOP7mo ago
Make this run on all of your CPU's threads
Enceladus
Enceladus7mo ago
ow ok
polyzium
polyziumOP7mo ago
Currently this thing is singlethreaded
Enceladus
Enceladus7mo ago
this could be very efficient then Do you have texturing yet?
polyzium
polyziumOP7mo ago
As you can see, no Dammit of course I do, since the affine mapping days Why are you even asking? You can clearly see dithering of the texture in my later videos
Enceladus
Enceladus7mo ago
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?
polyzium
polyziumOP7mo ago
You can But here I am generating a texture What you are seeing is a custom version of the Munching Squares texture
polyzium
polyziumOP7mo ago
The original looks like this
No description
Enceladus
Enceladus7mo ago
Yes ok, I see so are you planning on adding this?
polyzium
polyziumOP7mo ago
Planning adding on what? Texturing? It is already done
Enceladus
Enceladus7mo ago
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?
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
alright!
polyzium
polyziumOP7mo ago
Here's a very crude conversion to Shadertoy compatible GLSL
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec2 iResolution = vec2(800.0, 450.0); // Set this to your desired resolution
vec2 uv = fragCoord / iResolution;
int x = int(fragCoord.x);
int y = int(fragCoord.y);

int TEXTURE_W = int(iResolution.x);
int TEXTURE_H = int(iResolution.y);

int l = 0x1FF >> min(min(min(min(x, y), TEXTURE_W - 1 - x), TEXTURE_H - 1 - y), 31);

float fx = float(x);
float fy = float(y);
float fw = float(TEXTURE_W);
float fh = float(TEXTURE_H);

float hypot = pow(length(vec2(fx / (fw / 2.0) - 1.0, fy / (fh / 2.0) - 1.0) * 4.0), 2.0);
int d = int(min(50.0, max(0.0, 255.0 - 50.0 * hypot)));

int r = (~x & ~y) & 255;
int g = (x & ~y) & 255;
int b = (~x & y) & 255;

float red = float(min(max(r - d, l), 255)) / 255.0;
float green = float(min(max(g - d, l), 255)) / 255.0;
float blue = float(min(max(b - d, l), 255)) / 255.0;

fragColor = vec4(red, green, blue, 1.0);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec2 iResolution = vec2(800.0, 450.0); // Set this to your desired resolution
vec2 uv = fragCoord / iResolution;
int x = int(fragCoord.x);
int y = int(fragCoord.y);

int TEXTURE_W = int(iResolution.x);
int TEXTURE_H = int(iResolution.y);

int l = 0x1FF >> min(min(min(min(x, y), TEXTURE_W - 1 - x), TEXTURE_H - 1 - y), 31);

float fx = float(x);
float fy = float(y);
float fw = float(TEXTURE_W);
float fh = float(TEXTURE_H);

float hypot = pow(length(vec2(fx / (fw / 2.0) - 1.0, fy / (fh / 2.0) - 1.0) * 4.0), 2.0);
int d = int(min(50.0, max(0.0, 255.0 - 50.0 * hypot)));

int r = (~x & ~y) & 255;
int g = (x & ~y) & 255;
int b = (~x & y) & 255;

float red = float(min(max(r - d, l), 255)) / 255.0;
float green = float(min(max(g - d, l), 255)) / 255.0;
float blue = float(min(max(b - d, l), 255)) / 255.0;

fragColor = vec4(red, green, blue, 1.0);
}
this is the code I use to generate the munching squares texture
Enceladus
Enceladus7mo ago
ok thank you! I wonder how to deal with hypercomplex numbers in programming, i'll see that after
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
would it actually change something or make things work?
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
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
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
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
polyzium
polyziumOP7mo ago
Enceladus
Enceladus7mo ago
thx wop nevermind: as SFML uses OpenGL, there is GPU management
polyzium
polyziumOP7mo ago
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
Enceladus
Enceladus7mo ago
Alright
polyzium
polyziumOP3mo ago
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
polyzium
polyziumOP3mo ago
I looked at my perf data
No description
polyzium
polyziumOP3mo ago
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
Enceladus
Enceladus2mo ago
@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
polyzium
polyziumOP2mo ago
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
Enceladus
Enceladus2mo ago
alright and how many things are you drawing to get low fps?
polyzium
polyziumOP2mo ago
Idr 5000 triangles? lemme count
Enceladus
Enceladus2mo ago
oh Could you show a screen shot?
polyzium
polyziumOP2mo ago
OK it is far above that 78k triangles it's a map
polyzium
polyziumOP2mo ago
No description
polyzium
polyziumOP2mo ago
The textures are wobbly because it's using affine mapping, I temporarily turned off perspective correction
Enceladus
Enceladus2mo ago
ok
polyzium
polyziumOP2mo ago
and the white areas is due to the bugged texture mapping
Enceladus
Enceladus2mo ago
You're making the textures yourself using triangle ritght? like you told me
polyzium
polyziumOP2mo ago
Not sure what you mean the texture is procedurally generated at least here
Enceladus
Enceladus2mo ago
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
polyzium
polyziumOP2mo ago
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
Enceladus
Enceladus2mo ago
well I thought you were drawing triangles to make the squares
polyzium
polyziumOP2mo ago
No that's not how it works the squares are a bitmap which is rendered on top of the triangles
Want results from more Discord servers?
Add your server