Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making portals with ThreeJS

Tags:

three.js

Im trying to make portals with ThreeJS. I found this page Mini-Portals That explains how to make portals with OpenGL. So i tried to replicate the portal view function in TJS. Now this is my result:

Left is normal camera, right is the portalviewfunction

The left portal(right camera) is normal camera and right portal(left camera) is the view matrix gotten from tutorial. As you can see the portal view on the right is quite weird.

The main issue here is that the scaling of the images is all wrong and the angle im seeing the images in portal is wrong. Currently its flat and show where i pointed the camera, but what i want is portal where the scaling is correct(image on portal is same scale as the world itself) and what is see in portal depends on the angle where im watching.

What am i doing wrong and what should i do to fix it?

like image 655
Marko Taht Avatar asked Oct 20 '16 16:10

Marko Taht


People also ask

What can you do with Threejs?

js is a cross-browser JavaScript library and application programming interface (API) used to create and display animated 3D computer graphics in a web browser using WebGL.

Is Threejs good for games?

Three. js is a powerful library for creating three-dimensional models and games. With just a few lines of JavaScript, you can create anything from simple 3D patterns to photorealistic, real-time scenes. You can build simple and complex 3D geometrics, animate and move objects through a lifelike scene, and more.

Is Threejs open source?

Three. js is an open source JavaScript library that is used to display the graphics, 3D and 2D objects on the web browser.


2 Answers

For people who want a great Portal system with Three.js : https://github.com/markotaht/Portals

like image 66
DevMultiTech Avatar answered Oct 14 '22 08:10

DevMultiTech


Its been a while. But i have found a way to do what i needed. The 4th parameter in not needed. Basically i send camera, and my 2 portal objects(Meshes) to my function. Instead of using the matrix multiplication way(does not work in ThreeJS because ThreeJS does some weird stuff with it) I split the matrices into pieces. Then manually calculate the new position and rotation and construct the new matrix from it. And i set this new matrix as my cameras worldMatrix. Voila a working portal. Next step is oblique view fusrum, because we want our nearplane to be the portal otherwise we can have some objects between the camera and portal.

And the rendering procedure itself uses stencil buffer to render the portals correctly. If anyone needs, this will help you: https://th0mas.nl/2013/05/19/rendering-recursive-portals-with-opengl/

function portal_view(camera, src_portal, dst_portal, kordaja) {
                src_portal.updateMatrixWorld()
                dst_portal.updateMatrixWorld()
                camera.updateMatrixWorld()

                var camerapos = new THREE.Vector3();
                var camerarot = new THREE.Quaternion();
                var camerascale = new THREE.Vector3();
                camera.matrix.decompose(camerapos,camerarot,camerascale);

                var srcpos = new THREE.Vector3();
                var srcquat = new THREE.Quaternion();
                var srcscale = new THREE.Vector3();
                src_portal.matrix.decompose(srcpos, srcquat, srcscale);

                var destquat = new THREE.Quaternion();
                var destpos = new THREE.Vector3();
                var destscale = new THREE.Vector3();
                dst_portal.matrix.decompose(destpos,destquat,destscale);

                var diff = camerapos.clone().sub(srcpos);

                var ydiff = src_portal.rotation.y - dst_portal.rotation.y - Math.PI;
                diff.applyAxisAngle(new THREE.Vector3(0,1,0),-ydiff);
                var newcampos = diff.add(destpos);
                var yrotvec = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,1,0),-ydiff);
                console.log(yrotvec)
                srcquat = srcquat.multiply(destquat.inverse());

                camerarot = camerarot.multiply(yrotvec);

                var inverse_view_to_source = new THREE.Matrix4();
                inverse_view_to_source.compose(newcampos,camerarot,camerascale);

                return inverse_view_to_source;
            }

NOTE: I moved my answer to the answers so i can mark an answer.

like image 29
Marko Taht Avatar answered Oct 14 '22 09:10

Marko Taht