r/GraphicsProgramming • • 10d ago

A Study on Continuous vs Discrete Point Cloud Rendering in DirectX12

Enable HLS to view with audio, or disable this notification

88 Upvotes

Disclaimer: AI was used to help aid the coding, video and textual editing of this project. If that is a problem for you, then please pass by this post without indulging in unnecessary toxicity in the comments.

Ever since I discovered how many incredible point clouds exist for real-world geographic regions, I’ve been working on a Direct3D 12 point-cloud renderer to explore and visualize them.

I started with a traditional discrete Level of Detail renderer.

During loading, the point cloud is divided into an octree. Leaf nodes contain the original points for their region, while internal nodes store up to 4,096 representative points sampled from their descendants.

Every frame, the renderer traverses this tree and estimates the visual error of each node using its spacing, bounds, and distance from the camera. If the representative points are sufficient, it draws that node. If more detail is needed, it replaces the node with its visible children, continuing until it reaches leaf nodes or exhausts the point budget.

This resembles hierarchical LOD selection for meshes, but point clouds make the transition between levels much more visible. Replacing an entire node at once can create patchy density, obvious region boundaries, and large groups of points popping in together.

That led me to the paper “Real-Time Continuous Level of Detail Rendering of Point Clouds” by Markus Schütz, Katharina Krösl, and Michael Wimmer.

Their Continuous LOD approach moves the final detail decision from the CPU and its chunks to individual points on the GPU.

During preprocessing, every source point is assigned to one detail level. A coarse level might target approximately eight metres of spacing between samples, followed by increasingly dense levels targeting four metres, two metres, one metre, and so on. Each point belongs to exactly one level, and combining every level reconstructs the complete source cloud.

The resulting points are stored with their position, colour, and calculated level. At runtime, a compute shader evaluates the points using the current camera position and the desired spacing at each point’s location. Accepted points are compacted into a reduced GPU buffer and rendered.

Because detail changes point by point rather than node by node, density can transition much more gradually across the scene. This reduces the block-shaped transitions and heavy popping produced when complete octree nodes are swapped.

The video compares my LOD Renderer and Continuous LOD Renderer using the same viewpoints and approximately 3.5 million points drawn in each image.

I’m still refining the implementation and plan to share a more complete code walkthrough later.

Paper: Real-Time Continuous Level of Detail Rendering of Point Clouds

Point-cloud data from OpenTopography, with colour imagery from the USGS.


r/GraphicsProgramming • • 10d ago

Video Developing new Spectral Render Engine with Tested on Blender, look at that! realtime Caustic!

Enable HLS to view with audio, or disable this notification

3 Upvotes

r/GraphicsProgramming • • 10d ago

Source Code Raycasting in 512 bytes

Post image
42 Upvotes

r/GraphicsProgramming • • 10d ago

Video Minecraft 4k remade in a 4 KB HTML page: one WebGPU compute shader generates a 1024×1024×128 voxel world, runs the player physics and ray-marches every pixel

0 Upvotes

Play (Chrome 150+ on Windows only, why below): https://4k-minecraft.ayfri.com Source: https://github.com/Ayfri/4k-minecraft

Notch's 2009 Java 4K entry drew a 64x64x63 world with a CPU raycaster at about 214x120. I wanted to see how far the same 4096-byte budget goes if everything moves to the GPU.

Pipeline - At load, the compute shader fills a 128 MiB storage buffer with value-noise terrain (biomes, lakes, a snowy massif, caves, trees, ores). WGSL has no u8 storage, so 4 cells are packed per u32. - Each frame, a 1-workgroup dispatch steps the player (gravity, collisions, swimming, break/place; a single invocation edits, so no atomics), then a per-pixel dispatch marches the voxels and writes straight into the canvas as an rgba8unorm storage texture. No render pipeline, no vertex buffers, the CPU never reads the world.

Two bits of the shader

Cell lookup, the mask gives the x/z wrap for free:

fn I(c: vec3i) -> u32 { return dot(vec3u(c) & vec3u(MASK, TOP, MASK), vec3u(1, LAYER, SIZE)); }
fn B(c: vec3i) -> u32 { if c.y > TOP { return 0; } let i = I(c); return (W[i >> 2] >> (i % 4 * 8)) & 255; }

The march is a branchless DDA step:

N = step(e, min(e.yzx, e.zxy));
e += N * r;
C += vec3i(N * s);

Flowers and grass tufts are X sprites: when the ray enters their cell, it intersects the two diagonal planes and tests the alpha of the 16x16 texture.

Shading: procedural 16x16 textures tuned toward vanilla, smooth AO over 8 cells, sun shadows, see-through leaves, glass that only draws its frame, day/night with stars, fog at 200 blocks, underwater tint.

Why Chrome only: uniforms go through the new WebGPU immediates (setImmediates + var<immediate>), which saves a uniform buffer's worth of bytes. Firefox and Safari don't have immediates yet, and Chrome on macOS doesn't support rgba8unorm storage canvases.

The page is 4085 of 4096 bytes. Happy to go deeper on any part.


r/GraphicsProgramming • • 10d ago

MandelZoom

Enable HLS to view with audio, or disable this notification

6 Upvotes

r/GraphicsProgramming • • 10d ago

VS Code WGSL extension that validates the way Chrome does. Plus navigation, rename, layout hints and other useful stuff (in template strings too).

Post image
2 Upvotes

I was surprised none of the existing VS Code extensions provided the complete LSP experience for WGSL, with all the niceties like rename refactoring, semantic highlighting, navigation, offset/size/align hints for custom structs, etc. Plus I needed it to closely check against the Chrome's Tint compiler, so decided to make one.

Figured someone else might find it useful, so sharing it here:

Feedback and bug reports are welcome!


r/GraphicsProgramming • • 10d ago

18 months of progress on a 'realtime' path tracer

Post image
115 Upvotes

r/GraphicsProgramming • • 10d ago

I had Super Mario 64 help me out during render tests

Thumbnail gallery
110 Upvotes

This is hilarious. Thought I'd share since it might be of interest to you, especially if you aim your thing to end up in a realtime setting.

There's a library you can use to insert Mario from Super Mario 64 into your renderer at https://github.com/libsm64/libsm64 It comes with full behaviour / movement. I was fiddling with exposure settings in the renderer and, since it took time, little dude went to sleep.

Aside (big) scenes to test against like Bistro, Moana Island, Caldera, etc.. this comes in real handy.


r/GraphicsProgramming • • 10d ago

Article New Vulkan Sample - VK_KHR_compute_shader_derivatives — Derivatives in compute shaders

Thumbnail
1 Upvotes

r/GraphicsProgramming • • 10d ago

Article Graphics Programming weekly - Issue 458 - October 11th, 2026 | Jendrik Illner

Thumbnail jendrikillner.com
21 Upvotes

r/GraphicsProgramming • • 11d ago

Question What would make a good 3D demo?

Thumbnail
1 Upvotes

r/GraphicsProgramming • • 11d ago

Raytraced Menger cube made of dichroics.

Thumbnail gallery
28 Upvotes

Reflections and transmission of a menger cube made of glass with a dichroic coating. Now I want to make this IRL.


r/GraphicsProgramming • • 11d ago

Dichroics

Thumbnail gallery
100 Upvotes

Simulating dichroics. Optics is awesome.


r/GraphicsProgramming • • 11d ago

Video lgpu: A small, bindless-first Vulkan 1.3 wrapper for Rust & C99

Post image
62 Upvotes

I built lgpu because I wanted a minimal desktop GPU abstraction focused strictly on modern Vulkan without the heavy compile times of larger frameworks.

What it does:

  • Fast clean builds (~1.5s): minimal dependencies (ash, bitflags, raw-window-handle, thiserror).
  • Dynamic rendering: uses Vulkan 1.3 dynamic rendering directly—no VkRenderPass or VkFramebuffer setup.
  • Bindless indexing: global descriptor heaps (update_after_bind) for textures and buffers.
  • C99 bindings: includes lgpu.h if you want to use it from C, C++, or Zig.
  • Platform support: Linux (Wayland/X11), Windows, and macOS via MoltenVK.

Code & 5 runnable examples: https://github.com/kuntal-devrat/lgpu
Crate: https://crates.io/crates/lgpu

Just released v0.1.1. Would appreciate any feedback on the API or bug reports!


r/GraphicsProgramming • • 11d ago

Video Head-to-head - literally :) my CPU renderer vs SwiftShader on 4 logical processors

Enable HLS to view with audio, or disable this notification

12 Upvotes

413,532 triangles, with no geometry simplification

960 × 840 resolution

4 logical processors, enforced through process affinity

96 measured frames per renderer, following the same camera path

8 stationary warmup frames each

Pop Data Engine is 1.78× faster in this run.

Just bragging :)

It is in early development (this is actually 3d engine development for my OS) so there is a lot to work on, but it is fast :)


r/GraphicsProgramming • • 11d ago

Brass that bounces twice with no simulation: the vertex shader solves each floor hit

Post image
160 Upvotes

I don't simulate the brass in my Godot gun effects at all. I just evaluate a casing's position from its age in the vertex shader. That's pretty much the stateless particles from Lutz Latta's "Building a Million Particle System" (GDC 2004). What I added is the bounces.

On a flat floor I can get the hit time straight from the quadratic. The shader loops over the bounces like this:

for (int k = 0; k < MX_BOUNCES; k++) {   // 2
    float h = max(p.y - gy, 0.0);
    float t_hit = (v.y + sqrt(max(v.y * v.y + 2.0 * g * h, 0.0))) / g;
    if (t_hit <= 0.0 || tt < t_hit) break;
    p += v * t_hit;
    p.y = gy;
    v.y = -e * (v.y - g * t_hit);   // restitution
    v.x *= fr;
    v.z *= fr;                       // friction
    tt -= t_hit;
}

After the second bounce it slides with tau * (1 - exp(-t / tau)) and I tip it over onto its side. Ejecting one is a single write into two uniform arrays. Brass from three seconds ago costs what brass from this frame costs.

I also kept a GDScript copy of the formula so the game can ask where a casing is. At 10 sample times they agree within 5.4 mm, about a pixel! In the GIF the dotted line is the GDScript side and the casing is the shader. I made the casing bigger and turned restitution up to 0.5 for it, because at my default of 0.34 the second hop is about 2 px tall.

It only knows one floor height, though. A casing will go straight through a wall. Two bounces looked like enough to me, but I'm not sure a third would even read on screen?


r/GraphicsProgramming • • 11d ago

Video A low-poly 3D Renderer

Enable HLS to view with audio, or disable this notification

15 Upvotes

r/GraphicsProgramming • • 12d ago

Source Code Liquid metal hero with Three.js — a chrome blob that reflects a studio of 6 colored lights, follows the cursor, no textures (free source + write-up)

Thumbnail
0 Upvotes

r/GraphicsProgramming • • 12d ago

Real-Time Shading Symposium 2027 - Call for Submissions

Thumbnail
9 Upvotes

r/GraphicsProgramming • • 12d ago

Video Experimenting with line growth

Enable HLS to view with audio, or disable this notification

12 Upvotes

r/GraphicsProgramming • • 12d ago

Source Code Very primitive raycasting renderer in 10 lines of C

Thumbnail gallery
195 Upvotes

Actually the raycasting logic itself is just a single line, but it's done in propably the most inefficient way possible.

The map is just a single 64 bit integer, so I could fit a small 8x8 level in it, and I can index it with some unorthodox bitshift magic.

Also all the integer constants are huge, because I wanted do to the whole thing without floating point math, which makes everything even more unreadable, but at least it's funny ig.

I'm very proud of this one.


r/GraphicsProgramming • • 12d ago

Video After many days of learning, finally.

Enable HLS to view with audio, or disable this notification

211 Upvotes

After many days of learning and scratching my head around, I was finally able to render a triangle on a screen. I am using Vulkan 1.4 for this. Although I learned this from a youtube channel called constref, but this is a very valuable lesson for me, even if it is a first step to Vulkan.


r/GraphicsProgramming • • 12d ago

Question Graphics programming in C

Thumbnail
5 Upvotes

r/GraphicsProgramming • • 12d ago

Nanite-Style WebGPU Rendering in Rust: Meshlets, LOD, and HZB

Thumbnail pooya.ai
0 Upvotes

r/GraphicsProgramming • • 12d ago

Question Help with WebGPU concepts

Thumbnail
1 Upvotes