New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WebGL / Add support for patterns in polygons and lines #15279
Conversation
For clarity; now there is style/flat.js and style/webgl.js
📦 Preview the website for this branch here: https://deploy-preview-15279--ol-site.netlify.app/. |
This is necessary for dashes/symbols to render correctly along the line when an offset is applied. To do this we need to store an additional information for each vertex: the sum of the tangents of the join angles encountered so far. This will then be multiplied by the current line offset in the vertex shader. Did my best ASCII art to try and explain better what is going on in this part of the code.
8712729
to
acc364e
Compare
Nice! It should be easy to add support for fill pattern images to the Canvas 2D renderer. Stroke patterns like this will be a bit harder to support in Canvas 2D, because they need to consider the segment angle, but doable. Regarding the new style properties, I'm wondering if we could get along without |
Good to hear, feature parity would be awesome.
The
@mike-000 could you please tell me on which platform you witnessed this? Thanks a lot!! |
One of the systems mentioned in #13367 (comment) where until now there were no problems with WebGL, only WebGL2. In this case Firefox is also affected. The same ANGLE backend change will fix Chrome and Edge, I am not sure what can be done for Firefox. Results for https://webglreport.com/?v=1 with Chrome default settings (with the issue) and with Angle backend set to |
Thanks @mike-000 I could reproduce the issue (false hit detection + missing fill) using an emulated win10 system running both FF and Chrome; it's not related to this PR though. This looks like an ANGLE-related issue. I will look into this, see if there's anything that can be done on OL side. |
I have seen missing fill in the example in main as well now, so cannot be related to this PR. Both issues can also been seen in the deploy preview for #15121 so probably started with that. Chrome on Android also has the false hit detection issue. |
src/ol/style/webgl.js
Outdated
* @property {ColorExpression} [fill-color] The fill color. | ||
* @property {ColorExpression} [fill-color] Fill color. | ||
* @property {string} [fill-pattern-src] Fill pattern image source URI. If `fill-color` is defined as well, it will be used to tint this image. | ||
* @property {HTMLImageElement|HTMLCanvasElement} [fill-pattern-img] Fill pattern image object. Can be provided as an alternative to `fill-pattern-src`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Accepting an image here is at odds with the goal of parsing styles and preparing attribute buffers in a worker. But we could wait until we are doing that and then deal with this then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Absolutely, and a procedurally-generated image could easily be made into an object URL that could then be read from a worker.
I really went with a conservative approach here and mimicked the existing icon properties (also true for the origin-offset
properties which @ahocevar mentioned). But I'm considering removing the code path for Image
objects entirely, as there's no point in introducing APIs which we know are not aligned with long-term goals anyway.
edit: I thought this was present in the flat style as well but it isn't; I'll get rid of Image
support in WebGL styles in this PR then
* be functions and are made up of simple objects instead of classes. | ||
* @module ol/style/literal | ||
* WebGL style objects slightly differ from standard flat styles for certain properties | ||
* @module ol/style/webgl |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feels like we should work toward having a single place for these types. I think it would be preferable to have a single set of types and then to allow the implementations to differ (or be incomplete) rather than having two sets of types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is definitely what I'm aiming for. Having a separate type for WebGL renderers is helpful to keep track of where we stand and what is the gap between the two style formats, but it's not a situation that we want to keep eternally.
There is still some work to close this gap though, mainly around the concept of rules; I plan on addressing this later on while optimizing the way features are filtered out before rendering in WebGL.
Really impressive work, @jahow. I only left a couple general comments that I'm curious to hear your thoughts on, but think this looks good to go. |
A procedurally-generated image can either be turned into a data url or object url and then fed to the corresponding `*-src` property
@tschaub I added a commit to remove all traces of |
The docs describe the action of |
Yes absolutely, being able to get a translucent pattern is one benefit of the "tinting" behavior. Maybe the doc could clarify that tinting means multiplying colors? |
@jahow That makes sense. Applying |
Options to scale/resize patterns would be useful. For example the Esri feature style linked in #15095 (comment) (reproduced in https://codesandbox.io/s/vector-esri-forked-3ly3ry?file=/main.js) contains a data url for the icon pattern (which produces a 256 x 256 image) in the eastern-most polygon and specifies a smaller (64 pixel) width and height to be used in the pattern This could be specified as
but without support for that the data url would need be to be asynchronously loaded to an image, then scaled in canvas to produce another data url. |
I agree @mike-000, but with the limited resources available we're trying to aim for supporting Mapbox Style features, and the spec does not offer any option for scaling fill patterns. |
This PR adds support for fill and stroke patterns using the following properties of the flat WebGL-specific style:
fill-pattern-src
andfill-pattern-img
fill-pattern-offset
,fill-pattern-offset-origin
andfill-pattern-size
stroke-pattern-src
andstroke-pattern-img
stroke-pattern-offset
,stroke-pattern-offset-origin
andstroke-pattern-size
stroke-pattern-spacing
These properties work the same way as the
icon-
properties, letting the user specify an image either as a pathor an; the offset properties let the user specify a image in a spritesheet.Image
orCanvas
instanceI didn't reproduce the current API which accepts
CanvasPattern
andCanvasGradient
because:Fill pattern
Fill patterns have an origin which can be [0,0] in case of vector layers, or the tile origin in case of vector tiles. Patterns are slightly upscaled/downscaled when zooming to match integer zoom levels:
Fill patterns are tinted by the fill color if specified.
(note: I didn't touch the actual webgl vector example)
Stroke pattern
Stroke patterns are scaled to match the line width. They are tinted by the line color if specified. I also worked on fixing the distance computation along the line when applying an offset; before this PR, the computation was off and symbols were clearly not lining up at the joins. Now the symbols line up, although the interpolation the joins still needs work:
Before:
After:
Note: providing
Canvas
orImage
for fill patterns, stroke patterns or icons is not supported anymore. Use data URLs or object URLs instead.