Yotsuba Shader
Documentation

Tutorial

Writing your first shader

Declare vertex inputs and outputs, then write a vertex stage and a fragment stage that pass a color through.

Overview#

This HLSL-style authoring example uses MonoGame types and reuses the vertex output as fragment input. POSITION and COLOR are HLSL user semantics; SV_Position is a built-in, and the return attribute SV_Target(0) identifies the fragment color output.

BasicColorShader.cs
using Microsoft.Xna.Framework;
using YotsubaShader.Language;
using YotsubaShader.HlslSyntax;

public class BasicColorShader
{
    public struct VS_Input
    {
        [POSITION]
        public Vector2 Position;

        [COLOR]
        public Vector4 Color;
    }

    public struct VS_Output
    {
        [SV_Position]
        public Vector4 Position;

        [COLOR]
        public Vector4 Color;
    }

    [ShaderStage(Stage.Vertex)]
    public VS_Output VS(VS_Input input)
    {
        VS_Output output = new VS_Output();

        output.Position = new Vector4(
            input.Position.X,
            input.Position.Y,
            0.0f,
            1.0f
        );

        output.Color = input.Color;

        return output;
    }

    [ShaderStage(Stage.Fragment)]
    [return: SV_Target(0)]
    public Vector4 FS(VS_Output input)
    {
        return input.Color;
    }
}

What happens between stages#

The application supplies positions and colors. The vertex stage writes clip-space position with z = 0 and w = 1 and passes color onward. The rasterizer interpolates color for the fragment stage. The application remains responsible for vertex layout, render targets, pipeline creation, and draw calls.

This is an authoring example, not a successful C#-to-SPIR-V compilation test. MonoGame types without native mapping attributes are treated as ordinary structs by the current processor. Body lowering is still incomplete.

Copyright © 2026 Yotsuba Shader contributors · Licensing · GitHub