maplibre / maplibre-gl-js

MapLibre GL JS - Interactive vector tile maps in the browser
https://maplibre.org/maplibre-gl-js/docs/
Other
5.95k stars 656 forks source link

Add the actual projection matrix to transform #4044

Open dennemark opened 2 months ago

dennemark commented 2 months ago

User Story

As a developer I can get the projection matrix of the maplibre camera and apply it to a camera of another engine (threejs, bablyonjs, maybe even deckgl).

Rationale

Currently only the world-view-projection matrix is exposed. The projection matrix of transform is not actually a projection matrix, but it is multiplied by the view matrix (correct me if i am wrong).

The projection matrix normally contains nearZ, farZ, fov and aspectRatio. But the position and rotation of the camera are applied to it, too. (see code link below)

The official examples work around this, by messing with the projection matrices of cameras of threejs and babylonjs and applying a world-view-projection matrix to them. This however can lead to issues with i.e. shadows or line drawings, or click events that need a proper view matrix on a camera (https://forum.babylonjs.com/t/cascaded-shadow-map-are-not-properly-projected-with-camera-freezeprojectionmatrix/49570/14).

Libraries like threebox are copying the projection matrix code of maplibre to get a proper camera position. I have done so, too, now. It gives the same result as the babylonjs example of maplibre. DeckGL is creating its own projection matrix, but I think there were also similar code parts as in maplibre.

But maintaining this will be bothersome, since maplibre might change its calculation of the projection matrix because of the terrain i.e. So it would be nice to expose either the correct projection matrix and give the current projMatrix a new name or it would be nice to expose another property on a transform. The assignment should be added after this line:

https://github.com/maplibre/maplibre-gl-js/blob/3f481c81f87fa880bd80691a371eb75dd57c56b2/src/geo/transform.ts#L890

Normally adding 2-3 lines would already fix this. If we agree on naming, I could create a PR and optionally can add another babylonjs example.

Impact

Issues with i.e. shadows or line drawings, or click events in other overlayed engines.

HarelM commented 2 months ago

I think there was a PR that started this, the problem is the public API which is hard to define from my point of view. There is work on the globe branch and @kubapelc has mentioned refactoring the transform class, this might be one of these changes I guess...

dennemark commented 2 months ago

Thanks for the reply! Great to hear and makes sense to include it in new version!

Tried to find some discussion on it. But only found some closed PR. Otherwise I would have mentioned it and closed the issue.

Looking forward to the change :)

HarelM commented 2 months ago

Can you link to that PR? I'm having a hard time finding it... But in general, all I remember is that closed PR.

birkskyum commented 2 months ago

Related

HarelM commented 2 months ago

Thanks @birkskyum! Although not exactly the same thing, the linked PR is related to my concern about public API.