5 ms·
Show HN: Consol3 – A 3D engine for the terminal that executes on the CPU
Hi all
This has been my hobby project for quite a few years now
It started as a small engine to serve as a sandbox to try out new 3d graphics ideas
After adding many features through out the years and re-writing the entire engine a few times, this is the latest state
It currently supports loading models with animations, textures, lights, shadow maps, normal maps, and some other goodies
I've also recently added voxel raymarching as an alternative renderer, along with a fun physics simulation :)
- Guestmodinfo 3y agoWow. I love the concept so much
- jareklupinski 3y ago"I don't even see the code anymore. All I see is: noob... aimbot... afk..."
- mysterydip 3y agoReally nice, thanks for sharing! I like the pseudo-shader implementation. What kind of framerate were you seeing and how many triangles could you push?
- victormeriqui 3y agoThanks! Depends on the scene and the CPU of course, typically I get between 20-60 FPS on a small scene with a floor and a few models, but features like shadow maps or normal maps bring the performance down a lot though The scenes themselves don't have a lot of triangles, for the first scene with marvin and the car in the rasterization video there's 7427 triangles There is no parallelization whatsoever in the engine at the moment, so I feel like it could get much faster if I multi thread it, or use SIMD vectors Another aspect that influences the performance a lot is the output mode being used, for example the TextOnly mode is a lot faster than others since it uses no colors at all, the full RGB color mode has to have an escape sequence prepended to each character "pixel" so its quite slow It also depends on the frame disposition itself, the Windows console does some attribute caching when its rendering continuous character rows, so if a frame has a lot of different colors horizontally, it will be slightly slower than if it didn't
- paramu 3y agoRummy wealth
- raytopia 3y agoThis is so unbelievably awesome! Projects like these are why I browse HN
- raytopia 3y agoAnd it has shaders. Can't get any cooler
- lukan 3y agoWhat am I missing here? Why is it cool to not use the fast GPU and instead do everything slow in a software renderer on the CPU? It surely is interesting to do it for the sake of it, but are there any practical use cases?
- Blahah 3y agoRunning it remotely on a cloud instance? Or on any machine without a GPU.
- lukan 3y agoWell yeah, I remember those software renderer options from old computer games. I might not have known the difference between GPU and CPU back then, but I learned very quickly that Software renderer means slow and makes your Computer very hot. Not cool (literally) I thought back then.
- teaearlgraycold 3y agoIt's much easier to debug. And CPUs are actually fast enough to do real-time rendering of simple scenes. Because writing for the CPU is so different, and so much easier than writing for the GPU, a pure software stack allows you to explore new ideas.
- victormeriqui 3y agoExploring new ideas without worrying about GPUs was exactly one of my motivations :)
- jpc0 3y agoI would strongly encourage you to reduce your use of std::shared_ptr in your code. There is one instance where I saw you take a shared_ptr and then proceed to move from it. That could literally have been a unique_ptr and if you are making an assumption that that shared_ptr is still valid in another part of the codebase you at best now have UB but it is almost certainly a bug. Just replace shared_ptr with unique_ptr, the advantage of managed languages is that you are in control of the memory, to then proceed to just use ref counting means you may as well have written the code in Java / C# since you incur all the same overhead of atomic references and don't get the advantages of a sophisticated GC. unique_ptr can also trivially be upgraded to shared if you actually do need ref counting.
- mandarax8 3y agoAgree on the over-use of shared_ptr (there is _a lot_ of copying shared ptrs going on here). But moving from the shared_ptr like this is quite idiomatic no? void Consol3Engine::RegisterFrameDrawer(std::shared_ptr<IFrameDrawer> frame_drawer) { frame_drawers.push_back(std::move(frame_drawer)); ... }
- jpc0 3y agoIts idiomatic sure but specifically with shared pointer a lot of time people are using shared pointers because they don't want to think about ownership, this turns out not to be the case here but think about it, the function is taking shared_ptr by value which increases the ref count when looked at from the signature. In the calling code you then dereference that shared_ptr because it should still be valid but it isn't because it is now a moved from value. I would in this specific case just replace shared_ptr with unique_ptr in the entire call stack up until here. If there isn't an implicit conversation here, put the conversation to shared in this function. That makes it explicit ownership of the pointer is being moved into this function, it wasn't clear at all that that is happening with the shared_ptr. EDIT: You have to think of shared_ptr as global, if you moved from it ownership was changed but there is no way for everyone else holding a reference to thay shared pointer to know that.
- victormeriqui 3y ago
- tetris11 3y agoThis is definitely one of those "but, why?" projects that has me grinning from ear to ear, and makes HN the interesting place it is when it's not being drowned in AI or Fintech
- moffkalast 3y agoI wonder if it works on a headless server plugged into a display where you only get a TTY. If so it would actually be useful as a kiosk environment on machines without a GPU.
- jan_Sate 3y agoImpressive. Not sure on what it could be used for but it does look very cool. Good job!
- ametrau 3y agoThanks for posting this. This is probably the coolest project I’ve seen all year.
- neomantra 3y agoThis is really fun, thank you for sharing it! Recently, I've personally and professionally been going between TUI and deep 3D (mesh shading FTW) so this was fun to see. Your work is inspiring me to think about how to apply those principles to my own work. There have been other ascii renders but I've not seen anything quite like Consol3. I made a half-baked PR with some initial Mac support [1]. I don't have time this weekend but I'll pull on it later -- or maybe somebody here with more low-level Mac skills than me can take a look? [1] https://github.com/Victormeriqui/Consol3/pull/37 https://github.com/Victormeriqui/Consol3/pull/37
- victormeriqui 3y agoThanks! I really appreciate the PR
- Narishma 3y agoWhat's the advantage of re-implementing the GPU programming model (shaders) instead of just writing regular C++ code? I would think that would just introduce overhead for no reason.
- victormeriqui 3y agoThere's no performance reason really, the motivation behind it was flexibility for trying out new ideas and to decouple logic from the rasterizer
- ginko 3y agoShaders were originally a production rendering concept introduced by Pixar's RenderMan in the 80s. It only became a thing in GPUs much later. Programmable shading is really more of a design pattern in graphics renderers.
- westurner 3y agoTextual is not 3d too, but is also great for TUIs. Textualize/Frogmouth has a TUI tree control: https://github.com/Textualize/frogmouth https://github.com/Textualize/frogmouth FWICS browsh supports WebGL over SSH/MoSH https://www.brow.sh/docs/introduction/ https://www.brow.sh/docs/introduction/ : > The terminal client updates and renders in realtime so that, for instance, you can watch videos. It uses the UTF-8 half-block trick () to get 2 colours from every character cell, thus simulating basic graphics. https://github.com/fathyb/carbonyl https://github.com/fathyb/carbonyl : > Carbonyl originally started as html2svg and is now the runtime behind it. Always wondered how brew.sh added the brew sprite there; that's real nice. TIL that e.g. Kitty term can basically framebuffer modified Chrome? https://github.com/chase/awrit https://github.com/chase/awrit : > Yep, actual Chromium being rendered in your favorite terminal that supports the Kitty terminal graphics protocol. FWIW Cloudflare has clientless Remote Browser Isolation that also splits the browser at the rendering engine. A TUI Manim renderer would be neat. Re: Teaching math with Manim and interactive 3d: https://github.com/bernhard-42/jupyter-cadquery/issues/99 https://github.com/bernhard-42/jupyter-cadquery/issues/99 What would you add to make it easier to teach with this entirely CPU + software rendering codebase? What prompts for learning would you suggest? - Pixar in a Box, Wikipedia history of CG industry,: https://westurner.github.io/hnlog/#comment-36265807 https://westurner.github.io/hnlog/#comment-36265807 - "Rotate a wireframe cube or the camera perspective with just 2d pixels to paint to; And then rotate the cube about a point other than the origin, and then move the camera while the cube is rotating" - OTOH, ManimML, Yellowbrick, and the ThreeJS Wave/Particle simulator might be neat with a slow terminal framebuffer too
- MrYellowP 3y agoThis is neat. Not new, but definitely neat. Well done! We need more textmode out there!
- johnklos 3y agomake [ 1%] Building CXX object CMakeFiles/Consol3_raster.dir/src/Consol3.cpp.o In file included from /home/john/Consol3/src/Consol3.cpp:23: /home/john/Consol3/src/Engine/Input/LinuxInputManager.hpp:8:10: fatal error: linux/input.h: No such file or directory 8 | #include <linux/input.h> | ^~~~~~~~~~~~~~~ compilation terminated. Oh, well ;)
- victormeriqui 3y agoHi, if you want help getting it running please open an issue on github with some info like your OS I've compiled it in Windows and Linux and didn't have any issues
- mellutussa 3y agoI think listing required packages, even just for the most common linux distro would be a good start. In this case he's probably missing linux-headers for his kernel version? If people download your project and the build fails, it's very, very, very likely that they'll give up right away. You have to be very, very interested in a project to be bothered to research and install undocumented dependencies and their versions and then fight the build.