Reputation: 92
How do I access the standard camera in the three.js editor? I am trying to make a scene with a portal, in the scene I have two cameras (one inside the cube map) to project the image into the portal. In the case of a local project, everything works fine for me, but in the case of creating a similar scene in the editor, everything goes down a bad path. It seems to me that the reason is that when you click on PLAY, a new camera is created. I attach the script of the scene below. I hope that a solution will be found.
var mainMover, otherMover;
var otherCamera;
var portalA, portalB;
var portalRing;
function init() {
otherCamera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 1000);
//console.log(this.children[3].children[0]);
let ambientLight = new THREE.AmbientLight(0xcccccc, 1.00);
scene.add(ambientLight);
deltaTime = 0;
totalTime = 0;
let loader = new THREE.TextureLoader();
let defaultMaterial = new THREE.MeshBasicMaterial({
map: loader.load("https://raw.githubusercontent.com/stemkoski/AR-Examples/master/images/sphere-colored.png"),
color: 0x444444,
side: THREE.DoubleSide,
transparent: true
});
// Portal A ================================
portalA = new THREE.Mesh(
new THREE.CircleGeometry(1, 64),
defaultMaterial.clone()
);
portalA.material.opacity = 0.5;
portalA.position.set(-22, 0.5, -3);
portalA.rotation.y = Math.PI / 4;
portalA.layers.set(1);
scene.add(portalA);
portalRing = new THREE.Mesh(
new THREE.RingGeometry(1, 1.1, 64),
new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide, transparent: true })
);
portalRing.position.copy(portalA.position);
portalRing.rotation.copy(portalA.rotation);
portalRing.layers.set(0);
scene.add(portalRing);
mainMover = new THREE.Group();
mainMover.position.set(-21, 0.5, 0);
mainMover.add(camera);
mainMover.name = "mainMover";
scene.add(mainMover);
// Portal B - ================================
let skyMaterialArray2 = [
new THREE.MeshBasicMaterial({ map: loader.load("https://raw.githubusercontent.com/stemkoski/AR-Examples/master/images/mountain/posx.jpg"), side: THREE.BackSide }),
new THREE.MeshBasicMaterial({ map: loader.load("https://raw.githubusercontent.com/stemkoski/AR-Examples/master/images/mountain/negx.jpg"), side: THREE.BackSide }),
new THREE.MeshBasicMaterial({ map: loader.load("https://raw.githubusercontent.com/stemkoski/AR-Examples/master/images/mountain/posy.jpg"), side: THREE.BackSide }),
new THREE.MeshBasicMaterial({ map: loader.load("https://raw.githubusercontent.com/stemkoski/AR-Examples/master/images/mountain/negy.jpg"), side: THREE.BackSide }),
new THREE.MeshBasicMaterial({ map: loader.load("https://raw.githubusercontent.com/stemkoski/AR-Examples/master/images/mountain/posz.jpg"), side: THREE.BackSide }),
new THREE.MeshBasicMaterial({ map: loader.load("https://raw.githubusercontent.com/stemkoski/AR-Examples/master/images/mountain/negz.jpg"), side: THREE.BackSide }),
];
let skyMesh2 = new THREE.Mesh(
new THREE.BoxGeometry(30, 30, 30),
skyMaterialArray2);
skyMesh2.position.x = 20;
scene.add(skyMesh2);
portalB = new THREE.Mesh(
new THREE.CircleGeometry(1, 64),
defaultMaterial.clone()
);
portalB.material.opacity = 0.5;
portalB.position.set(24, 0.5, -5);
portalB.rotation.y = -Math.PI / 4;
portalB.layers.set(2);
scene.add(portalB);
otherMover = new THREE.Group();
otherMover.add(otherCamera);
scene.add(otherMover);
}
function update() {
portalRing.material.color.setHSL(totalTime / 10 % 1, 1, 0.75);
let relativePosition = portalA.worldToLocal(mainMover.position.clone());
otherMover.position.copy(portalB.localToWorld(relativePosition));
let relativeRotation = mainMover.quaternion.clone().multiply(portalA.quaternion.clone().invert());
otherMover.quaternion.copy(relativeRotation.multiply(portalB.quaternion));
otherCamera.rotation.x = camera.rotation.x;
render()
}
function render() {
camera.layers.enable(0);
camera.layers.enable(1);
renderer.render(scene, camera);
let gl = renderer.getContext();
renderer.clear(true, true, true);
renderer.autoClear = false;
// FIRST PASS (enable stencil buffer)
gl.enable(gl.STENCIL_TEST);
camera.layers.set(1);
gl.stencilFunc(gl.ALWAYS, 1, 0xff);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
gl.stencilMask(0xff);
gl.colorMask(false, false, false, false);
gl.depthMask(false);
renderer.render(scene, camera);
//SECOND PASS
let portalToCamera = new THREE.Vector3().subVectors(mainMover.position.clone(), portalA.position.clone()); // applyQuaternion( mainMover.quaternion );
let normalPortal = new THREE.Vector3(0, 0, 1).applyQuaternion(portalA.quaternion);
let clipSide = -Math.sign(portalToCamera.dot(normalPortal));
let clipNormal = new THREE.Vector3(0, 0, clipSide).applyQuaternion(portalB.quaternion);
let clipPoint = portalB.position;
let clipPlane = new THREE.Plane().setFromNormalAndCoplanarPoint(clipNormal, clipPoint);
renderer.clippingPlanes = [clipPlane];
gl.colorMask(true, true, true, true);
gl.depthMask(true);
gl.stencilFunc(gl.EQUAL, 1, 0xff);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
otherCamera.layers.set(0);
renderer.render(scene, otherCamera);
renderer.clippingPlanes = [];
//THIRD PASS
gl.disable(gl.STENCIL_TEST);
gl.colorMask(false, false, false, false);
gl.depthMask(true);
renderer.clear(false, true, false);
renderer.render(scene, camera);
//FINAL PASS
gl.colorMask(true, true, true, true);
gl.depthMask(true);
camera.layers.set(0);
renderer.render(scene, camera);
renderer.autoClear = true;
}
UPDATE: I added a helper for the camera, so the main camera should be in place of the cube. But, for some reason, when PLAYING, I find myself not in the place of this cube... (just create a mesh: let mainCameraMesh = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), new THREE.MeshBasicMaterial());
Upvotes: 1
Views: 923
Reputation: 31026
When you create a script in the three.js
editor, you have access to certain global variables within the update()
function. Next to the renderer and scene, you can also access the perspective camera. Just try this:
function update( event ) {
console.log( camera );
}
Upvotes: 0