ash_renderer 0.2.3

Production-quality Vulkan renderer in Rust using ASH - ECS-free, pure rendering engine
docs.rs failed to build ash_renderer-0.2.3
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Visit the last successful build: ash_renderer-0.4.30

ASH Renderer

Crates.io Documentation License CI

A production-read Vulkan renderer built with ASH and VMA. Designed for high-performance games and graphics applications, featuring ECS-independence and deep GPU optimization.

✨ Features (v0.2.3)

[!NOTE] Release 0.2.0 was broken due to a missing build script for shader compilation. v0.2.3 fixes this and is the recommended version. I apologize for the inconvenience!

Check out what's new!

  • 🎨 Bindless Texturing: Fully dynamic texture access using descriptor_indexing. Supports thousands of textures with zero binding overhead.
  • 🖥️ Headless Support: Run heavy rendering workloads or benchmarks on CI without a window (virtual swapchain).
  • 🌑 Advanced Shadows: Cascaded Shadow Maps (CSM) with PCF filtering and light culling.

Core Capabilities

  • PBR Materials: Metallic/Roughness workflow with texture mapping.
  • Post-Processing: Integrated Bloom, Tonemapping (ACES), and TAA.
  • GPU Profiling: Built-in Diagnostics Overlay and timestamp queries.
  • Hot-Reloading: Detects shader changes at runtime (experimental).
  • Cross-Platform: Runs on Windows (Win32), Linux (X11/Wayland), and macOS (Metal) via a unified SurfaceProvider.

🚀 Quick Start

Add to your Cargo.toml:

[dependencies]

ash_renderer = "0.2.3"

winit = "0.30"

glam = "0.30"

Initialization

use ash_renderer::{Renderer, WindowSurfaceProvider};
use winit::event_loop::EventLoop;

fn main() -> anyhow::Result<()> {
    let event_loop = EventLoop::new()?;
    let window = winit::window::Window::builder().build(&event_loop)?;
    
    // Create Renderer with cross-platform SurfaceProvider
    let surface_provider = WindowSurfaceProvider::new(&window, 800, 600);
    let mut renderer = Renderer::new(surface_provider)?;

    // Load assets...
    let mesh = Mesh::create_cube();
    renderer.set_mesh(mesh);

    // Render loop
    event_loop.run(move |event, _, control_flow| {
        // ... handling logic ...
        if let Event::MainEventsCleared = event {
            renderer.render_frame(view, projection, camera_pos).unwrap();
        }
    })?;
    Ok(())
}

🔌 Headless Benchmarking

Run graphics benchmarks in purely headless mode (no window required):

use ash_renderer::{Renderer, HeadlessSurfaceProvider};

// Initialize without winit/window
let provider = HeadlessSurfaceProvider::new(1920, 1080);
let mut renderer = Renderer::new(provider)?;

// Loop as fast as GPU allows (no VSync)
for _ in 0..1000 {
    renderer.render_frame(view, proj, cam_pos)?;
}

🛠️ Performance

Metric Target Achieved (v0.2.3)
Draw Calls (Bindless) 10k+
Headless FPS Unlocked
Texture Switches Zero Cost

📦 Feature Flags

Feature Description Default
validation Enables Vulkan Validation Layers
gltf_loading Support for loading .gltf/.glb models
profiling Enables GPU timestamp queries

📜 License

Licensed under Apache-2.0.