Skip to content

Instantly share code, notes, and snippets.

@cfloisand
Created October 10, 2023 14:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cfloisand/64c5965b6babf6915cf001cef0f3a922 to your computer and use it in GitHub Desktop.
Save cfloisand/64c5965b6babf6915cf001cef0f3a922 to your computer and use it in GitHub Desktop.
bool
are_equal(float a, float b) {
constexpr float epsilon = 0.00001f;
return fabs(a - b) <= epsilon;
}
float
edge_test(float2 p, float2 v0, float2 v1) {
// NOTE(christian): Skip edge testing for edges that are straight horizontal/vertical lines since they don't need anti-aliasing.
if (!are_equal(v0.x, v1.x) && !are_equal(v0.y, v1.y)) {
return (p.x - v0.x) * (v1.y - v0.y) - (p.y - v0.y) * (v1.x - v0.x);
} else {
return FLT_MAX;
}
}
bool
on_edge(float val, float edgeMax) {
return (val >= 0.f && val <= edgeMax);
}
fragment float4 fragment_primitive(VertexOut in [[ stage_in ]],
constant Edges &edges [[ buffer(0) ]],
constant RenderTarget &renderTarget [[ buffer(1) ]])
{
float2 pos = (in.pos.xy / float2(renderTarget.width, renderTarget.height)) * 2.f - 1.f;
pos.y *= -1.f;
float a = in.color.a;
float2 v0 = edges.verts[0];
float2 v1 = edges.verts[1];
float2 v2 = edges.verts[2];
float et0 = edge_test(pos, v0, v1);
float et1 = edge_test(pos, v1, v2);
float et2 = edge_test(pos, v2, v0);
float et = FLT_MAX;
float edgeMax = 0.f;
bool onEdge = false;
if (on_edge(et0, edges.edgeMaximas[0]) && (et0 < et)) {
et = et0;
edgeMax = edges.edgeMaximas[0];
onEdge = true;
}
if (on_edge(et1, edges.edgeMaximas[1]) && (et1 < et)) {
et = et1;
edgeMax = edges.edgeMaximas[1];
onEdge = true;
}
if (on_edge(et2, edges.edgeMaximas[2]) && (et2 < et)) {
et = et2;
edgeMax = edges.edgeMaximas[2];
onEdge = true;
}
if (onEdge) {
a = smoothstep(0.f, edgeMax, et);
}
return float4(in.color.rgb, a);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment