Use v_edgeDistance.y to differentiate between PLS strokes and fills Now that we have two coverage components per pixel, it's cleaner to use the second, which is otherwise unused for fills. Diffs= 4587a3d1d Use v_edgeDistance.y to differentiate between PLS strokes and fills (#5582) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com>
diff --git a/.rive_head b/.rive_head index 0362826..35e2648 100644 --- a/.rive_head +++ b/.rive_head
@@ -1 +1 @@ -60296f34fd95019c0dabe33b44a60d0ee6cbd5d5 +4587a3d1d15d1e101240baa22f573a375921461f
diff --git a/renderer/shaders/draw.glsl b/renderer/shaders/draw.glsl index 026be4c..5d0405d 100644 --- a/renderer/shaders/draw.glsl +++ b/renderer/shaders/draw.glsl
@@ -275,8 +275,11 @@ v_edgeDistance.x = make_half(clipDistance); } - // Strokes identify themselves by emitting a negative edgeDistance. - v_edgeDistance *= -globalCoverage; + v_edgeDistance *= globalCoverage; + + // Bias v_edgeDistance.y slightly upwards in order to guarantee v_edgeDistance.y is >= 0 at + // every pixel. "v_edgeDistance.y < 0" is used to differentiate between strokes and fills. + v_edgeDistance.y = max(v_edgeDistance.y, make_half(1e-4)); postTransformVertexOffset = MUL(mat, outset * vertexOffset); @@ -292,7 +295,9 @@ // Offset the vertex for Manhattan AA. postTransformVertexOffset = sign(MUL(mat, outset * norm)) * AA_RADIUS; - v_edgeDistance = make_half2(fillCoverage, 1); + + // "v_edgeDistance.y < 0" indicates to the fragment shader that this is a fill. + v_edgeDistance = make_half2(fillCoverage, -1); // If we're actually just drawing a triangle, throw away the entire patch except a single // fan triangle. @@ -483,21 +488,18 @@ #ifdef @DRAW_INTERIOR_TRIANGLES coverageCount += v_windingWeight; #else - // TODO: We may need to just send actual flags instead of using sign(edgeDistance) to identify - // strokes. Since edgeDistance is interpolated, it can sometimes cross signs. - half d = v_edgeDistance.x; - if (d < -1e-4 /*stroke with an intentionally negative edgeDistance*/) - coverageCount = min(max(d, v_edgeDistance.y), coverageCount); + if (v_edgeDistance.y >= .0 /*stroke*/) + coverageCount = max(min(v_edgeDistance.x, v_edgeDistance.y), coverageCount); else if (_clockwise /*clockwise fill*/) - coverageCount += d; + coverageCount += v_edgeDistance.x; else /*counterclockwise fill*/ - coverageCount -= d; + coverageCount -= v_edgeDistance.x; // Save the updated coverage. PLS_STORE2F(coverageCountBuffer, v_pathID, coverageCount); #endif - // Convert coverageCount to coverage. (Which is min(-edgeDistance) right now for strokes.) + // Convert coverageCount to coverage. half coverage = abs(coverageCount); #ifdef @ENABLE_EVEN_ODD if (v_pathID < .0 /*even-odd*/)