@deck.gl/extensions 9.4.0-beta.1 → 9.4.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +1281 -120
- package/dist/fill-style/fill-style-extension.d.ts +38 -6
- package/dist/fill-style/fill-style-extension.d.ts.map +1 -1
- package/dist/fill-style/fill-style-extension.js +88 -10
- package/dist/fill-style/fill-style-extension.js.map +1 -1
- package/dist/fill-style/procedural-pattern.d.ts +65 -0
- package/dist/fill-style/procedural-pattern.d.ts.map +1 -0
- package/dist/fill-style/procedural-pattern.js +135 -0
- package/dist/fill-style/procedural-pattern.js.map +1 -0
- package/dist/fill-style/shader-module.d.ts +13 -4
- package/dist/fill-style/shader-module.d.ts.map +1 -1
- package/dist/fill-style/shader-module.js +212 -21
- package/dist/fill-style/shader-module.js.map +1 -1
- package/dist/index.cjs +886 -2702
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/mask/shader-module.d.ts +1 -0
- package/dist/mask/shader-module.d.ts.map +1 -1
- package/dist/path-style/path-style-extension.d.ts +49 -6
- package/dist/path-style/path-style-extension.d.ts.map +1 -1
- package/dist/path-style/path-style-extension.js +237 -37
- package/dist/path-style/path-style-extension.js.map +1 -1
- package/dist/path-style/shaders.glsl.d.ts +30 -1
- package/dist/path-style/shaders.glsl.d.ts.map +1 -1
- package/dist/path-style/shaders.glsl.js +136 -21
- package/dist/path-style/shaders.glsl.js.map +1 -1
- package/dist/terrain/shader-module.d.ts +1 -0
- package/dist/terrain/shader-module.d.ts.map +1 -1
- package/dist.min.js +377 -98
- package/package.json +7 -7
- package/src/fill-style/fill-style-extension.ts +135 -13
- package/src/fill-style/procedural-pattern.ts +203 -0
- package/src/fill-style/shader-module.ts +233 -23
- package/src/index.ts +10 -1
- package/src/path-style/path-style-extension.ts +350 -44
- package/src/path-style/shaders.glsl.ts +268 -27
|
@@ -2,12 +2,40 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Dash shader injections for PathLayer, ScatterplotLayer and TextBackgroundLayer.
|
|
7
|
+
*
|
|
8
|
+
* PathLayer dash math crosses three coordinate spaces:
|
|
9
|
+
*
|
|
10
|
+
* 1. **Common space** — the private metric updater accumulates distance over normalized
|
|
11
|
+
* PathTessellator geometry, and `instanceDashOffsets` carries it to the shader. The public
|
|
12
|
+
* scalar `getDashOffsets` helper remains available for compatibility but does not back the
|
|
13
|
+
* managed attribute.
|
|
14
|
+
* 2. **Screen pixels** — the common basis for reconciling flat and billboard extrusion.
|
|
15
|
+
* At the dash injection point, `width` is in common units for a flat path but pixels for
|
|
16
|
+
* a billboarded path, whose conversion also includes `project.focalDistance`.
|
|
17
|
+
* `dashWidthPixels` is correct in both branches.
|
|
18
|
+
* 3. **Half-widths along the path** — the units of `vPathPosition.y`, tested by the fragment
|
|
19
|
+
* shader. One unit spans `dashWidthPixels` screen pixels.
|
|
20
|
+
*
|
|
21
|
+
* Convert explicitly whenever a value crosses these spaces. Mixing them directly makes dash
|
|
22
|
+
* period or phase depend on billboard, elevation, or offset configuration.
|
|
23
|
+
*/
|
|
5
24
|
export type Defines = {
|
|
6
25
|
// Defines passed externally
|
|
7
26
|
/**
|
|
8
27
|
* Enable high precision dash rendering.
|
|
9
28
|
*/
|
|
10
29
|
HIGH_PRECISION_DASH?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Set whenever the dash shaders are injected, so that the offset shaders can adjust dash
|
|
32
|
+
* varyings only when they actually exist.
|
|
33
|
+
*/
|
|
34
|
+
DASH_ENABLED?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Set when PathStyleExtension offset shaders remap the path-width coordinate.
|
|
37
|
+
*/
|
|
38
|
+
PATH_STYLE_OFFSET?: boolean;
|
|
11
39
|
};
|
|
12
40
|
|
|
13
41
|
export const dashShaders = {
|
|
@@ -15,18 +43,78 @@ export const dashShaders = {
|
|
|
15
43
|
'vs:#decl': `
|
|
16
44
|
in vec2 instanceDashArrays;
|
|
17
45
|
#ifdef HIGH_PRECISION_DASH
|
|
18
|
-
in
|
|
46
|
+
// [distance from the start of the path, total length of the path], in common space.
|
|
47
|
+
in vec2 instanceDashOffsets;
|
|
19
48
|
#endif
|
|
20
49
|
out vec2 vDashArray;
|
|
21
50
|
out float vDashOffset;
|
|
51
|
+
out float vDashPathLength;
|
|
52
|
+
|
|
53
|
+
// Also declared in the fragment stage. The vertex stage needs dashAlignMode so that it can
|
|
54
|
+
// reduce the dash phase modulo the same period the fragment stage will test against, and
|
|
55
|
+
// dashUnits to scale the dash array into that period's units.
|
|
56
|
+
layout(std140) uniform pathStyleUniforms {
|
|
57
|
+
float dashAlignMode;
|
|
58
|
+
bool dashGapPickable;
|
|
59
|
+
highp int dashUnits;
|
|
60
|
+
} pathStyle;
|
|
22
61
|
`,
|
|
23
62
|
|
|
24
63
|
'vs:#main-end': `
|
|
25
|
-
|
|
64
|
+
// How many screen pixels one unit of vPathPosition.y covers. The two extrusion branches of
|
|
65
|
+
// the path layer leave this in different units, and both differences have to be undone here
|
|
66
|
+
// for a billboarded path to dash like a flat one.
|
|
67
|
+
//
|
|
68
|
+
// Flat paths extrude in common space, so \`width\` is in common units and a unit of
|
|
69
|
+
// vPathPosition.y is width.x * project.scale pixels.
|
|
70
|
+
//
|
|
71
|
+
// Billboarded paths extrude in clip space, so \`width\` is already in pixels at this point -
|
|
72
|
+
// the clip-space conversion happens inside getLineJoinOffset. That conversion also folds in
|
|
73
|
+
// project.focalDistance, which scales the half-width the segment delta is divided by but not
|
|
74
|
+
// the delta itself, so a unit of vPathPosition.y ends up focalDistance pixels wider than the
|
|
75
|
+
// stroke it is supposed to be relative to.
|
|
76
|
+
float dashWidthPixels = path.billboard
|
|
77
|
+
? width.x * project.focalDistance
|
|
78
|
+
: width.x * project.scale;
|
|
79
|
+
|
|
80
|
+
// The actual half stroke width on screen, which is what 'widths' is relative to. It differs
|
|
81
|
+
// from dashWidthPixels by exactly the spurious focalDistance above, so expressing 'widths'
|
|
82
|
+
// as a ratio of the two corrects the billboard case onto the flat one - getDashArray is
|
|
83
|
+
// documented relative to the stroke, and flat paths already honor that.
|
|
84
|
+
float strokeHalfWidthPixels = path.billboard ? width.x : width.x * project.scale;
|
|
85
|
+
|
|
86
|
+
// Everything reduces to "how many screen pixels is one dash unit", divided through by the
|
|
87
|
+
// pixels per unit of vPathPosition.y, so the fragment shader needs no notion of units at all.
|
|
88
|
+
// Keep the cases in sync with DASH_UNITS in path-style-extension.ts.
|
|
89
|
+
float dashUnitPixels = strokeHalfWidthPixels;
|
|
90
|
+
if (pathStyle.dashUnits == 1) {
|
|
91
|
+
dashUnitPixels = 1.0;
|
|
92
|
+
} else if (pathStyle.dashUnits == 2) {
|
|
93
|
+
dashUnitPixels = project_size_to_pixel(1.0);
|
|
94
|
+
} else if (pathStyle.dashUnits == 3) {
|
|
95
|
+
dashUnitPixels = project.scale;
|
|
96
|
+
}
|
|
97
|
+
vDashArray = instanceDashArrays * (dashUnitPixels / dashWidthPixels);
|
|
98
|
+
|
|
26
99
|
#ifdef HIGH_PRECISION_DASH
|
|
27
|
-
|
|
100
|
+
// instanceDashOffsets accumulates common-space distance on the CPU. Convert it to pixels, then
|
|
101
|
+
// divide by the pixel half-width so both extrusion branches use the same dash coordinate.
|
|
102
|
+
vec2 dashOffsetAndLength = (instanceDashOffsets * project.scale) / dashWidthPixels;
|
|
103
|
+
vDashPathLength = dashOffsetAndLength.y;
|
|
104
|
+
|
|
105
|
+
// Reduce the phase into the first period here rather than in the fragment shader. On a long
|
|
106
|
+
// path at high zoom the raw offset reaches into the millions, and adding the much smaller
|
|
107
|
+
// vPathPosition.y to it in fp32 loses the latter entirely, freezing the pattern mid-segment.
|
|
108
|
+
// The dash function is periodic, so this discards nothing - but it has to be reduced modulo
|
|
109
|
+
// whichever period the fragment stage will actually test against, hence dashAlignMode here.
|
|
110
|
+
float dashUnitLength = vDashArray.x + vDashArray.y;
|
|
111
|
+
float dashPeriod = pathStyle.dashAlignMode == 0.0
|
|
112
|
+
? dashUnitLength
|
|
113
|
+
: vDashPathLength / max(round(vDashPathLength / max(dashUnitLength, 0.0001)), 1.0);
|
|
114
|
+
vDashOffset = dashPeriod > 0.0 ? mod(dashOffsetAndLength.x, dashPeriod) : 0.0;
|
|
28
115
|
#else
|
|
29
116
|
vDashOffset = 0.0;
|
|
117
|
+
vDashPathLength = 0.0;
|
|
30
118
|
#endif
|
|
31
119
|
`,
|
|
32
120
|
|
|
@@ -34,10 +122,44 @@ vDashOffset = 0.0;
|
|
|
34
122
|
layout(std140) uniform pathStyleUniforms {
|
|
35
123
|
float dashAlignMode;
|
|
36
124
|
bool dashGapPickable;
|
|
125
|
+
highp int dashUnits;
|
|
37
126
|
} pathStyle;
|
|
38
127
|
|
|
39
128
|
in vec2 vDashArray;
|
|
40
129
|
in float vDashOffset;
|
|
130
|
+
in float vDashPathLength;
|
|
131
|
+
|
|
132
|
+
// Integral of the dash square wave from 0 to position, i.e. how much solid stroke lies before it.
|
|
133
|
+
float dashPatternIntegral(float position, float solidLength, float unitLength) {
|
|
134
|
+
return floor(position / unitLength) * solidLength +
|
|
135
|
+
min(mod(position, unitLength), solidLength);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Fraction of the filter-width interval centered on position that is covered by solid stroke.
|
|
139
|
+
//
|
|
140
|
+
// Testing the dash pattern with a single comparison per fragment aliases as soon as one
|
|
141
|
+
// period approaches one pixel: the stroke breaks into moire or, when the phase happens to
|
|
142
|
+
// land inside a dash, reads as solid. Integrating the wave over the fragment footprint
|
|
143
|
+
// instead is the closed form of what a mipmapped dash texture approximates, and it degrades
|
|
144
|
+
// the way one wants - once a period drops below a pixel the result converges on the duty
|
|
145
|
+
// cycle solidLength / unitLength, so the stroke fades to a uniformly lighter line.
|
|
146
|
+
//
|
|
147
|
+
// position is reduced into the first period first. The integral satisfies
|
|
148
|
+
// F(position + periodIndex * unitLength) = F(position) + periodIndex * solidLength,
|
|
149
|
+
// so the same periodIndex cancels out of the
|
|
150
|
+
// difference below, and keeping the arguments small avoids subtracting two large nearly
|
|
151
|
+
// equal numbers in fp32 on long paths.
|
|
152
|
+
float dashPatternCoverage(
|
|
153
|
+
float position,
|
|
154
|
+
float solidLength,
|
|
155
|
+
float unitLength,
|
|
156
|
+
float filterWidth
|
|
157
|
+
) {
|
|
158
|
+
float halfFilter = 0.5 * filterWidth;
|
|
159
|
+
float reducedPosition = mod(position, unitLength);
|
|
160
|
+
return (dashPatternIntegral(reducedPosition + halfFilter, solidLength, unitLength) -
|
|
161
|
+
dashPatternIntegral(reducedPosition - halfFilter, solidLength, unitLength)) / filterWidth;
|
|
162
|
+
}
|
|
41
163
|
`,
|
|
42
164
|
|
|
43
165
|
// if given position is in the gap part of the dashed line
|
|
@@ -49,41 +171,131 @@ in float vDashOffset;
|
|
|
49
171
|
// 1 - stretch to fit, draw half dash at each end for nicer joints
|
|
50
172
|
// o-- ---- ---- ---- --o-- --o-- ---- --o
|
|
51
173
|
'fs:#main-start': `
|
|
174
|
+
float dashCoverage = 1.0;
|
|
175
|
+
bool shouldDiscardDash = false;
|
|
176
|
+
bool inRoundedDashGap = false;
|
|
177
|
+
float roundedDashResolvedCoverage = 1.0;
|
|
178
|
+
float roundedDashSubPixelBlend = 0.0;
|
|
179
|
+
float roundedDashDutyCycle = 1.0;
|
|
180
|
+
|
|
52
181
|
float solidLength = vDashArray.x;
|
|
53
182
|
float gapLength = vDashArray.y;
|
|
54
183
|
float unitLength = solidLength + gapLength;
|
|
55
184
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (unitLength > 0.0) {
|
|
185
|
+
if (unitLength > 0.0 && gapLength > 0.0) {
|
|
186
|
+
float offset;
|
|
59
187
|
if (pathStyle.dashAlignMode == 0.0) {
|
|
60
188
|
offset = vDashOffset;
|
|
61
189
|
} else {
|
|
62
|
-
|
|
190
|
+
// Justified: stretch the period so a whole number of them spans the run, and start
|
|
191
|
+
// half a dash in so both ends finish on a joint. Rounding up to at least one period
|
|
192
|
+
// matters - a run shorter than half a period used to round to zero, which made
|
|
193
|
+
// unitLength infinite and rendered it solid.
|
|
194
|
+
#ifdef HIGH_PRECISION_DASH
|
|
195
|
+
// Justify across the entire path rather than each segment separately, so the gaps stay
|
|
196
|
+
// even instead of being stretched by a different amount on every segment. vDashOffset
|
|
197
|
+
// already carries the distance to the start of this segment, reduced modulo this same
|
|
198
|
+
// period in the vertex shader.
|
|
199
|
+
unitLength = vDashPathLength / max(round(vDashPathLength / unitLength), 1.0);
|
|
200
|
+
#else
|
|
201
|
+
unitLength = vPathLength / max(round(vPathLength / unitLength), 1.0);
|
|
202
|
+
#endif
|
|
203
|
+
// A short segment or path can make the fitted period shorter than the requested dash.
|
|
204
|
+
// Bound the solid interval to that period so coverage and duty cycle remain valid.
|
|
205
|
+
solidLength = min(solidLength, unitLength);
|
|
63
206
|
offset = solidLength / 2.0;
|
|
207
|
+
#ifdef HIGH_PRECISION_DASH
|
|
208
|
+
offset += vDashOffset;
|
|
209
|
+
#endif
|
|
64
210
|
}
|
|
65
211
|
|
|
66
|
-
float
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
212
|
+
float alongPath = vPathPosition.y + offset;
|
|
213
|
+
float unitOffset = mod(alongPath, unitLength);
|
|
214
|
+
float filterWidth = max(fwidth(alongPath), 0.0001);
|
|
215
|
+
|
|
216
|
+
// Picking stays a hard in-or-out test. A blended picking colour decodes to the wrong
|
|
217
|
+
// index, and dashGapPickable is defined in terms of whole gaps rather than coverage.
|
|
218
|
+
if (bool(picking.isActive)) {
|
|
219
|
+
bool inGap = unitOffset > solidLength;
|
|
220
|
+
// Only measure the rounded end-cap distance after the hard interval test has found a
|
|
221
|
+
// gap. Inside a solid interval the longitudinal distance is negative; taking its
|
|
222
|
+
// vector length would turn it positive and incorrectly discard the middle of a dash.
|
|
223
|
+
if (inGap && path.capType > 0.5) {
|
|
224
|
+
inGap = length(vec2(
|
|
76
225
|
min(unitOffset - solidLength, unitLength - unitOffset),
|
|
77
226
|
vPathPosition.x
|
|
78
|
-
));
|
|
79
|
-
if (distToEnd > 1.0) {
|
|
80
|
-
if (!(pathStyle.dashGapPickable && bool(picking.isActive))) {
|
|
81
|
-
discard;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
227
|
+
)) > 1.0;
|
|
84
228
|
}
|
|
229
|
+
if (inGap && !pathStyle.dashGapPickable) {
|
|
230
|
+
shouldDiscardDash = true;
|
|
231
|
+
}
|
|
232
|
+
} else if (path.capType <= 0.5) {
|
|
233
|
+
dashCoverage = dashPatternCoverage(alongPath, solidLength, unitLength, filterWidth);
|
|
234
|
+
} else {
|
|
235
|
+
// Rounded caps: the dash end is an arc, so resolve the 2D distance to the nearer solid
|
|
236
|
+
// end rather than the 1D position along the path. Only filter fragments in the gap;
|
|
237
|
+
// PathLayer already antialiases the ordinary sides of the solid stroke.
|
|
238
|
+
float distanceAlongGap = min(unitOffset - solidLength, unitLength - unitOffset);
|
|
239
|
+
// Clamp before taking the derivative so the distance stays continuous across the
|
|
240
|
+
// wrapped period boundary. Evaluate fwidth for every fragment in the quad; derivatives
|
|
241
|
+
// are undefined inside the non-uniform gap branch below.
|
|
242
|
+
float distanceToEnd = length(vec2(max(distanceAlongGap, 0.0), vPathPosition.x));
|
|
243
|
+
float capEdgePixels = (1.0 - distanceToEnd) / max(fwidth(distanceToEnd), 1e-6);
|
|
244
|
+
if (distanceAlongGap > 0.0) {
|
|
245
|
+
inRoundedDashGap = true;
|
|
246
|
+
roundedDashResolvedCoverage = smoothedge(0.0, capEdgePixels);
|
|
247
|
+
dashCoverage = roundedDashResolvedCoverage;
|
|
248
|
+
}
|
|
249
|
+
// That smoothstep resolves one dash end at a time, so it stops meaning anything once a
|
|
250
|
+
// whole period fits inside the filter footprint. Start fading only at that boundary;
|
|
251
|
+
// blending resolvable periods would attenuate the solid body of every rounded dash.
|
|
252
|
+
float subPixelBlend = smoothstep(unitLength, 2.0 * unitLength, filterWidth);
|
|
253
|
+
roundedDashSubPixelBlend = subPixelBlend;
|
|
254
|
+
// At sub-pixel scale, preserve the area of the repeated capsule rather than falling
|
|
255
|
+
// back to the rectangular duty cycle. Each scanline contains the solid body plus the
|
|
256
|
+
// two circular cap intrusions, capped when neighboring caps overlap across the gap.
|
|
257
|
+
float boundedSolidLength = min(solidLength, unitLength);
|
|
258
|
+
float effectiveGap = max(unitLength - boundedSolidLength, 0.0);
|
|
259
|
+
float capSpan = 2.0 * sqrt(max(1.0 - vPathPosition.x * vPathPosition.x, 0.0));
|
|
260
|
+
float roundedDutyCycle = clamp(
|
|
261
|
+
(boundedSolidLength + min(effectiveGap, capSpan)) / unitLength,
|
|
262
|
+
0.0,
|
|
263
|
+
1.0
|
|
264
|
+
);
|
|
265
|
+
roundedDashDutyCycle = roundedDutyCycle;
|
|
266
|
+
dashCoverage = mix(dashCoverage, roundedDutyCycle, subPixelBlend);
|
|
85
267
|
}
|
|
268
|
+
|
|
269
|
+
dashCoverage = clamp(dashCoverage, 0.0, 1.0);
|
|
270
|
+
// Fully transparent fragments would still write depth and occlude whatever is behind.
|
|
271
|
+
shouldDiscardDash = shouldDiscardDash || dashCoverage <= 0.0;
|
|
272
|
+
}
|
|
273
|
+
`,
|
|
274
|
+
|
|
275
|
+
'fs:#main-end': `
|
|
276
|
+
// PathLayer computes analytic-edge derivatives in its fragment body. A discard in
|
|
277
|
+
// #main-start can remove helper invocations and make those derivatives undefined, so all
|
|
278
|
+
// dash-related termination is deferred until the layer has completed that work.
|
|
279
|
+
#ifdef ANTIALIASING
|
|
280
|
+
if (inRoundedDashGap) {
|
|
281
|
+
// The rounded dash cap and PathLayer silhouette are two geometric constraints on the
|
|
282
|
+
// same fragment. Intersect their coverage instead of multiplying two edge ramps; at the
|
|
283
|
+
// cap/body shoulder both ramps are half covered and multiplication would create a dark
|
|
284
|
+
// quarter-covered notch. Keep the sub-pixel duty cycle separable from the path silhouette.
|
|
285
|
+
float pathCoverage = smoothedge(0.0, edgePixels);
|
|
286
|
+
float resolvedCapMultiplier =
|
|
287
|
+
min(pathCoverage, roundedDashResolvedCoverage) / max(pathCoverage, 1e-6);
|
|
288
|
+
dashCoverage = mix(
|
|
289
|
+
resolvedCapMultiplier,
|
|
290
|
+
roundedDashDutyCycle,
|
|
291
|
+
roundedDashSubPixelBlend
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
#endif
|
|
295
|
+
if (shouldDiscardDash) {
|
|
296
|
+
discard;
|
|
86
297
|
}
|
|
298
|
+
fragColor.a *= dashCoverage;
|
|
87
299
|
`
|
|
88
300
|
}
|
|
89
301
|
};
|
|
@@ -316,13 +528,42 @@ in float instanceOffsets;
|
|
|
316
528
|
vPathPosition.x = (vPathPosition.x + offsetDir) * offsetWidth - offsetDir;
|
|
317
529
|
vPathPosition.y *= offsetWidth;
|
|
318
530
|
vPathLength *= offsetWidth;
|
|
531
|
+
#ifdef DASH_ENABLED
|
|
532
|
+
// DECKGL_FILTER_SIZE above widened the stroke by offsetWidth, so these rescalings restore
|
|
533
|
+
// units of the original half-width. The dash block merges ahead of this one.
|
|
534
|
+
if (pathStyle.dashUnits != 0) {
|
|
535
|
+
// Absolute dash units must not inherit the artificial width used to build offset
|
|
536
|
+
// geometry. Relative 'widths' units intentionally remain tied to the original stroke.
|
|
537
|
+
vDashArray *= offsetWidth;
|
|
538
|
+
}
|
|
539
|
+
vPathBounds *= offsetWidth;
|
|
540
|
+
#ifdef HIGH_PRECISION_DASH
|
|
541
|
+
vDashPathLength *= offsetWidth;
|
|
542
|
+
// The dash block reduced the CPU path offset modulo a period expressed in widened-width
|
|
543
|
+
// units. Multiplying that remainder cannot recover the original phase after wrapping, so
|
|
544
|
+
// redo the reduction with both the restored path offset and restored justified period.
|
|
545
|
+
float restoredDashUnitLength = vDashArray.x + vDashArray.y;
|
|
546
|
+
float restoredDashPeriod = pathStyle.dashAlignMode == 0.0
|
|
547
|
+
? restoredDashUnitLength
|
|
548
|
+
: vDashPathLength /
|
|
549
|
+
max(round(vDashPathLength / max(restoredDashUnitLength, 0.0001)), 1.0);
|
|
550
|
+
vDashOffset = restoredDashPeriod > 0.0
|
|
551
|
+
? mod(dashOffsetAndLength.x * offsetWidth, restoredDashPeriod)
|
|
552
|
+
: 0.0;
|
|
553
|
+
#else
|
|
554
|
+
vDashOffset *= offsetWidth;
|
|
555
|
+
#endif
|
|
556
|
+
#endif
|
|
319
557
|
`,
|
|
320
|
-
'fs:#main-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
558
|
+
'fs:#main-end': `
|
|
559
|
+
#ifndef ANTIALIASING
|
|
560
|
+
// With analytic antialiasing, PathLayer evaluates this boundary using the remapped
|
|
561
|
+
// vPathPosition and retains the complete centered coverage ramp. The hard clip remains for
|
|
562
|
+
// the original non-AA path.
|
|
563
|
+
if (abs(vPathPosition.x) > 1.0) {
|
|
324
564
|
discard;
|
|
325
565
|
}
|
|
566
|
+
#endif
|
|
326
567
|
`
|
|
327
568
|
}
|
|
328
569
|
};
|