vidya/crates/renderer/shaders/font.slang
2025-09-20 15:27:21 +02:00

135 lines
2.9 KiB
Plaintext

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<PushConstant> 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<GlyphDesc> glyphs;
[[vk::binding(1)]]
StructuredBuffer<uint> 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;
}