GithubHelp home page GithubHelp logo

Comments (5)

chrisgervang avatar chrisgervang commented on May 21, 2024

Alternate idea I haven't implemented:

  • Use an off-screen canvas for rendering.
    • Solution 1 seems to work when Requirement 2 was relaxed. We can relax it since the user won't see it.
    • I expect this has the same viewport boundary issue as Solution 2.
    • Still need a preview. Use Solution 1 if its ok to be inaccurate by a few pixels?? Or Solution 2 w/ viewport addressed.

from hubble.gl.

chrisgervang avatar chrisgervang commented on May 21, 2024

Digging deeper I've realized that so far neither solution satisfies requirement 3. yet, and I spent some time figuring out why.

“Resolution setting” is user defined setting of the expected image export.
“Container” is canvas.clientHeight/Width
“Rendered resolution” is the actual image export resolution. It’s canvas.height/width
“DPI” is window.devicePixelRatio
“Viewport bounds” is the perspective boundary of the rendered world (would be a new viewport.getBounds().

In Solution 1, it’s observed that the viewport changes when the user resizes the container. It’s also observed that locking the container size results in a fixed viewport at any resolution setting, and this results in the expected rendered resolution because the DPI is changing.

In Solution 2 it’s observed that the viewport changes when resolution setting is changed because DPI is fixed, and the container changes to export the expected rendered resolution. It’s also observed that locking the resolution setting and setting any container size results in a fixed viewport because the rendered resolution is exactly set to the resolution setting, the container is scaled with CSS transform, and DPI is fixed.

So it seems the only way to keep the viewport bounds fixed in the current system is to not change the container size. Next I'm going to investigate if I can change DPI while maintaining a viewport - if I can, I'm interested in understanding why because the frameworks pass that into webgl and I'd like to have more direct control if I can.

from hubble.gl.

chrisgervang avatar chrisgervang commented on May 21, 2024

change DPI while maintaining a viewport

I'm happy to see changing window.devicePixelRatio can change the resolution without changing viewport, so it seems the canvas.clientWidth/Height is directly related to viewport bounds. Next I'll look at how this works.

I want a better solution than changing window.devicePixelRatio, since it's undefined behavior. Being a global variable and it'll also cause effects on other components relying on the variable.

Low DPI (expecting blurry)

Screen Shot 2021-09-20 at 5 47 37 PM

High DPI

Screen Shot 2021-09-20 at 5 47 23 PM

from hubble.gl.

chrisgervang avatar chrisgervang commented on May 21, 2024

@ibgreen I've been watching the code that runs when resizing the canvas or changing DPI and I have more (but not all) confidence a shared drawing buffer resolution is controlled by our frameworks rather than mapbox. Deck's AnimationLoop constantly checks for canvas size/DPI changes and calls luma's resizeGLContext.

Luma floors the resolution, which partly explains why I'm seeing slightly unexpected resolutions.

I'd like to have a new feature on resizeGLContext / AnimationLoop that allows me to directly set the inner canvas width/height and ignore DPI. The viewport uses the canvas client width/height to set the viewport bounds - I'll either need to set the canvas to something constant or directly set the viewport size somewhere.

Edit: In the mean time I'm going to hack together a proof that our frameworks have control of the mapbox gl context resolution.

from hubble.gl.

chrisgervang avatar chrisgervang commented on May 21, 2024

Today I took a slight tangent to see if we could render both deck and mapbox to a non-default framebuffer that we define. While it was easy to do with deck, I don't think it is possible in mapbox right now. Implementation in 26dbd2f.

DeckRender allows the target framebuffer to be overridden,
opts.target = opts.target || Framebuffer.getDefaultFramebuffer(this.gl);

The Painter in mapbox doesn't appear to have it where I expected it,
this.context.bindFramebuffer.set(null);

from hubble.gl.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.