Minimalist base-project for interactive graphical applications (2D/3D)

Recent Activity

PBR: Albedo + Normal Maps

SlimTracing: Goodby Lamber, Bling and Phong... Hello Cook, Torrance, Schlick and Smith! 😇

Pushed to github (excluding the textures as they are too big)

SlimEngine with the software rasterizer (single-threaded, no SIMD), doing high-poly with 2K textures, normal maps and AA:

Major Update to SlimEngine: https://github.com/HardCoreCodin/SlimEngine Quality: Line drawing and blending improved significantly and can now also use MSAA. Performance: Improved somewhat across the board. Robustness: All examples tested in C and C++ on multiple compilers and architectures. API: Simplified and improved argument-order consistency. Correctness: Many subtle bugs and issues fixed, .mesh and .scene files now work on x86 and x64. Presentation: Updated README.md (screenshots and gifs re-captured).

Fixed some alpha-blending issues for Anti-Aliased line drawing. Looks much better now already, but then wanted to implement (software)MSAA on-top... 🙂

Let there be textures! 🙂

JavaScript vs. C (pure software rasterization): ~70 / ~14 = ~5x

Well, not too bad actually (all things considered...)

Camera controls matching 🙂

Live-toggeling between Raytracing vs. Rasterization of the same scene (for verifying correctness of the rasterizer, so switched-off shadows of the raytracer)

Ported my software rasterizer from TypeScript to C (SlimEngine):

BVH debug-mode also works well 🙂

3D Line drawing now account for the depth buffer appropriately, with perspective-corrected depth interpolation, and with antialiasing 🙂

The entire code for this demo 🙂 (and yes, that's a JavaScript pixel shader there, fancy that...)

One liner sliders, camera controls and texture wrapping

Bi-Linear filtering in pure TypeScript (I'm honestly impressed by how well JavaScript performs...)

Let there be lights! 😄

Hosted interactively using GitHub pages: https://hardcorecodin.github.io/RenderEngine3D (double-click then WASD + mouse)

CPU Rasterizer: Pixel Shaders and Vertex attribute interpolation in Clipping and Rasterization (perspective-corrected barycentrics):

Got back to my old software-rasterizer (implemented from scratch in TypeScript - will port to C soon'ish...). Just finished: Culling, clipping, rasterisation (w/ persp. corrected interpolation) and materials with mesh/pixel shaders:

Added the perspective projection visualization to SlimEngine in the examples section: https://github.com/HardCoreCodin/SlimEngine

Line drawing: Anti-aliasing, depth sorting and proper alpha blending:

Fixed a bunch of issues with the area lights (emissive quads) Soft shadows behave much more naturally now. There was a problem of negative light being accumulated that caused overly strong shadows, especially in areas that are lit by other light sources - it all blends much more naturally now.

I'm just having waaay too much fun at this point(s)... 😋

Point lights are now fully integrated in the rendering (as opposed to being a post-pass) so they appear in reflections and refractions (causing some interesting effects especially when inside a glass shape 🙂 ) They also blend nicely volumetrically and obey occlusion.

Point lights now show as glowing spherical volumes (analytically-integrated) They're also now movable and scalable (scale changes intensity)

Area light soft-shadows! 🙂
Not physically accurate at all - just visually plausible. Shadow sharpness reacts to changes in dimensions, orientation and proximity of the emissive quad. Simple ray-tracing approximisations (no path-tracing, no stochatic-sampling/integration, no cone-tracing, no ray-matching, no sdf, no rasterisation, etc.) (pure-software, single-threaded)

Quads can now be emissive, becomming area-lights (no shadows yet)

...and through meshes 🙂

...and chucked onto CUDA 🙂 (same exact code cross-compiled to both CPU and GPU) GPU mode can be toggled on/off dynamicly

Here's the behind-the-scenes magic (BVH with top-down SweepSAH algorithm, and some good depth-first traversal):

"...and now... for a taste of things to come..." (written from-scratch using my SlimEngine - pure-software, no-GPU, single-threaded, no-SIMD) Tomorrow, I'll chuck it onto CUDA - just for kicks 😄

Simplified string/file handeling and scene setup: Scene settings now has a file (string) member. Meshes now load automagically from provided file paths. Memory is now allocated automatically for meshes (by reading their headers before loading). No more need to set-aside additional memory for them 🙂

Few last updates to SlimEngine: Added companion CLI tool for converting .obj to .mesh supporting vertex normals and texture coordinates. Scens can now also be saved to and loaded from .scene files. (Added/updated examples and README)

https://github.com/HardCoreCodin/SlimEngine

SlimEngine is now complete! https://github.com/HardCoreCodin/SlimEngine (no plans to add anything, as I wanna keep it slim/minimalist)

For clarity, here's a summary:

  • Plain C: Compilable in either C or C++
  • Platform-agnostic and very slim (barebone executable is ~17Kb).
  • Self-contained: No dependencies (except for math.h).
  • Single-header or a header-directory ("unity build").
  • Rich README with heavilly documented examples.

Features:

  • 3D viewport with wireframe rendering, rich navigation and a flexible HUD.
  • Scene with cameras, meshes and parametric 3D shapes.
  • Scene selection with rich interactive manipulation.
  • Mesh: Loading from files, instancing and wire-frame drawing.
  • Semi-automatic memory allocation for scene content.
  • Scene and viewport are fully customizable via callbacks.

Based on SlimApp (a base-project for windowe'd apps) featuring:

  • A well-behaved window (resizable, minimizable, etc.).
  • Canvas for drawing numbers, text and basic shapes.
  • Mouse and keyboard input capturing and handling.
  • File reading and writing.
  • Memory arena allocation.

Added support for triangular meshes:

  • Loading from file
  • Wireframe drawing
  • Instancing
  • Transformation manipulation

https://github.com/HardCoreCodin/SlimEngine

Added an example of having multiple cameras and interactively switching between them for the current viewport. Also added camera-shape drawing.

HUD is also fully configurable now: Re-wrote the viewport/HUD example to demonstrate that and updated the readme with code samples from it.

https://github.com/HardCoreCodin/SlimEngine

Added support for scene selection and object manipulation (TRS). Also just moving around stuff along the screen without selecting. Uses ray-casting against bounding boxes (in object-space). Works on all geometry types. (BTW, the executable is 53KB!)

https://github.com/HardCoreCodin/SlimEngine

Working on an off-shoot to my SlimApp called SlimEngine, with a lot more of a base for a hand-made 3D engine (CPU): https://github.com/HardCoreCodin/SlimEngine

Next-up: Scene selection and interactive manipulations (TRS), then mesh loading and rendering 🙂
I already have most of the code in another project, just cleaning stuff up migrating it into this one. Haven't actually re-constructed the single-header-file variant yet, but the directory-variant works

Added basic file reading and writing to SlimApp (using win32 in that platform layer). Also improved the examples and README a bunch: https://github.com/HardCoreCodin/SlimApp

Made this super-minimal (~13Kb) app/platform layer(s) lib: https://github.com/HardCoreCodin/SlimApp No dependencies on anything (not even any standard library stuff). Can compile in either C or C++. CPU-only (no OpenGL). Very beginner friendly, leaner and smaller than other alternatives. Currently only implemented win32 for the platform layer, but app-layer is completely decoupled. (Documented by examples - check'em out to see if you like it)

"Look ma... No red squiggles!" #VSCodeFTW!

Finally got tired enough of re-compiling for light tweaking, so wrote my own light and color controlls 😋 The stored values are in Linear, but the swatches are displayed in sRGB (gamma corrected). I think it makes it more intuitive to explore the gamut this way, as the colors you pick more closely represent how they impact the scene. And the colors in the picker show how there's more gamut space taken by the lower-ends of the values.

And this time it runs just fine on the GPU (using CUDA) at 1080p(!) 😇 (Even though it still uses recursion)

Having fun with specular and reflective shaders again 😇 This time with a scene and acceleration structures (BVH & SSB) with multiple types of polygonal geometry:

...and if triangles are possible on tetrahedra, then quads on cubes are also, because why the not..? 😋

...and now on the GPU (~2K FPS 😆 )

Tetrahedra are now dynamically resizable & rotatable. Acceleration structure mix: Screen-space bounds for culling primary ray intersections BVH for culling shadow ray intersections Ray/tetrahedron intersection checks now default to happen in tangent-space for a ~20% performance boost :)

New and improved way of generating screeen-space bounds for visibility masking! Derived the new approach myself: Gets perfect perspective projection of spheres onto a rectangular 2D bounds, at any FOV, without needing any AABBs, or a projection matrix, and doesn't use any trig.

Much more accurate and very robust to even the most extreme FOV(!) The old way was breaking down completely there (as can be seen around the end)

Red = Old Yellow = New

BVH FTW!!!

(...or NOT in this case...) 😆 SSB = ScreenSpace Bounds check

Turns out that for such a simple scene it's better to just have one node as both root and leaf...😇

Added Cylindical columns (dynamically editable, w/ collision-detection, etc.) Full demo: https://youtu.be/RxBg8BsLVxo

CPU vs. GPU : Can now be toggled dynamically at run-time! 😋 Even while interacting with the camera, togeling debug-render modes, etc. Also switched to showing micro-seconds per-frame in the HUD

Chucked it onto CUDA for some ridiculus FPS... 😋

Got ray/triangle intersection working 😇 Still no acceleration structure, so still slow... Though came up with an in/out-testing approach for tetrahedral-triangles that's ~30% faster (doing it in tangent-space instead of world-space): y > 0 && y < x*SQRT3 && y < (1 - x)*SQRT3 Donno it it's a common thing I've re-invented or not, but works very nicely 😎

Recursive Ray-Tracing is sooooo much fun!😇 (when it works...😋 ) Initial material system:

  • Double-sided, with transparency + transparent shadows + animated UV rotation (just for fun...)
  • Solid glass (finally fixed...)
  • Multi-bounce (Ray-depth = 4)

Double-sided glass (with air inside): Refraction + Reflection with fresnel 😎

Real time Ray-Traced reflections! On a single threaded CPU (without SIMD) Because hey, why the hell not...? 😎

Per-geometry material: Lamber walls and a small ball Phong ball Blinn ball Chrome ball (Blinn-based)

...aaaaand we got shadows 😇 Wasn't even that difficult to add (take that rasterization... 😋 ), and not even that expensive

"I got walls!" 😋 Fps deffinitly taking a dive now at higher resolutions, especially with Blinn Still real-time at lower res. though 😇 Not too much to optimize for simple ray/plane intersections... Onto shadows and reflections next! 😁

...aaaand now some old-school shading, just for fun 😋 (Lamvert, Phong and Blinn, with Ambient + 3-point lighting with quadratic-atteniuation) Really digging this new per. 🤘

Got back to my CPU RayTracer (single-threaded, no SIMD) applying a very simplified "Acceleration Structure", and got a MASSIVE performace boost. Not a BVH or anything (yet), but works very well for spheres 😇 Debug-mode shows how it works: Just doing an orthographic projection of each sphere onto a projection plane set at a distance of the sphere's center (appropriately scaled, accounting for the focal length), then taking a screen-space bounding-rectangle. Additionally, pre-emptively filtering-out spheres that can be easilly rejected as being out of view. The HUD show's how many "active" spheres are being considered, as well as what overall percentage of the screen's pixels get a ray traced for them 😁 With these kind of FPSes, gonna start doing some shading now.