an_editor/shaders/text_atlas.metal

67 lines
1.7 KiB
Metal

#include <metal_stdlib>
using namespace metal;
struct VertexInput {
float2 position;
float2 tex_coord;
};
struct VertexOutput {
float4 position [[position]];
float2 tex_coord;
};
struct Glyph {
float2 atlas_position;
float2 size;
float2 target_position;
float y_offset;
float _haha_alignment;
};
struct UniformParams {
float2 screen_size;
};
float4 to_device_position(float2 position, float2 size) {
return float4(((position / size) * 2.0) - float2(1.0), 1.0, 1.0);
}
vertex VertexOutput
vs_main(
uint vertex_id [[vertex_id]],
uint glyph_id [[instance_id]],
constant VertexInput *vertices [[buffer(0)]],
constant Glyph *glyphs [[buffer(1)]],
constant UniformParams &params [[buffer(2)]]
)
{
VertexOutput out;
Glyph glyph = glyphs[glyph_id];
float2 scaled_size = ((vertices[vertex_id].position + 1.0) / 2.0) * (glyph.size/2.0);
float2 scaled_size_2 = ((vertices[vertex_id].position + 1.0) / 2.0) * (glyph.size);
float2 glyph_pos = scaled_size + glyph.target_position + float2(0, glyph.y_offset/2.0+32);
float4 device_position = to_device_position(glyph_pos, params.screen_size);
float2 atlas_position = (scaled_size_2 + glyph.atlas_position) / 1024.0;
device_position.y = -device_position.y;
out.position = device_position;
out.tex_coord = atlas_position;
return out;
}
fragment float4 fs_main(VertexOutput in [[stage_in]],
texture2d<float, access::sample> texture [[texture(0)]])
{
constexpr sampler texture_sampler (mag_filter::linear, min_filter::linear);
float text_color = texture.sample(texture_sampler, in.tex_coord).r;
return float4(text_color * float3(1,1,1), text_color);
}