[EditableImage] PixelRasterizer -- Real-time 2D Pixel Grid System with Dynamic Lighting & EditableImage Rendering

PixelRasterizer is a real-time 2D pixel grid rendering system implemented in Roblox. It creates a configurable virtual pixel grid that continuously casts rays into the 3D scene. When rays hit objects, pixels adopt the surface colors with dynamic lighting and shadow effects. The system now uses Roblox’s EditableIamge feature for ultra-efficient rendering, displaying the results on a SurfaceGui.

New Features & Major updates

EditableImage Integration

  • High-Performance Rendering: Now uses EditableImage with WritePixelsBuffer for efficient bulk pixel updates
  • Surface Display: Renders to a SurfaceGui on a 3D part for seamless world integration
  • Buffer-Based Processing: Uses optimized buffer operations for faster color manipulation
  • Aspect Ratio Preservation: Automatic aspect ratio constraint maintains proper proportions

Enhanced Lighting System

  • Advanced Shadow Detection: Each pixel performs shadow raycasting using sun direction
  • Sophisticated Color Blending: Multi-stage color blending preserves surface colors while applying realistic lighting
  • Skybox Integration: Pixels render appropriate skybox colors when no geometry is hit

Performance Optimizations

  • Intelligent Batching: Processes 200 pixels per frame for consistent 30 FPS performance
  • Smart Update Detection: Only updates pixels when scene geometry or lighting changes
  • Efficient Shadow Limiting: Controls shadow ray casting with per-frame limits (400 rays max)
  • Optimized Memory Usage: Pre-allocated pixel buffer for zero-allocation rendering
  • Change Detection Caching: Stores last hit data to minimize redundant calculations

Visual Quality Improvements

  • High-Resolution Output: 70x60 pixel grid (4,200 total pixels) with configurable dimensions
  • Accurate Color Reproduction: Preserves original surface colors while applying lighting effects
  • Realistic Shadow Blending: Dark blue shadows (RGB: 50,50,100) blend naturally with surface colors
  • Warm Lighting: Golden light color (RGB: 255,255,200) creates appealing lighting contrast
  • Sky Rendering: Beautiful sky blue (RGB: 51,168,247) for background areas

Technical Specifications

Grid Configuration

local IMAGE_WIDTH = 70          -- Pixel grid width
local IMAGE_HEIGHT = 60         -- Pixel grid height
local TOTAL_PIXELS = 4200       -- Total pixels rendered
local BATCH_SIZE = 200          -- Pixels processed per frame

Lighting Constants

local SHADOW_COLOR = {R = 50, G = 50, B = 100}      -- Deep blue shadows
local LIGHT_COLOR = {R = 255, G = 255, B = 200}     -- Warm golden light
local SKYBOX_COLOR = {R = 51, G = 168, B = 247}     -- Sky blue background

Performance Metrics

  • Frame Rate: Locked to 30 FPS for optimal performance
  • Ray Budget: ~3,000+ rays per second (primary + shadow rays)
  • Update Efficiency: Only renders when changes are detected
  • Memory Footprint: Pre-allocated 16.8KB pixel buffer
  • Shadow Ray Limiting: Maximum 400 shadow rays per frame

Ray Casting System

  • Primary Rays: Cast 150 studs forward from each pixel position
  • Shadow Rays: Cast 300 studs toward sun direction for lighting calculations
  • Smart Filtering: Automatic ray filtering to prevent self-intersections
  • Surface Normal Usage: Uses hit normals for accurate shadow positioning

Setup & Usage

The system automatically initializes a pixel grid at world position (0, 15, -30) with 0.5 world units per pixel. The renderer part is positioned at (10, 3, 0) and displays the real-time pixel grid output.

Key Components

  1. Pixel Data Array: Stores world positions and ray directions for each pixel
  2. EditableImage: High-performance image buffer for pixel color data
  3. SurfaceGui: Displays the rendered image in the 3D world
  4. Ray Origin Plane: Visual reference showing the virtual pixel grid location

Customization Options

  • Adjust IMAGE_WIDTH and IMAGE_HEIGHT for different resolutions
  • Modify BATCH_SIZE to balance performance vs. responsiveness
  • Change lighting colors for different visual moods
  • Alter ray distances for performance tuning
  • Adjust the scale parameter in initializePixelData() for pixel density

Performance Characteristics

Current Performance: Maintains excellent 30 FPS while rendering a 70x60 pixel grid (4,200 pixels) with full dynamic lighting on standard hardware. The system automatically monitors frame times and reports any frames exceeding 2ms for performance debugging.

Technical Implementation

The system uses a sophisticated pixel update pipeline:

  1. Scene Detection: Raycasts from pixel positions to detect geometry
  2. Change Analysis: Compares current hits with cached data
  3. Lighting Calculation: Determines shadow state using sun direction
  4. Color Blending: Applies realistic lighting to surface colors
  5. Buffer Writing: Efficiently updates the EditableImage buffer
  6. Display Refresh: Flushes updates to the visual display

GitHub: PixelRasterizer – Make sure to read the ReadMe!

The codebase includes both TypeScript source files and compiled Luau output, making it accessible for developers using either language. Full JSDoc documentation provides detailed API references for all functions and systems.

21 Likes

Working on an update that adds greedy meshing and lower refresh update and also bringing the rendering to the client . Soon

1 Like

This update made me so mad :cry: I spent a few hours figuring out some very annoying bugs

1 Like

It’s okay, keep up the good work! This is neat

1 Like

Fixed bugs, improved performance, took out the garbage, mowed the front lawn and now I need a nap.

In all seriousness I added shadows to the render

Added a skybox to the renderer :slight_smile:

Uh huh finally used buffer library in something

updated the devforum with new changes to it