so I am a newbie towards threejs and basically have just started to learn and develop in threejs. I do understand due to limitations on mobile browsers there are some characteristics that is not present on desktop may be present on mobile. I however have run into a problem that I cant seem to google or find as to why it happened. I have created a very basic scene with the background color of black ‘0x000000’ and in this scene I have a sphere with wireframe as its material and its color is set to white. On desktop this renders perfect and shows up exactly as black background scene with white sphere geometry. However once Ive test deployed on a domain and accessing it through mobile, the scene and sphere color are totally inverted. I am still unsure what is causing it and any answer would be greatly appreciated. Thanks in advance!
This below code is how I create a canvas and a scene and a sphere.
import "../css/style.css";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import * as dat from "dat.gui";
// Debug
// const gui = new dat.GUI();
// Canvas
const canvas = document.querySelector("canvas.main-bg");
// Scene
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x000000);
// Objects
const geometry = new THREE.SphereBufferGeometry(0.5, 15, 8);
// Materials
const material = new THREE.MeshBasicMaterial({
color: 0xffffff,
wireframe: true,
});
// Mesh
const sphere = new THREE.Mesh(geometry, material);
// Lights
// Point light
const pointLight = new THREE.PointLight(0x252525, 0.1);
pointLight.position.x = 2;
pointLight.position.y = 3;
pointLight.position.z = 4;
scene.add(pointLight);
// Sizes
const sizes = {
width: window.innerWidth,
height: window.innerHeight,
};
window.addEventListener("resize", () => {
// Update sizes
sizes.width = window.innerWidth;
sizes.height = window.innerHeight;
// Update camera
camera.aspect = sizes.width / sizes.height;
camera.updateProjectionMatrix();
// Update renderer
renderer.setSize(sizes.width, sizes.height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
});
// Base camera
const camera = new THREE.PerspectiveCamera(
75,
sizes.width / sizes.height,
0.1,
100
);
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 2;
scene.add(camera);
// Controls
// const controls = new OrbitControls(camera, canvas)
// controls.enableDamping = true
// Renderer
const renderer = new THREE.WebGLRenderer({
canvas: canvas,
});
renderer.setSize(sizes.width, sizes.height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
const clock = new THREE.Clock();
const animate = () =>
const elapsedTime = clock.getElapsedTime();
// Update objects
sphere.rotation.y = -0.2 * elapsedTime;
sphere2.rotation.y = 0.1 * elapsedTime;
sphere3.rotation.x = 0.7 * elapsedTime;
sphere.rotation.x += 0.5 * (targetY - sphere.rotation.x);
sphere.rotation.y += 0.5 * (targetX - sphere.rotation.y);
sphere.position.z += -0.5 * (targetY - sphere.rotation.x);
// Render
renderer.render(scene, camera);
// Call animate again on the next frame
window.requestAnimationFrame(animate);
};
animate();
Nothing else besides this is altering the scene.background color. This is how it looks like on desktop.
desktop image
And this is how it looks like on mobile.mobile
Nothing else is setting the canvas color however the colors are inverted on mobile, Any help is greatly appreciated! Thank you
You have added the CSS rule mix-blend-mode: exclusion to your <canvas>. For some reason, Safari is the only browser that's respecting that rule, and that's why it's showing inverted colors on mobile.
If you want a black background with white wireframes, just get rid of any mix-blend-modes in CSS so you get exactly the color you're defining.
Related
I have quite a large plane with a set displacement map and scale which I do not want to be changed. I simply want the loaded texture to apply to that mesh without it having to scale up so largely.
Currently, a floor texture doesn't look like a floor as it has been upscaled to suit the large plane.
How would I be able to scale down the texture and multiply it across the plane so it looks more like actual terrain?
const tilesNormalMap = textureLoader.load(
"./textures/Stylized_Stone_Floor_005_normal.jpg"
);
function createGround() {
let disMap = new THREE.TextureLoader().load("./models/Heightmap.png");
disMap.wrapS = disMap.wrapT = THREE.RepeatWrapping;
disMap.repeat.set(4, 2);
const groundMat = new THREE.MeshStandardMaterial({
map: tilesBaseColor,
normalMap: tilesNormalMap,
displacementMap: disMap,
displacementScale: 2
});
const groundGeo = new THREE.PlaneGeometry(300, 300, 800, 800);
let groundMesh = new THREE.Mesh(groundGeo, groundMat);
scene.add(groundMesh);
groundMesh.rotation.x = -Math.PI / 2;
groundMesh.position.y -= 1.5;
I tried using the .repeat method as shown below but i can't figure out how this would be implemented
tilesBaseColor.repeat.set(0.9, 0.9);
tilesBaseColor.offset.set(0.001, 0.001);
a photo of the current ground texture
enter image description here
First of all what you want to achieve does currently not work with three.js since it's only possible to a have a single uv transform for all textures (except for light and ao map). And map has priority in your case so you can't have different repeat settings for the displacement map. Related issue at GitHub: https://github.com/mrdoob/three.js/issues/9457
Currently, a floor texture doesn't look like a floor as it has been upscaled to suit the large plane. How would I be able to scale down the texture and multiply it across the plane so it looks more like actual terrain?
In this case, you have to use repeat values great 1 otherwise you zoom into the texture. Do it like in the following live example:
let camera, scene, renderer;
init().then(render);
async function init() {
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10);
camera.position.z = 1;
scene = new THREE.Scene();
const loader = new THREE.TextureLoader();
const texture = await loader.loadAsync('https://threejs.org/examples/textures/uv_grid_opengl.jpg');
// repeat settings
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(2, 2);
const geometry = new THREE.PlaneGeometry();
const material = new THREE.MeshBasicMaterial({map: texture});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
function render() {
renderer.render(scene, camera);
}
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.148/build/three.min.js"></script>
I am a novice to Javascript and ThreeJS. I have a 3D rotating cube that appears on top of a static background, but one frustrating property is that the cube typically appears first and then the background image appears. How do I ensure the background is rendered first? Specifically, I always want the background image to appear before the cube.
My code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body { margin: 0; }
</style>
</head>
<body>
<script src="js/three.js"></script>
<script>
function resize() {
var aspect = window.innerWidth / window.innerHeight;
let texAspect = bgWidth / bgHeight;
let relAspect = aspect / texAspect;
bgTexture.repeat = new THREE.Vector2( Math.max(relAspect, 1), Math.max(1/relAspect,1) );
bgTexture.offset = new THREE.Vector2( -Math.max(relAspect-1, 0)/2, -Math.max(1/relAspect-1, 0)/2 );
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = aspect;
camera.updateProjectionMatrix();
}
const scene = new THREE.Scene();
// Arguments:
// 1) Field of Value (degrees)
// 2) Aspect ratio
// 3) Near clipping plane
// 4) Far clipping plane
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer();
// Need to set size of renderer. For performance, may want to reduce size.
// Can also reduce resolution by passing false as third arg to .setSize
renderer.setSize( window.innerWidth, window.innerHeight );
// Add the rendered to the HTML
document.body.appendChild( renderer.domElement );
// A BoxGeometry is an object that contains all points (vertices) and fill (faces)
// of the cube
const geometry = new THREE.BoxGeometry();
// Determines surface color (maybe texture?)
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
// Mesh takes a geometry and applies the material to it
const cube = new THREE.Mesh( geometry, material );
// Add background image
const loader = new THREE.TextureLoader();
bgTexture = loader.load('https://images.pexels.com/photos/1205301/pexels-photo-1205301.jpeg' ,
function(texture) {
// Resize image to fit in window
// Code from https://stackoverflow.com/a/48126806/4570472
var img = texture.image;
var bgWidth = img.width;
var bgHeight = img.height;
resize();
});
scene.background = bgTexture;
// By default, whatever we add to the scene will be at coordinates (0, 0, 0)
scene.add( cube );
camera.position.z = 5;
// This somehow creates a loop that causes the rendered to draw the scene
// every time the screen is refreshed (typically 60fps)
function animate() {
requestAnimationFrame( animate );
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render( scene, camera );
}
animate();
</script>
</body>
</html>
This is happening because the texture is taking longer to load than it takes for Three.js to set up the rest of the scene. You already have a handler for the onLoad callback of TextureLoader.load(), so we can use that to adjust the behavior.
Before scene.add( cube );, add a new line:
cube.visible = false;
Now the cube will still be added to the scene, but it won't be visible. Now after the resize() call at the end of function(texture), add
cube.visible = true;
While testing the problem and solution locally, I ran into a few other, less significant issues with your code. You can see all of the changes I had to make to get it running properly at this Gist.
I have looked through stack overflow and google and I have found how to CENTER a text geometry but that is not what I want to do.
I have a scene that just has a block of text that says "Buy Here!". Using the documentation in the three.js website and examples here I was able to do that after some struggling. I had some trouble finding out how to refer to that mesh since I had created the geometry inside a function, and it took hours for me to know about setting a name for it as a string so it can be accessible from different parent/child levels.
What I am NOT able to do now is to offset the text by some arbitrary number of units. I tried shifting it down by 5 units. No matter how I try to do it it isn't working. I either manage to make the text geometry disappear OR my whole scene is black.
Here is my code...
I have the basic scene setup working properly and I'll include it here but feel free to skip since I'm pretty sure this has nothing to do with the issue...
import './style.css'
import * as THREE from 'three';
import { OrbitControls } from 'https://cdn.jsdelivr.net/npm/three#0.117.0/examples/jsm/controls/OrbitControls.js';
import TWEEN from 'https://cdn.jsdelivr.net/npm/#tweenjs/tween.js#18.5.0/dist/tween.esm.js';
//BASIC SCENE SETUP
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);
//LIGHTS (POINT AND AMBIENT)
const pointLight = new THREE.PointLight(0xFFFFFF);
pointLight.position.set(5, 5, 5);
const ambientLight = new THREE.AmbientLight(0xFFFFFF);
scene.add(pointLight, ambientLight);
//RESIZE WINDOW
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
render();
}, false);
//ORBIT CONTROLS
const controls = new OrbitControls(camera, renderer.domElement);
controls.minDistance = 5;
controls.maxDistance = 70;
controls.enablePan = false;
controls.enableRotate = false;
controls.enableZoom = false;
controls.target.set(0,0,-1);
camera.position.setZ(25);
window.addEventListener("click", (event) => {
onClick(event);
})
window.addEventListener("mousemove", onMouseMove);
var animate = function() {
requestAnimationFrame(animate);
controls.update();
render();
TWEEN.update();
};
function render() {
renderer.render(scene, camera);
}
animate();
and here is my code for the text object....
var loaderF = new THREE.FontLoader();
loaderF.load( 'https://threejs.org/examples/fonts/optimer_regular.typeface.json', function ( font ) {
var geometry = new THREE.TextGeometry( 'Buy Here!', {
font: font,
size: 2.3,
height: 0.1,
curveSegments: 15,
bevelEnabled: true,
bevelThickness: 0.5,
bevelSize: 0.31,
bevelSegments: 7
} );
geometry.center();
var material = new THREE.MeshLambertMaterial({color: 0x686868});
var mesh = new THREE.Mesh( geometry, material );
mesh.name = "bhText"
scene.add( mesh );
mesh.userData = { URL: "http://google.com"};
} );
Here's what I have tried.....
under "var geometry ({...});" I typed....
geometry.position.setX(-5);
but the text object disappears completely so I tried
geometry.position.setX = -5;
but there was no difference so i tried taking out
geometry.center();
but it had the same results.
So then I tried using
mesh.position.x = -5;
with AND without
geometry.center();
but again, they all just make my text object disappear.
So now I tried to set the position from outside the function by typing the following code OUTSIDE of everything that is contained in
loaderF.load ('https.....', function (font){var geometry = .....})
using the reference I learned....
scene.getObjectByName("bhText").position.x(-5);
but this makes my entire scene go blank (black). So I tried variations of like
scene.getObjectByName("bhText").position.x = -5;
scene.getObjectByName("bhText").position.setX(-5);
scene.getObjectByName("bhText").position.setX = -5;
mesh.position.setX = -5;// I was pretty sure this wasn't going to work since I wasn't
//using the mesh name specifically for when it's inside something
//I can't reach because of parent-child relations
and again trying each of those with AND without
geometry.center();
but they all made my scene go black.
I just wanna move it down a couple of units. Sheesh.
Could anyone be kind enough to tell me WHERE in my code I can set the position of the text geometry? Thank you please.
I just wanna move it down a couple of units.
In this case use mesh.position.y = - 5;. Changing the x coordinate will move the mesh to the left or right. Here is a complete live example based on your code:
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set( 0, 0, 10 );
const renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);
const pointLight = new THREE.PointLight(0xFFFFFF);
pointLight.position.set(5, 5, 5);
const ambientLight = new THREE.AmbientLight(0xFFFFFF);
scene.add(pointLight, ambientLight);
const loader = new THREE.FontLoader();
loader.load('https://threejs.org/examples/fonts/optimer_regular.typeface.json', function(font) {
const geometry = new THREE.TextGeometry('Buy Here!', {
font: font,
size: 2,
height: 0.5
});
geometry.center();
const material = new THREE.MeshLambertMaterial({
color: 0x686868
});
const mesh = new THREE.Mesh(geometry, material);
mesh.position.y = - 1; // FIX
mesh.name = "bhText"
scene.add(mesh);
renderer.render(scene, camera);
});
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.130.1/build/three.min.js"></script>
I'm studying Three.js and I'm tryng to do my first game: and endless game.
I have read this article and the purpose is to do something very similar.
The protagonist (the hero) is a blue ball that rolls towards the "infinity" and must avoid some obstacles that gradually arise in front of him. The user can avoid these obstacles by guiding the ball to the left or right and jumping (the idea is to use the keyboard and in particular the left/right arrow keys and the space bar to jump).
Here is my idea:
I want to follow the idea of the article but not to copy the code (I want to understand it).
This is what I've done so far:
let sceneWidth = window.innerWidth;
let sceneHeight = window.innerHeight;
let canvas;
let camera;
let scene;
let renderer;
let dom;
let sun;
let hero;
let ground;
let clock;
let spotLight;
let ambientLight;
init();
function init() {
createScene();
showHelpers();
update();
}
/**
* Set up scene.
*/
function createScene() {
clock = new THREE.Clock();
clock.start();
scene = new THREE.Scene();
window.scene = scene;
camera = new THREE.PerspectiveCamera(60, sceneWidth / sceneHeight, 0.1, 1000);
camera.position.set(0, 0, 0);
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setClearColor(0x333f47, 1);
renderer.shadowMap.enabled = true;
renderer.shadowMapSoft = true;
renderer.setSize(sceneWidth, sceneHeight);
canvas = renderer.domElement;
document.body.appendChild(canvas);
// const orbitControls = new THREE.OrbitControls(camera, canvas);
addGround();
addHero();
addLight();
camera.position.set(0, -1, 0.6);
camera.lookAt(new THREE.Vector3(0, 0, 0));
window.addEventListener("resize", onWindowResize, false);
}
/**
* Show helper.
*/
function showHelpers() {
const axesHelper = new THREE.AxesHelper(5);
// scene.add(axesHelper);
const spotLightHelper = new THREE.SpotLightHelper(spotLight);
scene.add(spotLightHelper);
}
/**
* Add ground to scene.
*/
function addGround() {
const geometry = new THREE.PlaneGeometry(1, 4);
const material = new THREE.MeshLambertMaterial({
color: 0xcccccc,
side: THREE.DoubleSide
});
ground = new THREE.Mesh(geometry, material);
ground.position.set(0, 1, 0);
ground.receiveShadow = true;
scene.add(ground);
}
/**
* Add hero to scene.
*/
function addHero() {
var geometry = new THREE.SphereGeometry(0.03, 32, 32);
var material = new THREE.MeshLambertMaterial({
color: 0x3875d8,
side: THREE.DoubleSide
});
hero = new THREE.Mesh(geometry, material);
hero.receiveShadow = true;
hero.castShadow = true;
scene.add(hero);
hero.position.set(0, -0.62, 0.03);
}
/**
* Add light to scene.
*/
function addLight() {
// spot light
spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(2, 30, 0);
spotLight.angle = degToRad(10);
spotLight.castShadow = true;
spotLight.shadow.mapSize.width = 1024;
spotLight.shadow.mapSize.height = 1024;
spotLight.shadow.camera.near = 1;
spotLight.shadow.camera.far = 4000;
spotLight.shadow.camera.fov = 45;
scene.add(spotLight);
// ambient light
ambientLight = new THREE.AmbientLight(0x303030, 2);
scene.add(ambientLight);
}
/**
* Call game loop.
*/
function update() {
render();
requestAnimationFrame(update);
}
/**
* Render the scene.
*/
function render() {
renderer.render(scene, camera);
}
/**
* On window resize, render again the scene.
*/
function onWindowResize() {
sceneHeight = window.innerHeight;
sceneWidth = window.innerWidth;
renderer.setSize(sceneWidth, sceneHeight);
camera.aspect = sceneWidth / sceneHeight;
camera.updateProjectionMatrix();
}
/**
* Degree to radiants
*/
function degToRad(degree) {
return degree * (Math.PI / 180);
}
<script src="https://threejs.org/build/three.min.js"></script>
(JSFiddle)
I'm having several problems, the first is the position of objects and the camera.
I would like to be able to position the plane so that the minor side is positioned at the beginning of the screen (the entire plane must therefore be visible, there must not be a hidden part).
I would like the ball to be positioned horizontally in the middle and vertically almost at the beginning of the floor (in short, as shown in the figure) and with the shadow projected onto the plane. Each object must have the shadow projected onto the plane.
I'm using a spotlight and Lambert materials so the shade should be there, but there is not. Why?
I don't even understand how to position objects.
I understood that the point (0, 0, 0) is the center of the screen.
I would like the ground to be at y=0 and all the other objects are positioned above as if they were resting.
My code works but I don't know if there are better ways to handle object placement.
I would also simplify my life by assigning to sphere radius 1 and not 0.03 and then making the scene "smaller" moving the camera away as zoom-out (I think this is the trick).
So, I need help setting the scene correctly.
That is my first application in ThreeJs so any advice is welcome!
EDIT 1
I changed camera.lookAt(new THREE.Vector3(0, 0, 0)); to camera.lookAt(new THREE.Vector3(0, 0, -5)); and I added spotLight.lookAt(new THREE.Vector3(0, 0, -5));.
This is the result:
Not exactly what I want...
You're right in placing your plane and sphere at 0 on the y-axis. The problem you're having is that you're telling the camera to look straight at (0, 0, 0) when you do
camera.lookAt(0, 0, 0);
so you'll get the ball perfectly centered. What you should do is tell the camera to look a little bit ahead of the sphere. You'll have to tweak the value, but something like this should do the trick:
camera.lookAt(0, 0, -5);
Additionally, your spotlight is pointing straight ahead. When you place it at (2, 30, 0), its effects get lost. You need to point it to where you want:
spotLight.lookAt(0, 0, -5);
I am trying to replicate the functionality of Google's Cardboard Demo "Exhibit" with three.js. I took the starting example straight from the Chrome Experiments web page and just dropped in code to draw a simple triangular pyramid in the init method:
function init() {
renderer = new THREE.WebGLRenderer();
element = renderer.domElement;
container = document.getElementById('example');
container.appendChild(element);
effect = new THREE.StereoEffect(renderer);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(90, 1, 0.001, 700);
camera.position.set(0, 0, 50);
scene.add(camera);
controls = new THREE.OrbitControls(camera, element);
controls.rotateUp(Math.PI / 4);
controls.noZoom = true;
controls.noPan = true;
var geometry = new THREE.CylinderGeometry( 0, 10, 30, 4, 1 );
var material = new THREE.MeshPhongMaterial( { color:0xffffff, shading: THREE.FlatShading } );
var mesh = new THREE.Mesh( geometry, material );
mesh.updateMatrix();
mesh.matrixAutoUpdate = false;
scene.add( mesh );
var light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 1, 1, 1 );
scene.add( light );
light = new THREE.DirectionalLight( 0x002288 );
light.position.set( -1, -1, -1 );
scene.add( light );
light = new THREE.AmbientLight( 0x222222 );
scene.add( light );
function setOrientationControls(e) {
if (!e.alpha) {
return;
}
controls = new THREE.DeviceOrientationControls(camera);
controls.connect();
controls.update();
element.addEventListener('click', fullscreen, false);
window.removeEventListener('deviceorientation', setOrientationControls, true);
}
window.addEventListener('deviceorientation', setOrientationControls, true);
window.addEventListener('resize', resize, false);
setTimeout(resize, 1);
}
The OrbitControls method on desktop works perfectly: by dragging with the mouse, the screen orbits around the pyramid. On mobile using DeviceOrientationControls however, this effect is entirely lost and instead the camera moves freely at (0, 0, 0). I tried doing as a previous question suggested and replacing the camera with scene such that:
controls = new THREE.DeviceOrientationControls(scene);
however this does not work at all and nothing moves when the device is rotated. What do I need to change to replicate OrbitControls behavior with the motion captured by DeviceOrientationControls?
To create a deviceorientation orbit controler, like you see on this demo, http://novak.us/labs/UmDemo/; It involves modifying the existing OrbitControls.js.
The file changes can be seen in this commit on github: https://github.com/snovak/three.js/commit/f6542ab3d95b1c746ab4d39ab5d3253720830dd3
I've been meaning to do a pull request for months. Just haven't gotten around to it. Needs a bunch of clean up.
You can download my modified OrbitControls.js here (I haven't merged in months either, results may vary): https://raw.githubusercontent.com/snovak/three.js/master/examples/js/controls/OrbitControls.js
Below is how you would implement the modified OrbitControls in your own scripts:
this.controls = new THREE.OrbitControls( camera, document.getElementById('screen') ) ;
controls.tiltEnabled = true ; // default is false. You need to turn this on to control with the gyro sensor.
controls.minPolarAngle = Math.PI * 0.4; // radians
controls.maxPolarAngle = Math.PI * 0.6; // radians
controls.noZoom = true ;
// How far you can rotate on the horizontal axis, upper and lower limits.
// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].
controls.minAzimuthAngle = - Math.PI * 0.1; // radians
controls.maxAzimuthAngle = Math.PI * 0.1; // radians
this.UMLogo = scene.children[1];
controls.target = UMLogo.position;
I hope that gets you where you want to be! :-)
To use the DeviceOrientationControls You must call controls.update() during your animation loop or the control will not update it's position based on device info.