Obecnie używam AngularJS i Three.js, aby spróbować stworzyć mały przykład aplikacji VR. Zdefiniowałem formanty na podstawie tego, czy klient użytkownika jest urządzeniem mobilnym, czy nie. To podejrzana metoda, ale to tylko przykład. OrbitControls są używane na urządzeniach innych niż mobilne, a DeviceOrientationControls są używane w inny sposób.Dlaczego reflektor w mojej scenie three.js pozostaje wyśrodkowany w perspektywie aparatu, ale tylko w Chrome na Androida?
var controls = new THREE.OrbitControls(camera, game.renderer.domElement);
controls.noPan = true;
controls.noZoom = true;
controls.target.set(
camera.position.x,
camera.position.y,
camera.position.z
);
// Really dodgy method of checking if we're on mobile or not
if(/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
controls = new THREE.DeviceOrientationControls(camera, true);
controls.connect();
controls.update();
}
return controls;
Stworzyłem również kilka obiektów do wyświetlenia.
this.camera = new THREE.PerspectiveCamera(90, window.innerWidth/window.innerHeight, 0.001, 1000);
this.camera.position.set(0, 15, 0);
this.textGeometry = new THREE.TextGeometry("Hello World", { size: 5, height: 1 });
this.textMesh = new THREE.Mesh(this.textGeometry, new THREE.MeshBasicMaterial({
color: 0xFF0000, opacity: 1
}));
this.textMesh.position.set(-20, 0, -20);
this.light = new THREE.SpotLight(0x999999, 3, 300);
this.light.position.set(50, 50, 50);
this.floorGeometry = new THREE.PlaneBufferGeometry(1000, 1000);
this.floorTexture = THREE.ImageUtils.loadTexture('img/textures/wood.jpg');
this.floorTexture.wrapS = THREE.RepeatWrapping;
this.floorTexture.wrapT = THREE.RepeatWrapping;
this.floorTexture.repeat = new THREE.Vector2(50, 50);
this.floorTexture.anisotropy = this.game.renderer.getMaxAnisotropy();
this.floorMaterial = new THREE.MeshPhongMaterial({
color: 0xffffff,
specular: 0xffffff,
shininess: 20,
shading: THREE.FlatShading,
map: this.floorTexture
});
this.floor = new THREE.Mesh(this.floorGeometry, this.floorMaterial);
this.floor.rotation.x = -Math.PI/2;
this.scene.add(this.textMesh);
this.scene.add(this.light);
this.scene.add(this.floor);
this.scene.add(this.camera);
Działa to dobrze na Chrome dla OSX, Safari na OSX & Safari na iPadzie (w tym kontroli orientacji urządzenia, gdzie właściwe).
Problem występuje podczas uruchamiania aplikacji w przeglądarce Chrome na Androida. Reflektor, który został dodany do sceny, będzie stale wskazywany w tym samym kierunku co kamera. Oto zrzut ekranu z uruchomionej aplikacji na Androida:
Na każdej innej przeglądarce próbowałem użyć, światło jest umieszczone na (50, 50, 50) prawidłowo i pozostaje statyczne. W powyższym przykładzie światło jest renderowane pośrodku aparatu i kontynuuje podążanie za kamerą podczas jej przesuwania lub obracania. Faktyczne sterowanie orientacją działa dobrze.
Fakt, że dzieje się to tylko w jednej przeglądarce, naprawdę sprawia mi ból głowy, ponieważ demo musi działać w przeglądarce Chrome na Androida.
Dzięki.
Aktualizacja: Próbowano wielu różnych rozwiązań, od różnych metod sterowania po różne rodzaje oświetlenia, bez skutku.
Czy możesz opublikować pełny kod, także dla renderera? łatwiej nam wtedy powielić i przetestować – cviejo
Tak powinno się stać, gdy światło jest dzieckiem aparatu. W twoim przypadku tak nie jest, więc nie musisz dodawać kamery do sceny. – gaitat
Położyłem mały przykład w Internecie, aby sprawdzić to na moich urządzeniach mobilnych ... ale nie jestem całkowicie przekonany, że mam reprodukcję. Ograniczona swoboda działania aparatu w połączeniu z dużym odbiciem światła sprawia, że trudno go dostrzec. Jeśli ktokolwiek chce spojrzeć, próbka jest tutaj: http://eponalabs.com/experiments/so19086690/. –