mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
102.77k stars 35.38k forks source link

Strange behavior on Mobile Safari. #1440

Closed Dino4674 closed 12 years ago

Dino4674 commented 12 years ago

Hi,

I made a simple app which uses Three.js and on video below you can see how it works in iPhone simulator. Those three sliders represents camera rotation over x, y and z axis and they go from -PI to +PI.

Application running in iPhone simulator video

You can see how it works perfectly normal.

But the problem is when I run the same app on a device (same on iPhone and iPad). Here are few screenshots of app on a device:

1 2 3 4 5

X and Y axis acts normal.

First I thought that this was a Three.js's issue but obviously it isn't since it works normally in simulator. The problem must be on iOS's native browser. So the question is: what can I do in my JS code to fix this?

Same is if mesh is cube or plane in this case.

I use canvas renderer here.

gyuque commented 12 years ago

Reduced test case: http://dl.dropbox.com/u/103789/trbug.html

Well, mobile safari on iOS5 seems to be badly corrupted.

(on Chrome, Windows: OK) on PC (on iOS4, old iPod touch: OK) iOS4

(on iOS5, iPad: BAD) iOS5

Dino4674 commented 12 years ago

Well this is not good at all for me.

This looks like a dead end for me:

Should I just wait for Apple to fix this or for WebGL enabling or should I consider some different framework from ThreeJS?

Any suggestions would be great.

WestLangley commented 12 years ago

@Dino4674 If you can't wait, you can hack it: http://atnan.com/blog/2011/11/07/amazing-response-to-my-ios-webgl-hack/.

Dino4674 commented 12 years ago

@WestLangley I saw that post 2 months ago but if I would do this than Apple would refuse my app from store so this is not a good solution for me.

I saw this. Someone posted on ThreeJS issues. This is CSS 3D renderer for iOS and it works perfectly on iOS but mrdoob said 3 months ago that he will not implement this renderer because he expects WebGL to be enabled before the time he could finish this renderer. I'm afraid that WebGL will not be enabled any time soon just like the case is with flash.

Dino4674 commented 12 years ago

@mrdoob Since you are the author of library, could you please suggest me what are my options here because I really wouldn't like to loose ThreeJs's awesome features because of this? Thx.

gyuque commented 12 years ago

This bug will be fixed in the near future by WebKit team but...yes, we cannot ask users to update Mobile Safari right now because it's bundled with iOS. So I tried to write quick hack: http://dl.dropbox.com/u/103789/wk-quickfix.html

It works well on my iPad. This uses [drawImage + clip] instead of [path + fill pattern] to draw textured polygon. This way has a limitation; cannot render "repeated" texture.

mrdoob commented 12 years ago

Thanks for researching on this @gyuque! Great to know that it's a WebKit bug. By the way, CanvasRenderer also uses drawImage + clip in some cases (lambert illumination as far as I remember).

@Dino4674 what you can try to do is to change all the patternPath() calls in CanvasRenderer to drawImage(), and then recompile the lib (/utils/build_all.sh). That will use he method @gyuque has show it works on these devices, but, as he rightly said, it doesn't support repeated textures, which may or may not affect you.

Dino4674 commented 12 years ago

@mrdoob @gyuque what do you mean by repeated texture?

mrdoob commented 12 years ago
texture.repeat.x = 2;
texture.repeat.y = 2;
Dino4674 commented 12 years ago

@mrdoob @gyuque I replaced calls to patternPath() to _context.drawImage() and now my image is not showing at all. Any ideas? Do I need to change that somewhere else also?

TonyRogersAtWork commented 12 years ago

Here is a code replacement that worked for me (last argument is different):

// patternPath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _uvs[ uv1 ].u, _uvs[ uv1 ].v, _uvs[ uv2 ].u, _uvs[ uv2 ].v, _uvs[ uv3 ].u, _uvs[ uv3 ].v, material.map );
clipImage( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _uvs[ uv1 ].u, _uvs[ uv1 ].v, _uvs[ uv2 ].u, _uvs[ uv2 ].v, _uvs[ uv3 ].u, _uvs[ uv3 ].v, material.map.image );

Tested this out this morning on my iPad and it works !!!

Thanks so much @gyuque and @mrdoob.

Dino4674 commented 12 years ago

@stsci Tested on my iPhone 4 and this method with clipImage() works. Thx to all.

eddyb commented 12 years ago

Well, I did that replace: https://gist.github.com/2271918 - but I still have problems. See the image distortion here (spin it a bit): http://jsfiddle.net/LKNXc/14/show Can three.js do this: http://tulrich.com/geekstuff/canvas/perspective.html - because that's what I need.

mrdoob commented 12 years ago

Can three.js do this: http://tulrich.com/geekstuff/canvas/perspective.html - because that's what I need.

Nope, you can add more detail to the cube though.

http://jsfiddle.net/LKNXc/22/show/

eddyb commented 12 years ago

That still gets distorted, and in the latest version I have holes in the board, which aren't visible sometimes because of the distortion. Open this with webGL disabled: http://me.kwhq.net/webGerber/?debug (or do delete THREE.WebGLRenderer; in the console before clicking to load the demo). Is there no way to properly show a 2D square texture on a 2D canvas? I've seen CSS3 3D demos that require no acceleration and look like what I want.

mrdoob commented 12 years ago

Well, considering that's just 2D Canvas (having done the delete THREE.WebGLRenderer), is not bad at all! :)

jdbender commented 11 years ago

I am having a similar problem to the issue described here. I have tried using the most current release build and the most current dev build. The problem occurs in Safari only on both a Mac (Safari 6.0.2 (8536.26.17)) and on IOS devices. Here is an example http://data.iscorecentral.com/iscorecast/jb/test10.htm Press the Rotate button and Chrome and Firefox work fine. Safari shows a severely distorted image and will barely update.

mrdoob commented 11 years ago

@jdbender Oh wow. That's broken indeed...

Anyway, you may want to use CSS3DRenderer for that instead.

http://mrdoob.github.com/three.js/examples/css3d_periodictable.html http://mrdoob.github.com/three.js/examples/css3d_molecules.html

jdbender commented 11 years ago

Thank you, the CSSRenderer draws my image well in all browsers. However, as you can see, the dynamic spline based lines are integral to the project I am working on. When I use CanvasRenderer for the splines, the CSS image does not appear in the scene. When I use the CSS3DRenderer, the spline generated lines do not appear in the scene. Is there a way to show both types in a single renderer or somehow combine the two renderers?

mrdoob commented 11 years ago

You can put the CanvasRenderer dom element on top of the CSS3DRenderer dom element.

zz85 commented 11 years ago

@jdbender CSS3DRenderer currently do not support lines. It is however still possible to render lines with by creating div of 1 pixel height. See createLineObject in http://jabtunes.com/labs/3d/css/CSS3DRenderer2.js from http://jabtunes.com/labs/3d/css/css3d_scene.html

jdbender commented 11 years ago

@zz85 Thank you for the suggestion but in the project I am working on, the lines are variable sizes (depending on hit strength) so single pixel lines will not work in this instance.

@mrdoob Unfortunately when you put the CanvasRenderer dom element on top of the CSS3DRenderer, any rotation where the image plane would normally be closer to the camera would not render correctly because the CanvasRenderer would still draw the spline lines on top.

I see that 10 months ago there was a fix suggested (replace patternPath with clipImage) that people said fixed the issue. I tried that method with the current codebase but was unable to get it to work. Is there any chance you can add that fix back into the current codebase and allow us to set a flag that chooses which method to use. Until Apple supports WebGL it would be great if we could still support mobile users.

ima747 commented 11 years ago

Is the canvasrenderer still broken? My current experience is that the image utils load texture doesn't work with canvas at all. If you use a straight texture and loader it kinda works: on chrome loading a transparent png shows the texture transparent by default and it can't be overwritten with transparent false. On safari it loads it also shows transparent but I get the weird texture skewing shown in the original post with white around the texture even though the texture is showing transparent... Is this an expected issue at this point, or might I be doing something wrong, or have a shaken a gremlin loose?

mrdoob commented 11 years ago

As stated in the guidelines, help requests should be done in stackoverflow. This board is for bugs or feature requests.