Yotsuba Shader
Documentation

Article

Choosing a syntax

The HLSL, GLSL, MSL, SPIR-V and WGSL syntaxes express the same intent. Pick the one your team knows.

Overview#

The five examples below are the same shader: a vertex and a fragment stage, plus a compute stage that writes to a storage buffer. Only the attribute names change. Switch between them with the tabs, or with the Syntax menu at the top of the page; your choice is remembered across the documentation.

One package per syntax#

Each syntax is its own package with a namespace of the same name: YotsubaShader.HlslSyntax, YotsubaShader.GlslSyntax, YotsubaShader.MslSyntax, YotsubaShader.SpirvSyntax and YotsubaShader.WgslSyntax. Resource attributes live in its .Resources namespace, for example YotsubaShader.HlslSyntax.Resources. They reference YotsubaShader.Language for stage and native-type annotations and YotsubaShader.Concepts for shared concepts. Locations and resource attributes are supplied by syntax namespaces. Engines and frameworks build on that core; add only the syntax you write with.

The same shader in five syntaxes#

Triangle.cs
using YotsubaShader.Language;
using YotsubaShader.HlslSyntax;
using YotsubaShader.HlslSyntax.Resources;

public struct VertexOutput
{
    [SV_Position]
    public Vector4 Position;
}

public class Triangle
{
    [register(RegisterPrefix.u, 0)]
    public RWStructuredBuffer<float> Output;

    [ShaderStage(Stage.Vertex)]
    public VertexOutput Vertex([SV_VertexID] uint id)
    {
        VertexOutput output = new VertexOutput();
        output.Position = new Vector4(0, 0, 0, 1);
        return output;
    }

    [ShaderStage(Stage.Fragment)]
    [return: SV_Target(0)]
    public Vector4 Fragment(VertexOutput input)
    {
        return new Vector4(1, 0.4f, 0.7f, 1);
    }

    [ShaderStage(Stage.Compute)]
    [numthreads(8, 8, 1)]
    public void Compute([SV_DispatchThreadID] UInt3 id)
    {
    }
}

These names deliberately resemble their source languages. In C#, WGSL-inspired attributes use @ in the identifier, as in [@builtin_position], while remaining valid C#.

Resources in five syntaxes#

Uniform buffers and binding slots follow the same pattern.

Lighting.cs
using YotsubaShader.HlslSyntax;
using YotsubaShader.HlslSyntax.Resources;

public class Lighting
{
    [cbuffer]
    [register(RegisterPrefix.b, 0)]
    public Material Material;
}

The shared [Uniform], [StorageBuffer] and [Binding] attributes in YotsubaShader.Language work in every syntax as well.

Which one should I pick?#

  • Your team already knows a shading language: use its syntax. Nothing in the IR depends on the syntax.
  • You target a single API: the matching syntax reads most naturally (MSL for Metal, SPIR-V for Vulkan), but it is a convenience, not a requirement.
  • You are starting fresh: the HLSL syntax is a good first choice. The relationship between stages, inputs, position and fragment color is easy to see.

Equivalence#

Each syntax is meant to be semantically equivalent to the others. The frontend already maps the position and vertex-index attributes of all five syntaxes to the same IR built-ins. See the full table in Built-in values across syntaxes.

Copyright © 2026 Yotsuba Shader contributors · Licensing · GitHub