Real-time 3D point cloud viewer for Xbox Kinect 360
GPU-accelerated rendering Β· cyberspace effects Β· plugin system Β· built-in profiler
KinectPyEffects transforms an Xbox Kinect 360 sensor into a real-time 3D point cloud viewer. The entire depth-to-point-cloud pipeline runs on the GPU via OpenGL 4.3 compute shaders β no CPU-side geometry building, no VBO upload stalls, no blocking GPU readbacks.
The viewer includes 20+ visual effects (cyberspace mode, ghost particles, particle trails, bloom, chromatic aberration), depth filters, color palettes, a preset system, a built-in performance profiler, and an extensible plugin architecture.
Key highlights:
- Zero-CPU point cloud β depth texture β compute shader β SSBO β
glDrawArraysIndirect - 144 FPS interpolation β Kinect's 30 FPS depth smoothly interpolated on GPU with depth-edge snapping
- GPU temporal smoothing β EMA-based depth stabilization computed per-pixel in compute shader
- Batched atomics β workgroup-level shared memory reservation reduces global atomic contention ~256Γ
- 20+ real-time effects β cyberspace mode, ghost particles, particle trails, bloom, glitch, CRT, and more
- Built-in profiler β CPU + GPU section timings, 1% low FPS, sparkline graphs
- Plugin system β extend with Python scripts, hot-reloadable at runtime
- One-click setup β
install.batβrun.bat
- Requirements
- Installation
- Usage
- Controls
- Features
- Plugin API
- Architecture
- Project Structure
- Troubleshooting
- License
| Component | Details |
|---|---|
| OS | Windows 10 / 11 |
| Python | 3.10 (other versions not tested) |
| Kinect SDK | Microsoft Kinect SDK v1.8 |
| Sensor | Xbox Kinect 360 (v1) with USB adapter + power supply |
| GPU | OpenGL 4.3+ capable (compute shaders required) |
Download and install Microsoft Kinect SDK v1.8. Connect your Kinect sensor (USB + power supply).
Double-click install.bat. The script will:
- Locate your Python 3.10 installation
- Create a virtual environment (
kinect_env/) - Install all dependencies:
numpy opencv-python moderngl glfw imgui[glfw] pythonnet PyOpenGL PyOpenGL-accelerate
Double-click run.bat.
The script activates the virtual environment and runs
main.py. On first launch, the app will initialize the Kinect sensor and open a 1280Γ720 window.
The application opens an interactive 3D viewport with a control panel on the left. All settings are adjustable in real time via the ImGui interface. Changes can be saved to presets and exported.
| Input | Action |
|---|---|
| LMB + drag | Orbit camera |
| RMB + drag | Pan camera |
| Scroll wheel | Zoom in/out |
| Home | Reset camera to default |
| F10 | Toggle UI visibility |
| F11 | Toggle fullscreen |
| F12 | Capture screenshot (PNG, no UI overlay) |
| P | Export point cloud to PLY |
| ESC | Quit |
| Feature | Description |
|---|---|
| GPU Compute Pipeline | Depth + color textures β compute shader (16Γ16 workgroups) β SSBO β glDrawArraysIndirect. Zero CPU geometry. Batched atomic reservation via shared memory (~256Γ less global atomic contention). |
| GPU Frame Interpolation | 30 β 144 FPS via weighted depth/color blending with 200 mm snap threshold at depth edges. Runs entirely in compute shader using double-buffered textures (current + previous Kinect frame). |
| GPU Temporal Smoothing | Exponential moving average per-pixel in compute shader via persistent image2D texture. Snap threshold prevents smearing at motion edges. |
| Point Size & Shape | Adjustable size (1β10), circle or square shape. |
| Depth Range | Configurable min/max depth in cm. |
| Depth-Color Alignment | Perspective correction for IR β RGB camera offset with adjustable baseline (X/Y mm). |
| Frustum Culling | Gribb-Hartmann 6-plane extraction, evaluated per-point in compute shader. |
| Depth-Scaled Points | Near points rendered larger (configurable factor). |
| Point Shading (SSAO) | Per-point hemisphere ambient occlusion with adjustable strength. |
| Filter | Description |
|---|---|
| Smooth Depth | Bilateral filter (cv2.bilateralFilter) β smooths noise while preserving edges. |
| Edge Filter | Removes flying pixels at depth discontinuities (threshold: 10β200 mm). Runs in compute shader using texelFetch neighbor sampling. |
| Temporal Smoothing | GPU-side EMA with snap threshold β stabilizes surfaces without smearing motion. Persistent state in r32f image texture. |
A full netrunner-aesthetic rendering mode with depth-based coloring and numerous glitch effects:
| Effect | Description |
|---|---|
| Cluster Coloring | Automatic near/far cluster detection via depth histogram gap (~5 Hz, downsampled). Cyan near, magenta far. |
| Invert Colors | Swap near/far cluster palette. |
| Color Glitch | Random per-fragment color replacement (cyan / pink / white / channel swap). |
| Glitch Bands | Horizontal displacement bands, stochastically triggered. |
| Double Glitch | Screen-space duplication with random offset (composite pass). |
| Ghost Render | Temporal screen accumulation with configurable decay (ping-pong FBOs). |
| Drip Trails | Downward UV shift creating vertical drip effect. |
| Ghost Particles | Sampled points persist as fading ghosts. GPU double-buffered SSBO, two-phase dispatch with glMemoryBarrier. Up to 200K entries. |
| Particle Trails | Randomly frozen points with downward drip animation. GPU compute, two-phase dispatch. Up to 30K base points. |
| Grid Floor | Procedural dot grid at floor level. |
| Noise Particles | Floating ambient particles, shader-animated. |
| Jitter | Per-vertex position noise. |
| Effect | Description |
|---|---|
| Bloom | Multi-sample gaussian blur with brightness threshold. Adjustable strength. |
| Chromatic Aberration | Radial R/G/B channel offset from screen center. |
| Edge Glow | Neighbor color-difference detection with white-cyan glow. |
| Pixelate | UV grid snapping, adjustable pixel size (1β40). |
| Effect | Description |
|---|---|
| Wave Distortion | Sinusoidal position displacement. Configurable amplitude and frequency. |
| Voxelize | Snaps vertex positions to a 3D grid. |
| Pulse | Rhythmic point size oscillation. |
| Palette | Style |
|---|---|
| Original | Kinect RGB colors |
| Thermal | Blue β Cyan β Green β Yellow β Red β White |
| Night Vision | Green phosphor with noise grain |
| Retro Amber | Warm amber monochrome |
| Format | Details |
|---|---|
| Screenshot (F12) | PNG capture of the viewport without UI overlay. Saved to screenshots/. |
| PLY (P) | Binary little-endian PLY with XYZ (float32) + RGB (uint8). Read directly from GPU SSBO via ctx.finish(). Up to 1M points. Saved to exports/. |
Save, load, and delete named presets via the UI panel. All settings (including plugin settings) are stored as JSON files in presets/. Presets are portable β drop a .json file into the folder and it appears in the list.
Built-in CPU + GPU profiler accessible from the Performance section in the UI panel.
| Feature | Description |
|---|---|
| CPU Sections | Per-section timing (perf_counter) for: swap, events, readback, kinect, gpu_upload, compute, tex_upload, render, imgui |
| GPU Sections | OpenGL timer queries (GL_TIME_ELAPSED) with 1-frame-delayed readback (ring buffer of 3 queries) for: compute, render |
| Frame Stats | Average/max frame time, 1% low FPS (worst 1% of frames over 120-frame window) |
| Sparkline | 120-frame rolling graph of frame times |
| Zero overhead | Disabled by default; no performance cost when profiler is off |
Plugins are Python files placed in the plugins/ directory. Each file must define a class inheriting from KinectPlugin. Plugins are auto-discovered at startup and can be hot-reloaded from the UI.
from plugin_api import KinectPlugin
class MyPlugin(KinectPlugin):
name = "My Plugin"
version = "1.0"
author = "Author"
description = "Does something cool"
def on_init(self, app):
"""Called once after OpenGL initialization."""
pass
def on_kinect_frame(self, app, depth, color):
"""Called on each new Kinect frame.
depth: np.ndarray uint16 (mm), color: np.ndarray uint8 (BGR)"""
pass
def on_draw_ui(self, app):
"""Draw custom ImGui panels."""
pass| Hook | When |
|---|---|
on_init(app) |
After GL init, before main loop |
on_cleanup(app) |
Application shutdown |
on_frame_start(app, dt) |
Start of each frame |
on_kinect_frame(app, depth, color) |
New Kinect depth + color data received |
on_pre_render(app) |
Before 3D scene render (after compute dispatch) |
on_post_render(app) |
After composite pass, before ImGui |
on_draw_ui(app) |
Inside ImGui frame |
on_export(app, xyz, rgb, path) |
After PLY export completes |
on_settings_changed(app, key, old, new) |
Any setting modified via UI |
on_preset_save(app, name) |
Preset saved |
on_preset_load(app, name) |
Preset loaded |
The app argument passed to all hooks exposes:
| Field | Type | Description |
|---|---|---|
ctx |
moderngl.Context |
OpenGL context |
window |
GLFW window | Window handle |
camera |
OrbitCamera |
Camera (get MVP, frustum planes) |
settings |
dict |
All application settings |
sensor |
KinectSensor |
.NET Kinect sensor object |
pc_ssbo |
moderngl.Buffer |
Point cloud SSBO (XYZ+RGB, float32Γ6 per point) |
indirect_buf |
moderngl.Buffer |
Indirect draw buffer (first uint = point count) |
width, height |
int |
Viewport size |
time |
float |
Current time (seconds) |
dt |
float |
Frame delta time |
fps |
int |
Current FPS |
Override get_settings() β dict and set_settings(data) to save/restore plugin-specific settings with presets.
| Plugin | Description |
|---|---|
| Auto Orbit | Cinematic auto-rotation with vertical bob, zoom breathe, pause on mouse drag |
| CRT Monitor | Post-processing CRT effect: scanlines, vignette, barrel distortion, flicker, RGB shift, film noise |
| FPS Overlay | Transparent overlay with FPS and point count (throttled GPU readback at 2 Hz) |
| Point Explosion | GPU compute shader that explodes cloud from center with gravity, spin, and fade |
| Smoke Dissolve | Top-down dissolve sweep into rising turbulent smoke with configurable color |
Kinect 360 (30 FPS)
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β C# Interop (pythonnet) β
β DepthStream β int16[] β numpy (bit-shift >> 3) β
β ColorStream β byte[] β numpy (BGRAβBGR) β
β Zero-copy double-buffered output arrays β
ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CPU Pre-processing β
β Downsample (cv2.resize, pre-allocated dst) β β
β Optional bilateral filter β
ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β GPU Upload (< 0.15 ms) β
β Depth: uint16βfloat32 β R32F texture β
β Color: BGR direct upload (shader swizzles) β
β Double-buffered: curr β prev textures β
ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β GPU Compute Pipeline (OpenGL 4.3) β
β β
β Build Shader (16Γ16 workgroups) β
β ββ Interpolation (prevβcurr depth+color blend) β
β ββ Temporal smoothing (EMA via image2D state) β
β ββ Range filter, edge filter (texelFetch) β
β ββ Unproject (IR intrinsics β 3D) β
β ββ Color lookup (RGB intrinsics + baseline) β
β ββ BGRβRGB swizzle in shader β
β ββ Frustum culling (6-plane test) β
β ββ Cluster coloring (depth histogram gap) β
β ββ Atomic append β SSBO + indirect draw count β
β β β
β βββ Ghost Particles Compute (2-phase) β
β β Shared-memory batched atomics β
β β Double-buffered SSBO, up to 200K β
β β β
β βββ Particle Trails Compute (2-phase) β
β Shared-memory batched atomics β
β Double-buffered SSBO, up to 30K β
β β
β glFlush() β pipeline GPU commands immediately β
ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Render β
β glDrawArraysIndirect (points from SSBO) β
β + grid floor + noise particles β
β β β
β βΌ β
β Post-Processing FBO chain β
β Scene β Temporal Accumulation (ping-pong) β
β β Composite (bloom, chroma, edge, pixel) β
β β Plugin post-effects (CRT, etc.) β
β β Screen β
ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Frame Timing β
β VSync (swap_interval) OR β
β Frame limiter (hybrid sleep + spin-wait, 1 ms β
β Windows timer resolution via timeBeginPeriod) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
KinectPyEffects/
β
βββ main.py Application class, GLFW window, main loop
βββ app_state.py AppState dataclass (replaces 30+ globals)
βββ config.py Settings TypedDict, constants, presets
βββ kinect_capture.py Kinect v1 sensor I/O via .NET interop
βββ gpu_pipeline.py Compute shaders, SSBOs, point cloud build
βββ renderer.py OpenGL programs, FBOs, draw calls
βββ shaders.py All GLSL shaders (vertex, fragment, compute Γ4)
βββ camera.py OrbitCamera with MVP and frustum extraction
βββ pointcloud.py Cluster threshold detection (histogram gap)
βββ ui_manager.py ImGui panels, settings UI, preset management
βββ perf_metrics.py CPU + GPU performance profiler
βββ plugin_api.py KinectPlugin base class, PluginManager, AppContext
β
βββ install.bat One-click environment setup (venv + pip)
βββ run.bat One-click launch (activate venv β python main.py)
βββ LICENSE MIT License
β
βββ presets/ Saved setting presets (.json)
βββ screenshots/ Captured screenshots (.png)
βββ exports/ Exported point clouds (.ply)
βββ plugins/ User plugins (.py)
βββ auto_orbit.py Auto-rotation with camera animation
βββ crt_monitor.py CRT monitor post-effect
βββ fps_overlay.py FPS + point count overlay
βββ point_explosion.py GPU compute explosion effect
βββ smoke_mug.py Smoke dissolve effect
| Problem | Solution |
|---|---|
| "Python Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½" | Install Python 3.10 to the default path (AppData\Local\Programs\Python\Python310\). |
| "Kinect Π½Π΅ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½" | Check USB + power supply connections. Verify Kinect appears in Device Manager. |
| "Near mode Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΡΡΡ" | Normal for standard Kinect 360. Near mode requires Kinect for Windows. The app continues in Default mode. |
| "GPU pipeline requires OpenGL 4.3+" | Your GPU does not support compute shaders. Update drivers or use a newer GPU. |
| Kinect disconnects mid-session | The app auto-reconnects within ~3 seconds. Check power supply stability. |
| Low FPS | Lower the Point Cloud resolution preset (e.g., 320Γ240). Disable Bloom, Ghost Particles, Particle Trails. Enable the Performance profiler to identify the bottleneck. |
| Crash on minimize | Fixed β the app skips rendering when the framebuffer size is 0Γ0. |
| "invalid color attachment" | Usually means the window was minimized or resized to 0. Should be handled automatically. |
This project is licensed under the MIT License.