Incorrect viewport bounds when renderer size doesn't match canvas element size
The calculation of the viewport rectangle (multi-camera.js#L321-328) assumes that the renderer size matches the size of the canvas element. In most cases this holds true, but when it doesn't, the computed viewport will no longer align with the target div. This can easily happen when scaling up any A-Frame app, as there is a built-in cap set to 1920x1920 (see https://github.com/aframevr/aframe/issues/5413).
It's straightforward to scale the rectangle, but this causes a different issue: the secondary camera views can "bleed" outside its bounds. This is caused both by the canvas interpolation and the fact that the bounds of the target div(s) may not line up with the rendered pixel grid.
As a result I don't think this can be fixed. Instead it's probably best to document the requirement that the renderer size must match the canvas size somewhere and how to disable A-Frame's built-in cap.
@mrxz, thanks for raising this - what do you think about #12 as a partial fix?
Can you create an example that exhibits this problem:
the secondary camera views can "bleed" outside its bounds. This is caused both by the canvas interpolation and the fact that the bounds of the target div(s) may not line up with the rendered pixel grid.
I'm not sure how serious this bleeding really is, and therefore whether/how to document it. I also wonder whether you may have been seeing problems due to #11 ?
@diarmidmackenzie Sure, here's a reproduction that shows the bleeding in question: https://glitch.com/edit/#!/aframe-multi-camera-issue-6. It's a very exaggerated example, the project where I ran into this issue had an 6:1 aspect ratio and would be projected onto the walls of a room, making even tiny bits of bleeding quite obvious due to it being enlarged even further.
There are two contributing factors to the bleeding. One being the interpolation of pixels of the canvas, and the other being the viewport div element not aligning with the canvas' pixel grid. The former can be mitigated by setting the CSS property image-rendering: pixelated on the canvas (at the cost of pixelation across the entire canvas), but would still leave any bleeding due to misalignment:
(Note that this is an even more exaggerated example (
maxCanvasHeight: 20), but shows the canvas pixels clearly)
I don't think there's anything that could realistically be done about it without adjusting the provided viewport. It should all work assuming that:
- The viewport aligns with the canvas pixel grid
- The viewport has a border width >=1 canvas pixel covering interpolation -OR- image-rendering is set to pixelated.
But ultimately it's easier to let users use a matching resolution. On A-Frame master the default values for maxCanvasWidth and maxCanvasHeight are now set to -1, so then it's only an issue for people who deliberately cap the resolution.
Ok, I understand now.
I will document the requirement that an element rendered to must have a border thick enough to cover any discrepancy between the canvas pixels and viewport pixels.
I will also attempt to modify the code to spot when that's not the case, and generate a warning.