Ahora
Vertex, Fragment, Compute
Las declaraciones de autoría existen actualmente. La compilación GPU completa sigue en desarrollo.
Yotsuba Shader es un framework de shaders y un compilador para C#. Escribe shaders con los tipos de tu propio proyecto y las bibliotecas que ya usas, y compila para Spirv y otros formatos con Yotsuba ShaderCross.
Escribe con el vocabulario que tu equipo conoce. Un frontend basado en Roslyn y una representación intermedia compartida lo convierten al formato de shader que espera cada API gráfica, como SPIR-V para Vulkan.
ETAPAS DE SHADER
Vertex, Fragment y Compute están declarados en la API actual; su compilación completa está en desarrollo. Geometry, Hull y Domain están previstos para marzo de 2027.
Ahora
Las declaraciones de autoría existen actualmente. La compilación GPU completa sigue en desarrollo.
Marzo de 2027
Soporte planificado para procesamiento de geometría y teselación en la GPU.
Octubre de 2027
Soporte planificado para los stages programables que hacen extensible el ray tracing.
SPONSORS
Yotsuba Shader es gratis para todos. El patrocinio paga el tiempo que lo mantiene vivo y te da voz sobre cómo se usa ese tiempo.

Vota qué backend o integración viene después y envía ideas de funciones a sponsor-roadmap@yotsubashader.com. Cada $50/mes te da 1 request al año.

Accede al devlog exclusivo para sponsors y a un canal privado para hablar conmigo directamente.

Tu nombre, enlace o logo en la página de Sponsors, el README y la web, además de una mención en los anuncios de versiones importantes.

Los Partners reciben una sesión de integración dedicada para llevar Yotsuba Shader a su entorno.
Patrocinar nunca desbloquea funciones ni cambia la licencia. Todos reciben el mismo código.
Etapas de vertex, fragment y compute, descritas en C# normal. Los tipos de vectores, matrices y texturas de tu proyecto se convierten en tipos nativos de la GPU, y tus shaders pueden apoyarse en bibliotecas externas: no hay un segundo lenguaje que aprender ni tipos duplicados. Si sabes escribir C#, sabes escribir shaders.
Cinco vocabularios de atributos describen conceptos de shaders en C#. Comparten una ruta de salida prevista; la conversión completa está en desarrollo y la salida WGSL sigue planificada.
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)
{
}
}
using YotsubaShader.Language;
using YotsubaShader.GlslSyntax;
using YotsubaShader.GlslSyntax.Resources;
public struct VertexOutput
{
[gl_Position]
public Vector4 Position;
}
public class Triangle
{
[buffer, layout(0, 0)]
public float[] Output;
[ShaderStage(Stage.Vertex)]
public VertexOutput Vertex([gl_VertexIndex] uint id)
{
VertexOutput output = new VertexOutput();
output.Position = new Vector4(0, 0, 0, 1);
return output;
}
[ShaderStage(Stage.Fragment)]
public Vector4 Fragment(VertexOutput input)
{
return new Vector4(1, 0.4f, 0.7f, 1);
}
[ShaderStage(Stage.Compute)]
[layout_local_size(8, 8, 1)]
public void Compute([gl_GlobalInvocationID] UInt3 id)
{
}
}
using YotsubaShader.Language;
using YotsubaShader.MslSyntax;
using YotsubaShader.MslSyntax.Resources;
public struct VertexOutput
{
[position]
public Vector4 Position;
}
public class Triangle
{
[device, buffer(0)]
public float[] Output;
[ShaderStage(Stage.Vertex)]
public VertexOutput Vertex([vertex_id] uint id)
{
VertexOutput output = new VertexOutput();
output.Position = new Vector4(0, 0, 0, 1);
return output;
}
[ShaderStage(Stage.Fragment)]
public Vector4 Fragment(VertexOutput input)
{
return new Vector4(1, 0.4f, 0.7f, 1);
}
// El tamaño del workgroup lo define el host
[ShaderStage(Stage.Compute)]
public void Compute([thread_position_in_grid] UInt3 id)
{
}
}
using YotsubaShader.Language;
using YotsubaShader.SpirvSyntax;
using YotsubaShader.SpirvSyntax.Resources;
public struct VertexOutput
{
[BuiltIn_Position]
public Vector4 Position;
}
public class Triangle
{
[StorageBuffer, DescriptorSet(0), @Binding(0)]
public float[] Output;
[ShaderStage(Stage.Vertex)]
public VertexOutput Vertex([BuiltIn_VertexIndex] uint id)
{
VertexOutput output = new VertexOutput();
output.Position = new Vector4(0, 0, 0, 1);
return output;
}
[ShaderStage(Stage.Fragment)]
public Vector4 Fragment(VertexOutput input)
{
return new Vector4(1, 0.4f, 0.7f, 1);
}
// El tamaño del workgroup lo define el host
[ShaderStage(Stage.Compute)]
public void Compute([BuiltIn_GlobalInvocationId] UInt3 id)
{
}
}
using YotsubaShader.Language;
using YotsubaShader.WgslSyntax;
using YotsubaShader.WgslSyntax.Resources;
public struct VertexOutput
{
[@builtin_position]
public Vector4 Position;
}
public class Triangle
{
[storage(storage_use.read_write), @group(0), @binding(0)]
public float[] Output;
[ShaderStage(Stage.Vertex)]
public VertexOutput Vertex([@builtin_vertex_index] uint id)
{
VertexOutput output = new VertexOutput();
output.Position = new Vector4(0, 0, 0, 1);
return output;
}
[ShaderStage(Stage.Fragment)]
public Vector4 Fragment(VertexOutput input)
{
return new Vector4(1, 0.4f, 0.7f, 1);
}
[ShaderStage(Stage.Compute)]
[@workgroup_size(8, 8, 1)]
public void Compute([@builtin_global_invocation_id] UInt3 id)
{
}
}
El playground ofrece actualmente diagnósticos C# y descubrimiento de shaders. Los diagnósticos de shaders en el IDE y el análisis de compatibilidad por backend están previstos.
El generador existente construye la tabla de instrucciones SPIR-V. Están previstos un generador que compile tus shaders y una CLI de compilación de shaders.
Entradas, salidas, recursos, ubicaciones, bindings y etapas se escriben con atributos, nunca se deducen por convenciones de nombres. Eso permite que el compilador revise un shader mucho antes de que lo vea cualquier controlador.
using Microsoft.Xna.Framework;
using YotsubaShader.HlslSyntax;
using YotsubaShader.HlslSyntax.Resources;
public struct VertexOutput
{
[SV_Position]
public Vector4 Position; // valor integrado
[COLOR]
public Vector4 Color; // pasa a fragment
}
public sealed class Material
{
[cbuffer, register(RegisterPrefix.b, 0)]
public float Exposure;
}
Tus shaders forman parte de tu proyecto de C#, así que comparten sus tipos. Marca con un atributo los vectores, matrices y texturas que ya tienes y se convierten en tipos nativos de la GPU, sin un conjunto paralelo de structs solo para shaders que mantener sincronizado.
// Tu propio tipo, como vector de la GPU
[Vector]
public struct Vector3
{
[VectorComponent(0)] public float X;
[VectorComponent(1)] public float Y;
[VectorComponent(2)] public float Z;
}
// ...y usado directamente por un shader
[ShaderStage(Stage.Vertex)]
public VertexOutput Vertex(
Vector3 position) { /* ... */ }
Compila el repositorio, lee la guía y descubre cómo una clase de C# se convierte en una etapa de shader.
Sin resultados. Prueba con “stage”, “SPIR-V”, “uniform” o “Metal”.