Skip to content

Introduce line-trim-offset paint property #11570

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

Merged
merged 17 commits into from
Apr 6, 2022
Merged

Conversation

zmiao
Copy link
Contributor

@zmiao zmiao commented Mar 7, 2022

Launch Checklist

In order to realize the vanishing route line effects(traveled part of the route will be marked as transparent), the styled line needs to be constantly updated along with the puck location, in case complexed line property such line-gradient is in use, it will be expensive to constantly parse and evaluate the expressions. In order to avoid this, the line-trim-offset is introduced, instead of passing the expression, a single percentage number is all we need. And as long as line-gradient is the same, there is no need to upload a new texture image and we directly mark the line part within trim-offset-range to be transparent. As a result, the performance will be improved vs constantly updating new line-gradient expressions.

line-trim-offset will be a paint property that will only be effective when line-gradient is set. The basic format could be as the following, which means between route starting point to the trim offset the route will be styled as transparent instead of pre-defined line-gradient color :

{"line-trim-offset", [start, end]}

Thanks for @endanke's help with making this work on the shader side.

  • briefly describe the changes in this PR
  • include before/after visuals or gifs if this PR includes visual changes
  • write tests for all new functionality
  • document any changes to public APIs
  • post benchmark scores
  • manually test the debug page
  • tagged @mapbox/map-design-team @mapbox/static-apis if this PR includes style spec API or visual changes
  • tagged @mapbox/gl-native if this PR includes shader changes or needs a native port
  • apply changelog label ('bug', 'feature', 'docs', etc) or use the label 'skip changelog'
  • add an entry inside this element for inclusion in the mapbox-gl-js changelog: <changelog>Introduce a new line layer paint property '{"line-trim-offset", [trim-start, trim-end]}', the property will only be effective when 'line-gradient' property is set. The line part between [trim-start, trim-end] will be marked as transparent to make a line gradient a vanishing effect along with puck. The line trim-off percentage is based on the whole line range [0.0, 1.0]. If either 'trim-start' or 'trim-end' offset is out of valid range, the default range [0.0, 0.0] will be set.</changelog>

Sorry, something went wrong.

@zmiao zmiao marked this pull request as ready for review March 7, 2022 11:05
@endanke endanke requested a review from a team March 8, 2022 09:06
@zmiao zmiao force-pushed the zmiao-line-gradient-trim-offset branch from 6fe4648 to 8ad3469 Compare March 15, 2022 15:36
@ansis ansis self-requested a review March 15, 2022 17:47
@zmiao zmiao force-pushed the zmiao-line-gradient-trim-offset branch from 8ad3469 to 4e72190 Compare March 21, 2022 10:16
// 1. trim_offset range is valid
// 2. line_progress is within trim_offset range
// 3. or if trim_offset end is line end (1.0), mark line_progress >=1.0 part to be transparent to cover 'round'/'square' cap
if (trim_end > trim_start && ((line_progress <= trim_end && line_progress >= trim_start) ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this validation be moved from the fragment shader to where it is set as a uniform? and maybe the trim_end == 1.0 special case can be avoided here by setting it to something > 1 outside the shaders

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this validation be moved from the fragment shader to where it is set as a uniform?

the problem here is if we move the calculation out of shader, we need to compare the trim offset with the every line_progress value, which is generated when creating the vertex array in line_bucket, but the uniform of trim offset is set inside draw_line for each layer, in that sense we need to somehow extract the corresponding line_progress from line bucket and do the comparison, which I think will bring more complexity than the effort of changing shader.

and maybe the trim_end == 1.0 special case can be avoided here by setting it to something > 1 outside the shaders

Good idea, I will do that!

Copy link
Contributor

@ansis ansis Apr 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, by validation I meant just this part trim_end > trim_start.

Could it be if (trim_start <= line_progress && line_progress <= trim_end) { ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 Maybe it is not that feasible, as we have to set the uniform even if the trim offset is not set, in which case, the default one [0.0, 0.0] will be used.
And if we want to validate this during a uniform setting, we then need to have a fallback value passed for an invalid trim offset range, which I think it is more trivial than this solution.

"line-trim-offset": {
"type": "array",
"value": "number",
"doc": "The line trim-off percentage range based on the whole line gradinet range [0.0, 1.0]. The line part between [trim-start, trim-end] will be marked as transparent to make a route vanishing effect. If either 'trim-start' or 'trim-end' offset is out of valid range, the default range will be set.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: gradient* typo

also, I'd suggest switching the order of the sentences so that the first one explains what it does generally, and the units are explained after that

@zmiao zmiao force-pushed the zmiao-line-gradient-trim-offset branch from 4e72190 to ed04445 Compare April 5, 2022 15:14
Copy link
Contributor

@ansis ansis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great to me!

To get the changelog status check to pass you'll need to add a changelog entry in the <changelog></changelog> in the pr body.

@zmiao zmiao merged commit 026d25b into main Apr 6, 2022
@zmiao zmiao deleted the zmiao-line-gradient-trim-offset branch April 6, 2022 05:33
@zmiao
Copy link
Contributor Author

zmiao commented Apr 6, 2022

@ansis @endanke, thanks for your help in making this pr land!

ansis pushed a commit that referenced this pull request Apr 11, 2022
* Add line-gradient-trim-offset definition

* Add line-trim-offset to line layer

* Add line-trim-offset to calculation

* Add new render tests

* remove incorrect precheck

* nit

* Add sdk-support for line-trim-offset property

* nit

* Prototype line trim offset in shader

* use shader to mark trimed line gradient part to be transparent

* cover round/square line-cap case when the trim-offset end is line end. Upload a_line_sofar whenever line-dash is enabled, including line-gradient and line-dash case

* fix line cap issue

* Update expectations

* fix typo

* Adress review findings

* Fix typo

* Add a new render test to test for case that line with round cap and runtime updating the line-trim-offset

Co-authored-by: Daniel Eke <daniel.eke@mapbox.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants