Description
Describe the bug
A clear and concise description of what the bug is.
I previously requested a 'stroke-pattern-start-offset' option in webgl.
#15944
There is also an issue with the WebGL renderer in OpenLayers when using stroke-pattern-spacing in LiteralStyle.
Specifically, when two different spacing values for 'stroke-pattern-spacing' (e.g. 40 and 80) are applied to the same style, the alignment between patterns becomes inconsistent.
This causes rendering errors for stroke patterns.
class WebGLVectorTileLayer extends VectorTile {
createRenderer() {
return new WebGLVectorTileLayerRenderer(this, {
className: this.getClassName(),
style: [{
'stroke-pattern-src': 'bar.png',
'stroke-width': 5,
'stroke-offset': 0,
'stroke-pattern-start-offset':20,
'stroke-pattern-spacing': 40,
},
{
'stroke-pattern-src': 'circle1.png',
'stroke-width': 5,
'stroke-offset': 0,
'stroke-pattern-start-offset':17,
'stroke-pattern-spacing': 80,
},
{
'stroke-pattern-src': 'circle2.png',
'stroke-width': 5,
'stroke-offset': 0,
'stroke-pattern-start-offset':23,
'stroke-pattern-spacing': 80,
}],
});
}
}
The style with an interval of 40 should match the style with an interval of 80 for the second time, but an error occurs.
So I checked that the style with an interval of 40 matches the interval of 80 for the second time when I changed it to 37.5.
This is the result when the image width is 5, and if the width of the image changes, the interval will have an error again.
So at first, I tried to compensate for the error value, but then I changed it to calculate the interval regardless of the image size.
let startOffsetExpression = '0.';
if ('stroke-pattern-start-offset' in style) {
startOffsetExpression = expressionToGlsl(
fragContext,
style['stroke-pattern-start-offset'],
NumberType,
);
}
fragContext.functions['sampleStrokePattern'] =
`vec4 sampleStrokePattern(sampler2D texture, vec2 textureSize, vec2 textureOffset, vec2 sampleSize, float spacingPx, float startOffsetPx, float currentLengthPx, float currentRadiusRatio, float lineWidth) {
float currentLengthScaled = currentLengthPx * sampleSize.y / lineWidth;
float spacingScaled = spacingPx * sampleSize.y / lineWidth;
float uCoordPx = mod(currentLengthScaled + startOffsetPx, spacingScaled);
// make sure that we're not sampling too close to the borders to avoid interpolation with outside pixels
uCoordPx = clamp(uCoordPx, 0.5, sampleSize.x - 0.5);
if (uCoordPx > sampleSize.x - 1.0) {
return vec4(0.0);
}
float vCoordPx = (0.5 - currentRadiusRatio * 0.5) * sampleSize.y;
vec2 texCoord = (vec2(uCoordPx, vCoordPx) + textureOffset) / textureSize;
return samplePremultiplied(texture, texCoord);
}`;
const textureName = `u_texture${textureId}`;
let tintExpression = '1.';
if ('stroke-color' in style) {
tintExpression = builder.getStrokeColorExpression();
}
builder.setStrokeColorExpression(
`${tintExpression} * sampleStrokePattern(${textureName}, ${sizeExpression}, ${offsetExpression}, ${sampleSizeExpression}, ${spacingExpression}, ${startOffsetExpression}, currentLengthPx, currentRadiusRatio, v_width)`,
);
}
The desired result was obtained as follows.
The issue was confirmed in 'stroke-line-dash'.
If there are no other issues with the code I wrote, please reflect it.
Thank you for solving the issue related to the filter related to 'geometry-type' that I wrote before.
#15805
To Reproduce
Steps to reproduce the behavior:
- Go to '...'
- Click on '....'
- See error
Expected behavior
A clear and concise description of what you expected to happen.