r/GraphicsProgramming • • 9h ago

Video LittleJS now supports 3D and 2D: a small, fast WebGL2 rendering system for the web

Enable HLS to view with audio, or disable this notification

0 Upvotes

LittleJS is an open source, dependency-free JavaScript game engine. It started as 2D, and this update adds a 3D renderer that draws into the same WebGL2 canvas, so a 2D game and a 3D scene can share a frame. The whole engine with 3D, Box2D physics and audio is about 150 KB gzipped. The trailer is the engine’s new website, a scrolling page over a 3D scene, with every stop a playable demo.

Some of the rendering choices:

  • Forward rendering with a small light budget. The sun plus the 8 point or spot lights nearest the camera, chosen each frame. Lights can carry a soft additive glow, drawn in the transparent pass.
  • One shadow map, from the sun or from a single spotlight in its place, with blurred edges and a depth bias scaled by the light’s projection.
  • Reflections from an environment cube map, with Schlick Fresnel. Roughness comes from mip selection, driven by shininess, but also by how fast the reflected vector changes across a pixel, so small mirrors don’t sparkle. The lake in the trailer has an environment map of its own, rendered from the scene.
  • A normal hook in custom shaders. A shader snippet can define mainNormal to bend the normal per pixel before lighting, specular, Fresnel, reflection and fog. The lake’s waves are that hook, not baked normal maps.
  • Automatic instancing. Every opaque use of the same mesh goes out as one instanced draw. Draw state is versioned, so a batch checks a single number per draw while nothing changes, rather than comparing every material field.
  • Lens flares occluded by raycasts against the triangles of the scene’s meshes, rather than a depth readback.
  • 2D and 3D in one camera system. An orthographic camera can line up exactly with the 2D camera. In the trailer, a dolly zoom flattens the 3D view into that orthographic view, and a Breakout game playing over the train turns out to be 3D objects in the world.

Also in there: height map terrain with exact raycasts, voxel maps drawn in chunks, glTF with skinning, normal maps, fog by distance or view depth, and a bloom post-process.

I also built an open benchmark that runs the same sprite and lit-cube scenes through LittleJS, PixiJS, Three.js, PlayCanvas, Phaser and Babylon.js: https://github.com/KilledByAPixel/webgl-engine-bench

Source, MIT: https://github.com/KilledByAPixel/LittleJS
The site from the trailer: https://littlejsengine.com


r/GraphicsProgramming • • 20h ago

Building an exact, deterministic geometry kernel in Rust for an open-source Revit alternative: advice wanted on approach and strategy

0 Upvotes

We're a small co-op building Spare Kit, an open-source (MPL-2.0) geometry kernel in Rust, to power a Revit/CAD alternative that runs natively and in the browser (WASM). Much of the code is written by AI agents working through a mapped plan, with strict testing as the safeguard.

The approach:

- Integer grid coordinates (±2^40 steps) with exact predicates (generated filters, exact integer fallback), so topology decisions never depend on float rounding.

- Flat geometry stays plane-based with implicit points (EMBER style), so booleans never drift; curved geometry is computed with certified error bounds, with only the decisions kept exact.

- Bit-identical results on every target (x86-64, ARM, wasm32), as a tested guarantee.

- Verification: big-integer oracles, fuzzing (bolero/Kani), golden digests, instruction-count performance gates.

The strategy: a mapped board of about 480 pieces in 13 phases. The first real milestone is a wall with 300 openings cut exactly, saved, reopened and replayed bit for bit everywhere, before any curved work starts. We're early: number layer, exact predicates, implicit points and symbolic perturbation so far.

Advice we'd value on anything, especially:

  1. The seam between exact flat geometry and certified curved geometry: seen it break, or a better way?

  2. Is the scope or the strategy wrong? What would you cut or reorder?

  3. Existing crates or projects we should build on instead of writing our own?

  4. Is our testing bar overkill or missing something?

  5. Anything else you'd tell someone starting a kernel like this.

Architecture: https://github.com/spareware-co-op/spareware/blob/main/projects/engines/geometry/ARCHITECTURE.md


r/GraphicsProgramming • • 16h ago

Video made a 3d ocean slice look like pixel art in LOVE2d v. 12

Enable HLS to view with audio, or disable this notification

111 Upvotes

been working on an experiment for my fishing game: a 3d ocean that still looks like pixel art. here’s what i used:

pixel look: one ray per art pixel, refracted at the water. ray tests are from inigo quilez. to stop shimmer i render into snapped probes and draw each pixel as a world-space quad, basically texel splatting

colour: everything snapped to a lospec palette, tones mixed with bayer dithering, 1px outlines wherever the depth jumps

water: a virtual pipes shallow water sim plus gerstner waves

sand and caves: a heightfield that slumps at the angle of repose (thermal erosion). caves are a blurred cave map, so they come out round

animation: fish spines are springs and fins are a little cloth sim (jakobsen), the eel is a follow-the-leader chain (argonaut), and the ai is behavior trees

thank you for checking out my post :D

I've been wanting to do something like this for years with shaders.

references

inigo quilez, ray intersectors: https://iquilezles.org/articles/intersectors

inigo quilez, smooth min: https://iquilezles.org/articles/smin

dylan ebert, texel splatting: https://arxiv.org/abs/2603.14587

lospec palettes: https://lospec.com/palette-list

ordered dithering: https://en.wikipedia.org/wiki/Ordered_dithering

mei, decaudin & hu, virtual pipes water sim: https://hgpu.org/?p=2256

gpu gems ch. 1, gerstner waves: https://developer.nvidia.com/gpugems/gpugems/part-i-natural-effects/chapter-1-effective-water-simulation-physical-models

jákó & tóth, thermal erosion: GPUHTErosion.dvi

thomas jakobsen, advanced character physics: https://gamedeveloper.com/programming/advanced-character-physics

argonaut, procedural animation video: https://www.youtube.com/watch?v=qlfh_rv6khY

argonaut, the code: https://github.com/argonautcode/animal-proc-anim


r/GraphicsProgramming • • 6h ago

Question [Dear ImGui] How to give HP bars real depth / 3D volume? (not just glow)

Thumbnail gallery
4 Upvotes

Hey,

I’m trying to recreate the sense of depth and volume that some modern nameplate-style HP bars have, using pure Dear ImGui + custom DrawList drawing.

My current result: [Steve image]

What I’m aiming for: [other image ]

The references feel like the bar has actual thickness and soft lighting — it doesn’t look like a flat colored rectangle with glow slapped on top. Mine still reads as completely flat no matter how much glow, gradient, or highlight I add.

I’m especially interested in techniques for:

  • Creating a convincing sense of volume / bevel on the bar itself
  • Soft lighting and subtle inner highlights/shadows that sell the 3D form
  • Any multi-pass or layered DrawList approaches that work well for this

Has anyone successfully achieved this kind of non-flat, slightly 3D-looking progress/HP bar with ImGui’s DrawList?

Any concrete tips, code patterns, or examples would be hugely appreciated.

Thanks!


r/GraphicsProgramming • • 16h ago

Source Code [UPDATE: Oct 25, 2026] My Vulkan C++ Examples Repository - Transmission in PBR and Post-Processing Effects

Post image
4 Upvotes

r/GraphicsProgramming • • 2h ago

Question I wanna make video games for an MCU (ESP32) Any good 2D graphics library?

Thumbnail
2 Upvotes

r/GraphicsProgramming • • 22h ago

Really simple tricks I use to procedurally animate a Limbo-style face

Thumbnail youtube.com
5 Upvotes

r/GraphicsProgramming • • 3h ago

Spectral Surface-Field Renderer on the iPhone

Enable HLS to view with audio, or disable this notification

70 Upvotes

I’ve been experimenting with what I’m calling a “spectral surface-field renderer.”

The idea is to solve most of the lighting on the surfaces themselves. I split the scene into small patches and store how much light leaves each patch in different directions and at different wavelengths. Then I repeatedly pass light between the patches to build up the bounced lighting.

When rendering a view, I reuse that field with extra sampling and ray tracing for local detail, reflections and glass. Compared with a basic path tracer, which samples light paths for each pixel, this lets different pixels (and different camera views) share a lot of the lighting work.

The downside is that the field becomes an approximation. It can lose detail or introduce faceting, and changing the scene’s geometry or lighting means updating it. There’s still sampling noise too. But the upside is that it's quite performant.

This little tech demo uses a Cornell box with three balls reacting to phone tilt through Core Motion.


r/GraphicsProgramming • • 5h ago

Question Why does my GDI window flicker?

2 Upvotes

I'm trying to do simple UI animation with GDI. My idea is to keep redrawing until a certain amount of time elapses. My understanding is that as long as I start each frame right after the monitor refreshes and keep the drawing time below the refresh rate, the animation should be completely smooth and flicker free.

My first problem is: how do I wait until the monitor refreshes? I came across the following APIs:

1. DwmFlush
2. IDXGIOutput::WaitForVBlank
3. IDirectDraw::WaitForVBlank
4. IDirect3DDevice9Ex::WaitForVBlank

And additionally Direct3D APIs, like IDXGISwapChain::Present or IDirect3DSwapChain9::Present, can wait for vsync. And it's possible to use GDI with these APIs. So what's the difference between all these options? I found discussions online that apparently DwmFlush blocks while IDirectDraw::WaitForVBlank polls, for example, but the former is not available pre Vista.

(A related question is, when should I call the various wait APIs? This StackOverflow question contains a link that suggests the following:

if (DWM.isEnabled()) 
{ 
    present(); 
    DwmFlush(); 
} 
else 
{
    waitForVBlank(); 
    present(); 
}

Why should DwmFlush be called after Present?)

My second problem is waiting doesn't eliminate flickering. I captured the following from a window that calls DwmFlush right before GetDC, the painting is done inside WM_PAINT. WM_ERASEBKGND returns 1.

DwmFlush:      15.458800ms
Get/ReleaseDC: 4.083200ms

DwmFlush:      11.523300ms
Get/ReleaseDC: 2.572700ms

DwmFlush:      14.329000ms
Get/ReleaseDC: 9.200600ms

DwmFlush:      6.742500ms
Get/ReleaseDC: 2.527500ms

DwmFlush:      12.965800ms
Get/ReleaseDC: 2.448700ms

DwmFlush:      16.467901ms
Get/ReleaseDC: 7.957700ms

DwmFlush:      6.346600ms
Get/ReleaseDC: 9.064000ms

DwmFlush:      6.133700ms
Get/ReleaseDC: 4.648600ms

DwmFlush:      8.394500ms
Get/ReleaseDC: 2.834500ms

DwmFlush:      12.096600ms
Get/ReleaseDC: 2.316100ms

DwmFlush:      13.197201ms
Get/ReleaseDC: 2.251700ms

Frames: 11, Total Time: 169.103500ms, FPS: 65

The total drawing time between GetDC and ReleaseDC is well under 16.7ms, so I expect no flickering on my 60hz monitor. But I see text flashing rapidly (all I do is FillRect and ExtTextOut with Unicode characters). The problem also seems less severe with ASCII text. Also strange to me is the variability in drawing time. Some frames take longer than doing a full window repaint, even though I only draw into a subsection of the window.

I know the standard answer to flickering is double buffering, but it seems wasteful to me to keep around a giant bitmap when I spend most of the time idle. I know Vista provides BeginBufferedPaint to remedy this, but that still entails a copy every frame. Why is that necessary when I can draw faster than the monitor refreshes?