Skip to content
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

CSS3DRenderer offset for Safari on High DPI displays with odd resolution #19854

Closed
9 of 19 tasks
JohannesDeml opened this issue Jul 16, 2020 · 14 comments
Closed
9 of 19 tasks

Comments

@JohannesDeml
Copy link
Contributor

JohannesDeml commented Jul 16, 2020

Description of the problem

When combining a webgl renderer with a cssrenderer (by punching holes through the webgl renderer to show the css renderer below, there is sometimes a missmatch between the renderers. It looks as if the cssRenderer has a slight offset compared to the webglrenderer. Interestingly enough, this happens on iPhoneX, but not iPhoneSE or iPad Mini4 and also not on android and desktop. Not sure about newer iPhones. The problem is especially present when looking at the css area at a very shallow angle.

The problem is not bound to the css object present (also tried it with a simple ).
There should be no white area around the youtube video:
Video
Screenshot 1
Screenshot 3

Three.js version
  • Dev
  • r118
  • ...
Browser
  • All of them
  • Chrome
  • Firefox
  • Safari
OS
  • All of them
  • Windows
  • macOS
  • Linux
  • Android
  • iOS
Hardware Requirements (graphics card, VR Device, ...)
  • iPhone SE
  • iPhone 8
  • iPhone X
  • iPhone 11 Pro
  • MacBook Pro with external High DPI Display
  • iMac
@yomotsu
Copy link
Contributor

yomotsu commented Jul 17, 2020

Confirm and reproduced the problem on my iPhoneX too.
I also checked another example: https://threejs.org/examples/?q=css#css3d_sandbox but this seems to work with no gap on the same iPhoneX

@JohannesDeml
Copy link
Contributor Author

JohannesDeml commented Jul 17, 2020

Confirm and reproduced the problem on my iPhoneX too.
I also checked another example: https://threejs.org/examples/?q=css#css3d_sandbox but this seems to work with no gap on the same iPhoneX

That is very interesting, thanks a lot for pointing it out! I somehow missed that example.

Maybe there is a precision problem for handling matrix3d css stacks that is even more apparent for my example (since it is scaled by a factor of 100). I will try to expose the difference that creates the very visible problem in my example.

@JohannesDeml
Copy link
Contributor Author

JohannesDeml commented Jul 17, 2020

I was able to check the example @yomotsu posted with an iPhoneX and the offset also happens there.
css3d-sandbox-screenshot

So I guess it is safe to say that the problem does exist (since I built my example without knowing of the other example) and it is a device specific limitation for iPhone X (and maybe newer, sadly I don't have a newer iOS device at hand).

@JohannesDeml
Copy link
Contributor Author

I was able to reproduce the problem on an iPhone 11 Pro as well. Could this have something to do with the notch / Rounded corners? I am already using the cover meta tag to avoid such problems, but it's really strange that the problem starts to appear on iOS devices with a notch...
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0, initial-scale=1.0, viewport-fit=cover" />

@JohannesDeml JohannesDeml changed the title CSS3DRenderer offset to WebGL Renderer on iPhone X CSS3DRenderer offset to WebGL Renderer on iPhone X and iPhone 11 Jul 20, 2020
@mrdoob
Copy link
Owner

mrdoob commented Jul 20, 2020

I've seen similar issues in the past and I think the issue was something like not being able to match CSS's perspective code with the current PerspectiveCamera updateProjectionMatrix code. Didn't end up digging deeper.

@WestLangley
Copy link
Collaborator

FWIW, on Safari on my iMac, showing the favorites bar causes a similar offset artifact (refresh required). It also occurs with page zoom not equal to 100%.

@JohannesDeml
Copy link
Contributor Author

I've seen similar issues in the past and I think the issue was something like not being able to match CSS's perspective code with the current PerspectiveCamera updateProjectionMatrix code. Didn't end up digging deeper.

Hm, I think that might be a different issue, I built a repro with a orthographic camera, which shows the same problem.

FWIW, on Safari on my iMac, showing the favorites bar causes a similar offset artifact (refresh required). It also occurs with page zoom not equal to 100%.

Interesting, thanks for pointing it out. I dug a bit deeper, and I get the same issue when using a MacBook connected to a high DPI monitor with scaling set to the smallest value (might be needed just to get to a higher css resolution).

As for zooming, that might be connected to this issue (Repro), which was fixed in every browser except safari.

Anyways, I think I might have a lead on how to fix the problem:
As mentioned, the problem can be reproduced on MacOS. There I took a closer look at the css styling of the camera element. I noticed that changing the last translate value (which is half width, halfHeight) by 0.5-1.0 pixels seems to fix the problem. I haven't found out, when we have to change it in one other the other direction. I need to dig a bit deeper there.

If that is the case and the fix is to handle the transform values differently in the camera on safari, where would I need to put the user agent read to validate if the browser is safari? Should I put that in the Camera code, or somewhere else?

@WestLangley
Copy link
Collaborator

WestLangley commented Aug 5, 2020

On your orhto example, with Safari on iMac, resizing the window vertically only or horizontally only is illustrative.

Screen Shot 2020-08-05 at 10 47 11 AM

Maybe try

_widthHalf = Math.round( _width / 2 );
_heightHalf = Math.round( _height / 2 );

Just a guess.

@JohannesDeml
Copy link
Contributor Author

JohannesDeml commented Aug 6, 2020

Maybe try

_widthHalf = Math.round( _width / 2 );
_heightHalf = Math.round( _height / 2 );

Just a guess.

Yep, that does it for safari

grafik

So we will need to implement a check for safari (similar to what is done for ie) and use rounded values there.
I will also port my perspective example to a test branch to see, if the rounding fixes that problem as well.

Update: Nope, for the perspective camera, I will need to dig a bit deeper 😣

@JohannesDeml
Copy link
Contributor Author

JohannesDeml commented Aug 6, 2020

Okay, so I fixed the orthographic problem, sadly it seems that it does not have too much to do with the perspective problem other than having problems with odd resolutions.

I made a playground branch with a perspective and orthographic css scene which show the problem quite well:
Orthographic
Perspective

The problem that still exists now is:

CSS rendering for safari with odd width and or height. In that case the css looks like it is pushed away a bit from the camera:
grafik

When rotating the camera orthogonal to the plane, the plane offsets in interesting ways: https://www.youtube.com/watch?v=5YeipB0ZKGs

This is not a translation problem anymore. Has anybody any idea how to tackle that one? Maybe perspective or scaling at some point?

@JohannesDeml JohannesDeml changed the title CSS3DRenderer offset to WebGL Renderer on iPhone X and iPhone 11 CSS3DRenderer offset for Safari on High DPI displays with odd resolution Aug 6, 2020
@mrdoob mrdoob closed this as completed Aug 8, 2020
@JohannesDeml
Copy link
Contributor Author

@mrdoob my PR sadly only fixed the problem for the orthographic camera, but not the perspective camera. Should I open another issue for that, or should we keep that one open?

@manthrax
Copy link
Contributor

I've encountered similar problems on a past product. The "page zoom" controls also affect these transforms. We ended up setting preferred min-zoom/max-zoom in the CSS to mitigate problems..
I also recall that chromes handling of the CSS transforms changed somewhat arbitrarily a number of times over the course of 6 months of work on the feature, requiring it to be addressed many times, only to have chrome revert the breaking changes, or, alternatively, respond to our bug reports of the issue.

@Mugen87
Copy link
Collaborator

Mugen87 commented Mar 3, 2021

This needs to be fixed in Webkit: https://bugs.webkit.org/show_bug.cgi?id=215590

@zh-pan
Copy link

zh-pan commented Jun 19, 2022

This issue beset me too, I debug a few hours. The result I've come to is this, you need set canvas width/height as even number at first, and set css3DObject's element width/height as even number too. The code maybe like this:

css3DRenderer.setSize(
  width % 2 === 0 ? width : width - 1,
  height % 2 === 0 ? height : height - 1
 );
----------------------------------
css3DObject.element.style.width = (width % 2 === 0 ? width : width - 1)+'px'
css3DObject.element.style.height= (height% 2 === 0 ? height: height- 1)+'px'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants