Home

Awesome

Rasterizr

Rasterizr is a software rasterizer written in C#. It adheres closely to the Direct3D 10/11 API, but is completely implemented in software. If you're familiar with SharpDX and / or Direct3D 10/11, you'll be immediately at home with Rasterizr's API.

Rasterizr is primarily intended as an educational tool. Its inner workings are roughly comparable to a modern GPU, so by studying how Rasterizr works, you will get a good idea of what your GPU is doing when you use a hardware API like Direct3D or OpenGL.

Although its primary goal is a didactic one, Rasterizr is quite powerful in its own right. See below for a list of implemented features.

Why?

Why not?

Features

Example

The following code is from the Basic Triangle sample. If you know SharpDX, then this code should look very familiar to you! But everything happens on the CPU, in managed code - in fact, Rasterizr.dll is a Portable Class Library (PCL).

const int width = 600;
const int height = 400;

// Create device and swap chain.
var swapChainPresenter = new WpfSwapChainPresenter();
var swapChain = device.CreateSwapChain(width, height, swapChainPresenter);
var deviceContext = device.ImmediateContext;

// Create RenderTargetView from the backbuffer.
var backBuffer = Texture2D.FromSwapChain(swapChain, 0);
var renderTargetView = device.CreateRenderTargetView(backBuffer);

// Compile Vertex and Pixel shaders
var vertexShaderByteCode = ShaderCompiler.CompileFromFile("MiniTri.fx", "VS", "vs_4_0");
var vertexShader = device.CreateVertexShader(vertexShaderByteCode);

var pixelShaderByteCode = ShaderCompiler.CompileFromFile("MiniTri.fx", "PS", "ps_4_0");
var pixelShader = device.CreatePixelShader(pixelShaderByteCode);

// Layout from VertexShader input signature
var layout = device.CreateInputLayout(
  new[]
  {
    new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0),
    new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 0)
  }, vertexShaderByteCode);

// Instantiate Vertex buffer from vertex data
var vertices = device.CreateBuffer(new BufferDescription(BindFlags.VertexBuffer), new[]
{
  new Vector4(0.0f, 0.5f, 0.5f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
  new Vector4(0.5f, -0.5f, 0.5f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
  new Vector4(-0.5f, -0.5f, 0.5f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f)
});

var model = new Model();
model.AddMesh(new ModelMesh
{
  IndexBuffer = device.CreateBuffer(new BufferDescription
  {
    BindFlags = BindFlags.IndexBuffer
  }, new uint[] { 0, 1, 2 }),
  IndexCount = 3,
  InputLayout = layout,
  PrimitiveCount = 1,
  PrimitiveTopology = PrimitiveTopology.TriangleList,
  VertexBuffer = vertices,
  VertexCount = 3,
  VertexSize = 32
});

// Prepare all the stages
deviceContext.VertexShader.Shader = vertexShader;
deviceContext.Rasterizer.SetViewports(new Viewport(0, 0, width, height, 0.0f, 1.0f));
deviceContext.PixelShader.Shader = pixelShader;
deviceContext.OutputMerger.SetTargets(null, renderTargetView);

// Render!
deviceContext.ClearRenderTargetView(renderTargetView, Color4.Black);
model.Draw(deviceContext);
deviceContext.Present(swapChain);

That code, along with a little more plumbing code, results in this:

Screenshot

Rasterizr Studio

Rasterizr Studio serves two purposes:

  1. It is a sample browser, showcasing a growing list of Rasterizr samples.
  2. It includes a visual debugger, integrated with the sample browser. When viewing any of the samples, you can pause them and open the current frame in the debugging tools. From there, you can click on a pixel to see the complete pixel history, as well as viewing all the events that make up that frame, and the resources that were used to render that frame. The debugging tools include:
    • Event list
    • Object table
    • Pixel history

Screenshot

Acknowledgements

While writing Rasterizr, I studied the code of several other software rasterizers:

To learn how to implement the rasterizer stage, I read a lot of papers / books / blog posts! Here's a few that I remember:

Rasterizr Studio includes some samples ported from SharpDX. The environment mapping sample was ported from RobyDX's SharpDX demos.

Disclaimer

Rasterizr is not feature-complete. It is a hobby project, and I've only implemented as much as I needed to in order to get the samples working. If you find a bug or missing feature, and you feel like digging into the code, then go for it - I'll probably accept any pull requests. But I don't intend to spend much more time on it myself. 3 years (on and mostly off) is long enough!

License

Rasterizr is released under the MIT License.