Skip to content

Commit

Permalink
- Optimize VRRenderer object use
Browse files Browse the repository at this point in the history
- Fix mock VR device not adjusting FOV/aspect correctly
Rate limit · GitHub

Access has been restricted

You have triggered a rate limit.

Please wait a few minutes before you try again;
in some cases this may take up to an hour.

unconed committed Sep 17, 2014
1 parent e0c62d1 commit 60bd225
Showing 6 changed files with 138 additions and 74 deletions.
50 changes: 33 additions & 17 deletions build/threestrap-extra.js
Original file line number Diff line number Diff line change
@@ -1333,7 +1333,7 @@ THREE.Bootstrap.registerPlugin('vr', {
device: null,
},

listen: ['window.load', 'pre', 'render', 'this.change'],
listen: ['window.load', 'pre', 'render', 'resize', 'this.change'],

install: function (three) {
three.VR = this.api({
@@ -1350,16 +1350,22 @@ THREE.Bootstrap.registerPlugin('vr', {
delete three.VR
},

mocks: function (camera) {
var aspect = camera.aspect;
var fov = camera.fov;
mocks: function (three) {
// Fake VR device for cardboard / desktop

var fovX = Math.atan(Math.tan(fov * Math.PI / 360) * aspect / 2) * 360 / Math.PI;
var fovY = fov;
// Interpuppilary distance
var ipd = 0.03;

// Fake VR device for cardboard / desktop
var getEyeTranslation = function (key) { return {left: {x: -0.03, y: 0, z: 0}, right: {x: 0.03, y: 0, z: 0}}[key]; };
var getRecommendedEyeFieldOfView = function (key) { return {
// Symmetric eye FOVs (Cardboard style)
var getEyeTranslation = function (key) { return {left: {x: -ipd, y: 0, z: 0}, right: {x: ipd, y: 0, z: 0}}[key]; };
var getRecommendedEyeFieldOfView = function (key) {
var camera = three.camera;
var aspect = camera && camera.aspect || 16/9;
var fov = camera && camera.fov || 65;
var fovX = Math.atan(Math.tan(fov * Math.PI / 360) * aspect / 2) * 360 / Math.PI;
var fovY = fov;

return {
left: {
"rightDegrees": fovX,
"leftDegrees": fovX,
@@ -1406,7 +1412,7 @@ THREE.Bootstrap.registerPlugin('vr', {
}
else {
console.warn('No native VR support detected.');
callback(this.mocks(three.camera), three);
callback(this.mocks(three), three);
}
},

@@ -1489,18 +1495,28 @@ THREE.Bootstrap.registerPlugin('vr', {

},

resize: function (event, three) {
if (this.active) {
// Reinit HMD projection
this.renderer.initialize();
}
},

render: function (event, three) {
if (three.scene && three.camera) {
var renderer = this.active ? this.renderer : three.renderer;

// Cleanup leftover renderer state when swapping back to normal
if (this.last != renderer && renderer == three.renderer) {
var dpr = renderer.devicePixelRatio;
var width = renderer.domElement.width / dpr;
var height = renderer.domElement.height / dpr;
renderer.enableScissorTest(false);
renderer.setViewport(0, 0, width, height);
if (this.last != renderer) {
if (renderer == three.renderer) {
// Cleanup leftover renderer state when swapping back to normal
var dpr = renderer.devicePixelRatio;
var width = renderer.domElement.width / dpr;
var height = renderer.domElement.height / dpr;
renderer.enableScissorTest(false);
renderer.setViewport(0, 0, width, height);
}
}

this.last = renderer;

renderer.render(three.scene, three.camera);
2 changes: 1 addition & 1 deletion build/threestrap-extra.min.js

Large diffs are not rendered by default.

50 changes: 33 additions & 17 deletions build/threestrap.js
Original file line number Diff line number Diff line change
@@ -9109,7 +9109,7 @@ THREE.Bootstrap.registerPlugin('vr', {
device: null,
},

listen: ['window.load', 'pre', 'render', 'this.change'],
listen: ['window.load', 'pre', 'render', 'resize', 'this.change'],

install: function (three) {
three.VR = this.api({
@@ -9126,16 +9126,22 @@ THREE.Bootstrap.registerPlugin('vr', {
delete three.VR
},

mocks: function (camera) {
var aspect = camera.aspect;
var fov = camera.fov;
mocks: function (three) {
// Fake VR device for cardboard / desktop

var fovX = Math.atan(Math.tan(fov * Math.PI / 360) * aspect / 2) * 360 / Math.PI;
var fovY = fov;
// Interpuppilary distance
var ipd = 0.03;

// Fake VR device for cardboard / desktop
var getEyeTranslation = function (key) { return {left: {x: -0.03, y: 0, z: 0}, right: {x: 0.03, y: 0, z: 0}}[key]; };
var getRecommendedEyeFieldOfView = function (key) { return {
// Symmetric eye FOVs (Cardboard style)
var getEyeTranslation = function (key) { return {left: {x: -ipd, y: 0, z: 0}, right: {x: ipd, y: 0, z: 0}}[key]; };
var getRecommendedEyeFieldOfView = function (key) {
var camera = three.camera;
var aspect = camera && camera.aspect || 16/9;
var fov = camera && camera.fov || 65;
var fovX = Math.atan(Math.tan(fov * Math.PI / 360) * aspect / 2) * 360 / Math.PI;
var fovY = fov;

return {
left: {
"rightDegrees": fovX,
"leftDegrees": fovX,
@@ -9182,7 +9188,7 @@ THREE.Bootstrap.registerPlugin('vr', {
}
else {
console.warn('No native VR support detected.');
callback(this.mocks(three.camera), three);
callback(this.mocks(three), three);
}
},

@@ -9265,18 +9271,28 @@ THREE.Bootstrap.registerPlugin('vr', {

},

resize: function (event, three) {
if (this.active) {
// Reinit HMD projection
this.renderer.initialize();
}
},

render: function (event, three) {
if (three.scene && three.camera) {
var renderer = this.active ? this.renderer : three.renderer;

// Cleanup leftover renderer state when swapping back to normal
if (this.last != renderer && renderer == three.renderer) {
var dpr = renderer.devicePixelRatio;
var width = renderer.domElement.width / dpr;
var height = renderer.domElement.height / dpr;
renderer.enableScissorTest(false);
renderer.setViewport(0, 0, width, height);
if (this.last != renderer) {
if (renderer == three.renderer) {
// Cleanup leftover renderer state when swapping back to normal
var dpr = renderer.devicePixelRatio;
var width = renderer.domElement.width / dpr;
var height = renderer.domElement.height / dpr;
renderer.enableScissorTest(false);
renderer.setViewport(0, 0, width, height);
}
}

this.last = renderer;

renderer.render(three.scene, three.camera);
4 changes: 2 additions & 2 deletions build/threestrap.min.js

Large diffs are not rendered by default.

50 changes: 33 additions & 17 deletions src/extra/vr.js
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ THREE.Bootstrap.registerPlugin('vr', {
device: null,
},

listen: ['window.load', 'pre', 'render', 'this.change'],
listen: ['window.load', 'pre', 'render', 'resize', 'this.change'],

install: function (three) {
three.VR = this.api({
@@ -25,16 +25,22 @@ THREE.Bootstrap.registerPlugin('vr', {
delete three.VR
},

mocks: function (camera) {
var aspect = camera.aspect;
var fov = camera.fov;
mocks: function (three) {
// Fake VR device for cardboard / desktop

var fovX = Math.atan(Math.tan(fov * Math.PI / 360) * aspect / 2) * 360 / Math.PI;
var fovY = fov;
// Interpuppilary distance
var ipd = 0.03;

// Fake VR device for cardboard / desktop
var getEyeTranslation = function (key) { return {left: {x: -0.03, y: 0, z: 0}, right: {x: 0.03, y: 0, z: 0}}[key]; };
var getRecommendedEyeFieldOfView = function (key) { return {
// Symmetric eye FOVs (Cardboard style)
var getEyeTranslation = function (key) { return {left: {x: -ipd, y: 0, z: 0}, right: {x: ipd, y: 0, z: 0}}[key]; };
var getRecommendedEyeFieldOfView = function (key) {
var camera = three.camera;
var aspect = camera && camera.aspect || 16/9;
var fov = camera && camera.fov || 65;
var fovX = Math.atan(Math.tan(fov * Math.PI / 360) * aspect / 2) * 360 / Math.PI;
var fovY = fov;

return {
left: {
"rightDegrees": fovX,
"leftDegrees": fovX,
@@ -81,7 +87,7 @@ THREE.Bootstrap.registerPlugin('vr', {
}
else {
console.warn('No native VR support detected.');
callback(this.mocks(three.camera), three);
callback(this.mocks(three), three);
}
},

@@ -164,18 +170,28 @@ THREE.Bootstrap.registerPlugin('vr', {

},

resize: function (event, three) {
if (this.active) {
// Reinit HMD projection
this.renderer.initialize();
}
},

render: function (event, three) {
if (three.scene && three.camera) {
var renderer = this.active ? this.renderer : three.renderer;

// Cleanup leftover renderer state when swapping back to normal
if (this.last != renderer && renderer == three.renderer) {
var dpr = renderer.devicePixelRatio;
var width = renderer.domElement.width / dpr;
var height = renderer.domElement.height / dpr;
renderer.enableScissorTest(false);
renderer.setViewport(0, 0, width, height);
if (this.last != renderer) {
if (renderer == three.renderer) {
// Cleanup leftover renderer state when swapping back to normal
var dpr = renderer.devicePixelRatio;
var width = renderer.domElement.width / dpr;
var height = renderer.domElement.height / dpr;
renderer.enableScissorTest(false);
renderer.setViewport(0, 0, width, height);
}
}

this.last = renderer;

renderer.render(three.scene, three.camera);
56 changes: 36 additions & 20 deletions vendor/renderers/VRRenderer.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
"use strict";

/**
* VRRenderer
*
* @author wwwtyro https://github.com/wwwtyro
* @author unconed https://github.com/unconed
*/
THREE.VRRenderer = function(renderer, hmd) {

var self = this;
@@ -22,13 +28,12 @@ THREE.VRRenderer = function(renderer, hmd) {
};
}

self.FovPortToProjection = function(fov, rightHanded /* = true */ , zNear /* = 0.01 */ , zFar /* = 10000.0 */ ) {
self.FovPortToProjection = function(matrix, fov, rightHanded /* = true */ , zNear /* = 0.01 */ , zFar /* = 10000.0 */ ) {
rightHanded = rightHanded === undefined ? true : rightHanded;
zNear = zNear === undefined ? 0.01 : zNear;
zFar = zFar === undefined ? 10000.0 : zFar;
var handednessScale = rightHanded ? -1.0 : 1.0;
var mobj = new THREE.Matrix4();
var m = mobj.elements;
var m = matrix.elements;
var scaleAndOffset = self.FovToNDCScaleOffset(fov);
m[0 * 4 + 0] = scaleAndOffset.scale[0];
m[0 * 4 + 1] = 0.0;
@@ -46,40 +51,51 @@ THREE.VRRenderer = function(renderer, hmd) {
m[3 * 4 + 1] = 0.0;
m[3 * 4 + 2] = handednessScale;
m[3 * 4 + 3] = 0.0;
mobj.transpose();
return mobj;
matrix.transpose();
}

self.FovToProjection = function(fov, rightHanded /* = true */ , zNear /* = 0.01 */ , zFar /* = 10000.0 */ ) {
self.FovToProjection = function(matrix, fov, rightHanded /* = true */ , zNear /* = 0.01 */ , zFar /* = 10000.0 */ ) {
var fovPort = {
upTan: Math.tan(fov.upDegrees * Math.PI / 180.0),
downTan: Math.tan(fov.downDegrees * Math.PI / 180.0),
leftTan: Math.tan(fov.leftDegrees * Math.PI / 180.0),
rightTan: Math.tan(fov.rightDegrees * Math.PI / 180.0)
};
return self.FovPortToProjection(fovPort, rightHanded, zNear, zFar);
return self.FovPortToProjection(matrix, fovPort, rightHanded, zNear, zFar);
}

var right = new THREE.Vector3();

var cameraLeft = new THREE.PerspectiveCamera();
var cameraRight = new THREE.PerspectiveCamera();

self.render = function(scene, camera) {
var cameraLeft = camera.clone();
var cameraRight = camera.clone();
cameraLeft.projectionMatrix = self.FovToProjection(self.fovLeft, true, camera.near, camera.far);
cameraRight.projectionMatrix = self.FovToProjection(self.fovRight, true, camera.near, camera.far);
var right = new THREE.Vector3(1, 0, 0);
self.FovToProjection(cameraLeft .projectionMatrix, self.fovLeft , true, camera.near, camera.far);
self.FovToProjection(cameraRight.projectionMatrix, self.fovRight, true, camera.near, camera.far);

right.set(self.halfIPD, 0, 0);
right.applyQuaternion(camera.quaternion);
cameraLeft.position.sub(right.clone().multiplyScalar(self.halfIPD));
cameraRight.position.add(right.clone().multiplyScalar(self.halfIPD));
renderer.enableScissorTest(true);
var dpr = renderer.devicePixelRatio;
var width = renderer.domElement.width / 2 / dpr;

cameraLeft .position.copy(camera.position).sub(right);
cameraRight.position.copy(camera.position).add(right);

cameraLeft .quaternion.copy(camera.quaternion);
cameraRight.quaternion.copy(camera.quaternion);

var dpr = renderer.devicePixelRatio;
var width = renderer.domElement.width / 2 / dpr;
var height = renderer.domElement.height / dpr;

renderer.enableScissorTest(true);

renderer.setViewport(0, 0, width, height);
renderer.setScissor(0, 0, width, height);
renderer.setScissor (0, 0, width, height);
renderer.render(scene, cameraLeft);

renderer.setViewport(width, 0, width, height);
renderer.setScissor(width, 0, width, height);
renderer.setScissor (width, 0, width, height);
renderer.render(scene, cameraRight);
}

self.initialize();
}
}

0 comments on commit 60bd225

Please sign in to comment.