shdrlib 0.1.0

A three-tiered Vulkan shader compilation and rendering framework built in pure Rust
Documentation
# Quick Start Tutorial


Get your first triangle rendered with shdrlib in under 10 minutes!

## Prerequisites


- ✅ Rust 1.82+ installed
- ✅ Vulkan drivers installed
- ✅ shdrlib added to your project

Not set up yet? See the [Installation Guide](installation.md).

---

## Step 1: Create a New Project


```bash
cargo new my_triangle
cd my_triangle
cargo add shdrlib ash
```

---

## Step 2: Choose Your Starting Tier


### Option A: EZ Tier (Recommended for Beginners)


**Best for:** Learning Vulkan, prototyping, quick results

Add this to `src/main.rs`:

```rust
use shdrlib::ez::*;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Step 1: Create renderer (replaces 100+ lines of setup)
    let mut renderer = EzRenderer::new()?;
    
    // Step 2: Create graphics pipeline
    let pipeline = renderer.quick_pipeline(VERTEX_SHADER, FRAGMENT_SHADER)?;
    
    // Step 3: Render a frame
    renderer.render_frame(|frame| {
        frame.bind_pipeline(pipeline)?;
        frame.set_viewport(0.0, 0.0, 800.0, 600.0);
        frame.set_scissor(0, 0, 800, 600);
        frame.draw(3, 1, 0, 0);  // Draw 3 vertices (a triangle)
        Ok(())
    })?;
    
    println!("✅ Rendered a triangle!");
    Ok(())
}

// Vertex shader: positions the triangle vertices
const VERTEX_SHADER: &str = r#"
#version 450


vec2 positions[3] = vec2[](
    vec2(0.0, -0.5),   // Top vertex
    vec2(0.5, 0.5),    // Bottom-right
    vec2(-0.5, 0.5)    // Bottom-left
);

void main() {
    gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
}
"#;

// Fragment shader: colors the triangle orange
const FRAGMENT_SHADER: &str = r#"
#version 450


layout(location = 0) out vec4 outColor;

void main() {
    outColor = vec4(1.0, 0.5, 0.2, 1.0);  // Orange color
}
"#;
```

**Run it:**
```bash
cargo run
```

**What you just did:**
- Created a Vulkan instance, device, and queues
- Compiled GLSL shaders to SPIR-V
- Built a graphics pipeline
- Rendered a triangle to an offscreen image

**Total lines of code: ~30** (vs 400+ with raw Vulkan)

---

### Option B: EX Tier (Production-Ready)


**Best for:** Real applications, when you need more control

```rust
use shdrlib::{
    core::ShaderStage,
    ex::{RuntimeManager, RuntimeConfig, ShaderManager, PipelineBuilder},
};
use ash::vk;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Step 1: Initialize runtime
    let mut runtime = RuntimeManager::new(RuntimeConfig::default())?;
    let device = runtime.device();
    
    // Step 2: Compile shaders
    let mut shaders = ShaderManager::new(device)?;
    let vert_id = shaders.add_shader(VERTEX_SHADER, ShaderStage::Vertex, "vert")?;
    let frag_id = shaders.add_shader(FRAGMENT_SHADER, ShaderStage::Fragment, "frag")?;
    
    // Step 3: Build pipeline
    let pipeline_id = shaders.build_pipeline(
        PipelineBuilder::new()
            .vertex_shader(shaders.get_shader(vert_id)?.handle(), "main")
            .fragment_shader(shaders.get_shader(frag_id)?.handle(), "main")
            .color_attachment_formats(vec![vk::Format::R8G8B8A8_UNORM])
            .viewport(0.0, 0.0, 800.0, 600.0)
            .scissor(0, 0, 800, 600),
        "triangle"
    )?;
    
    // Step 4: Render frame
    let frame = runtime.begin_frame()?;
    let pipeline = shaders.get_pipeline(pipeline_id)?;
    
    // Record commands (simplified - see full examples)
    // ... command buffer recording ...
    
    runtime.end_frame(&Default::default())?;
    
    println!("✅ Rendered with EX tier!");
    Ok(())
}

const VERTEX_SHADER: &str = r#"
#version 450

vec2 positions[3] = vec2[](vec2(0.0, -0.5), vec2(0.5, 0.5), vec2(-0.5, 0.5));
void main() { gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); }
"#;

const FRAGMENT_SHADER: &str = r#"
#version 450

layout(location = 0) out vec4 outColor;
void main() { outColor = vec4(1.0, 0.5, 0.2, 1.0); }
"#;
```

**What's different:**
- Explicit configuration at each step
- Type-safe shader/pipeline IDs
- More control over the render loop
- Better for production code

---

## Step 3: Understanding What Happened


### The Shaders


**Vertex Shader:**
- Runs once per vertex (3 times for a triangle)
- Positions vertices in clip space (-1 to 1)
- Outputs `gl_Position` for each vertex

**Fragment Shader:**
- Runs once per pixel inside the triangle
- Determines the color of each pixel
- Outputs to `outColor` (the framebuffer)

### The Pipeline


A **graphics pipeline** connects:
1. Vertex shader → processes vertices
2. Rasterizer → converts triangles to pixels
3. Fragment shader → colors pixels

shdrlib creates this pipeline from your shaders automatically!

### The Draw Call


```rust
frame.draw(3, 1, 0, 0);
```

This means:
- **3** vertices (a triangle)
- **1** instance (draw once)
- Start at vertex **0**
- Start at instance **0**

---

## Step 4: Add Color Interpolation


Let's make the triangle more interesting with per-vertex colors:

```rust
const VERTEX_SHADER: &str = r#"
#version 450


vec2 positions[3] = vec2[](
    vec2(0.0, -0.5),
    vec2(0.5, 0.5),
    vec2(-0.5, 0.5)
);

vec3 colors[3] = vec3[](
    vec3(1.0, 0.0, 0.0),  // Red
    vec3(0.0, 1.0, 0.0),  // Green
    vec3(0.0, 0.0, 1.0)   // Blue
);

layout(location = 0) out vec3 fragColor;

void main() {
    gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
    fragColor = colors[gl_VertexIndex];
}
"#;

const FRAGMENT_SHADER: &str = r#"
#version 450


layout(location = 0) in vec3 fragColor;
layout(location = 0) out vec4 outColor;

void main() {
    outColor = vec4(fragColor, 1.0);
}
"#;
```

**Run again:**
```bash
cargo run
```

Now you have a **gradient triangle**! The GPU interpolates colors between vertices automatically.

---

## Step 5: Add Vertex Buffers


Instead of hardcoding positions in the shader, let's use a vertex buffer:

```rust
use shdrlib::ez::*;

#[repr(C)]

#[derive(Clone, Copy)]

struct Vertex {
    pos: [f32; 2],
    color: [f32; 3],
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut renderer = EzRenderer::new()?;
    
    // Create vertex data
    let vertices = vec![
        Vertex { pos: [0.0, -0.5], color: [1.0, 0.0, 0.0] },
        Vertex { pos: [0.5, 0.5], color: [0.0, 1.0, 0.0] },
        Vertex { pos: [-0.5, 0.5], color: [0.0, 0.0, 1.0] },
    ];
    
    // Upload to GPU
    let buffer = renderer.create_vertex_buffer(&vertices)?;
    
    let pipeline = renderer.quick_pipeline(VERTEX_SHADER, FRAGMENT_SHADER)?;
    
    renderer.render_frame(|frame| {
        frame.bind_pipeline(pipeline)?;
        frame.bind_vertex_buffer(buffer)?;
        frame.set_viewport(0.0, 0.0, 800.0, 600.0);
        frame.set_scissor(0, 0, 800, 600);
        frame.draw(3, 1, 0, 0);
        Ok(())
    })?;
    
    Ok(())
}

// Updated shaders to read from vertex buffer
const VERTEX_SHADER: &str = r#"
#version 450


layout(location = 0) in vec2 inPos;
layout(location = 1) in vec3 inColor;

layout(location = 0) out vec3 fragColor;

void main() {
    gl_Position = vec4(inPos, 0.0, 1.0);
    fragColor = inColor;
}
"#;

const FRAGMENT_SHADER: &str = r#"
#version 450

layout(location = 0) in vec3 fragColor;
layout(location = 0) out vec4 outColor;
void main() { outColor = vec4(fragColor, 1.0); }
"#;
```

Now your triangle data is on the GPU, not hardcoded in shaders!

---

## Next Steps


### 🎨 Run the Examples


```bash
# EZ tier examples

cargo run --bin ez_01_hello_triangle
cargo run --bin ez_02_compute_multiply
cargo run --bin ez_03_buffers_demo

# EX tier examples  

cargo run --bin ex_01_triangle_100_lines
cargo run --bin ex_03_textured_quad

# CORE tier examples

cargo run --bin 01_triangle_raw
```

### 📚 Read the Guides


- **[EZ Tier Guide]../guides/ez-tier-guide.md** - Deep dive into EZ tier
- **[EX Tier Guide]../guides/ex-tier-guide.md** - Production patterns
- **[Vulkan Basics]vulkan-basics.md** - Understanding the graphics pipeline

### 🔧 Add Features


- **Textures:** Load and sample images
- **Uniforms:** Pass data from CPU to GPU
- **Compute shaders:** Run parallel computations
- **Multiple objects:** Draw more than one thing

### 🤔 Get Help


- [FAQ]faq.md - Common questions
- [Troubleshooting]troubleshooting.md - Fix issues
- [GitHub Discussions]https://github.com/paulburnettjones-wq/shdrlib/discussions

---

**Congratulations! 🎉** You just rendered with Vulkan using shdrlib!

---

**Last Updated:** October 30, 2025