struct VertexIn { [[vk::layout(0)]] float2 pos; } struct VertexOut { [[vk::layout(0)]] float4 color; float4 position : SV_Position; } struct PushConstant { float2 screen_size; float2 position; float size; } [[vk::push_constant]] ConstantBuffer push_constant; [shader("vertex")] VertexOut vertex(VertexIn vertex) { VertexOut output; output.position = float4( 2.0 * (push_constant.position.x + vertex.pos.x * push_constant.size) / push_constant.screen_size.x - 1.0, 2.0 * (push_constant.position.y + vertex.pos.y * push_constant.size) / push_constant.screen_size.y - 1.0, 0.0, 1.0, ); output.color = float4(1.0, 1.0, 0.0, 1.0); return output; } struct FragmentOut { float4 color : SV_Target; } [shader("fragment")] FragmentOut fragment(VertexOut input, float3 bary: SV_BARYCENTRICS) { FragmentOut output; output.color = input.color; return output; } struct GlyphDesc { uint vertex_offset; uint index_offset; uint vertex_count; uint index_count; } static const uint SOLID = 0; static const uint CONVEX = 0; static const uint CONCAVE = 0; struct MeshOut { float4 pos : SV_Position; } struct MeshInvocation { uint glyph_id; uint vertex_triangle_offsets; } struct MeshIn { MeshInvocation glyph_id[32]; } struct PrimOut { uint kind : BLENDINDICES0; } [[vk::binding(0)]] StructuredBuffer glyphs; [[vk::binding(1)]] StructuredBuffer glyphs_ids; [shader("mesh")] [numthreads(32, 1, 1)] [outputtopology("triangle")] void mesh(uint3 gid: SV_GroupID, // dispatched group id uint3 tid: SV_GroupThreadID, // global thread id uint ti: SV_GroupIndex, // local group thread index out indices uint3 triangles[126], out vertices MeshOut vertices[64], out primitives PrimOut attr[126], in MeshIn mesh, ) { SetMeshOutputCounts(0, 0); // we have a limited number of verts/triangles we can output // if a glyph exceeds the 126 triangles/64 verts limit, then we need more than // one thread building geometry. // all threads sharing one glyph should be in the same subgroup/wave. } struct FragmentIn2 { float4 pos : SV_Position; sample float3 bary : SV_BARYCENTRICS; uint kind : BLENDINDICES0; } float2 computeUV(const float3 bary) { const float u = bary.x * 0 + bary.y * 0.5f + bary.z * 1; const float v = bary.x * 0 + bary.y * 0.0f + bary.z * 1; return float2(u, v); } float computeQuadraticBezierFunction(const float2 uv) { return uv.x * uv.x - uv.y; } [shader("fragment")] FragmentOut fragment_barycentric(FragmentIn2 input) { const uint kind = input.kind; const float2 uv = computeUV(input.bary); const float sign = computeQuadraticBezierFunction(uv); if ((kind == CONVEX) && sign > 0.0f || (kind == CONCAVE) && sign < 0.0f) { discard; } FragmentOut output; output.color = float4(1.0, 0.0, 0.0, 1.0); return output; }