Displaying an iframe on an AR marker with the help of CSS3DRenderer and jsartoolkit

I am trying to achieve an interesting effect by overlaying a html iframe on top of an augmented reality marker. However, I seem to be facing some issues with the CSS3DRenderer not producing the same result as the WebGLRenderer and I'm struggling to pinpoint where I might be making a mistake.

While the WebGLRenderer works perfectly, smoothly rendering the mesh following the marker, the CSS3DRenderer seems to position the iframe at the center of the video, inverted and unscaled, rotating in the opposite direction.

Thanks to the amazing capabilities of three.js and artoolkit, I have put together some test code using video input and both renderers.

new Promise(function(resolve,reject) {
    var source = document.createElement('video');

    source.autoplay = true;
    source.playsinline = true;
    source.controls = false;
    source.loop = true;
    source.onplay = function(event) {
        resolve(source);
    }
    source.src = 'data/output_4.ogg';

    document.body.appendChild(source);
}).then(function(source) {
    var scene = new THREE.Scene();

    var camera = new THREE.Camera();
    camera.matrixAutoUpdate = false;

    scene.add(camera);

    var material = new THREE.MeshNormalMaterial({
        transparent : true,
        opacity : 0.5,
        side : THREE.DoubleSide
    });

    var geometry = new THREE.PlaneGeometry(1,1);
    var mesh = new THREE.Mesh(geometry,material);
    // mesh.matrixAutoUpdate = false;

    scene.add(mesh);

    var renderer = new THREE.WebGLRenderer({
        antialias : true,
        alpha : true
    });

    renderer.setSize(source.videoWidth,source.videoHeight);
    renderer.setClearColor(new THREE.Color('lightgrey'),0);

    document.body.appendChild(renderer.domElement);

    /*\

    cssRenderer

    \*/

    var cssRenderer = new THREE.CSS3DRenderer();
    cssRenderer.setSize(source.videoWidth,source.videoHeight);

    var cssScene = new THREE.Scene();

    var iframe = document.createElement("iframe");
    iframe.src = "/data/index.html";
    iframe.style.background = "rgb(0,0,0)";

    var iframe3D = new THREE.CSS3DObject(iframe);
    // iframe3D.matrixAutoUpdate = false;

    cssScene.add(iframe3D);

    document.body.appendChild(cssRenderer.domElement);

    /*\

    arController

    \*/

    var cameraParameters = new ARCameraParam();

    var arController = null;

    cameraParameters.onload = function() {
        arController = new ARController(source.videoWidth,source.videoHeight,cameraParameters);

        arController.addEventListener("getMarker",function(event) {
            var modelViewMatrix = new THREE.Matrix4().fromArray(event.data.matrix);

            camera.matrix.getInverse(modelViewMatrix);
            // mesh.matrix.copy(modelViewMatrix);
            // iframe3D.matrix.copy(modelViewMatrix);
        });

        var cameraViewMatrix = new THREE.Matrix4().fromArray(arController.getCameraMatrix());

        camera.projectionMatrix.copy(cameraViewMatrix);
    }

    cameraParameters.load("data/camera_para.dat");

    /*\

    animate

    \*/

    requestAnimationFrame(function animate() {
        requestAnimationFrame(animate);

        if (!arController) {
            return;
        }

        arController.process(source);

        renderer.render(scene,camera);
        cssRenderer.render(cssScene,camera);
    });
});

I had thought that adjusting the camera instead of the object might help solve the issue, but it seems like there could be a missing matrix transformation that needs to be applied.

Answer №1

It seems like there may have been an issue with the camera's field of view parameters or potentially the transform matrix being overwritten, but regardless, I was unable to pinpoint the exact problem. As a result, I've come up with an alternative solution that does not rely on CSS3DRenderer or THREE.js.

Instead, we can utilize the marker data coordinates themselves to generate a projection matrix. Huge thanks go out to this specific post, which supplied most of the necessary code.

function adjugate(m) { // Calculate the adjugate of m
    return [
        m[4]*m[8]-m[7]*m[5],m[7]*m[2]-m[1]*m[8],m[1]*m[5]-m[4]*m[2],
        m[6]*m[5]-m[3]*m[8],m[0]*m[8]-m[6]*m[2],m[3]*m[2]-m[0]*m[5],
        m[3]*m[7]-m[6]*m[4],m[6]*m[1]-m[0]*m[7],m[0]*m[4]-m[3]*m[1]
    ];
}

// Other functions and implementation details continue...

Answer №2

Even though this answer is 4 years late, it may still be helpful to someone out there.

I've come up with a different solution that might be of interest to you. Feel free to take a look at it here: https://github.com/jonathanneels/QrA

To sum it up; QrA utilizes tilt-js for creating 3D effects (parallax) and AR.js a-box as the initial object. The iframe is manipulated by the functions in tilt.js, while the position, scale, and rotation of the AR cube serve as points of reference.

Hope you find it enjoyable!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to use Shadcn to incorporate a calendar that takes up half of my website?

Currently, I am in the process of developing a scheduling appointment system. My main challenge is getting the calendar to take up half of my page's space. Despite my attempts to adjust its height and width, I have not been successful in seeing any ch ...

Managing Server Crashes in Node.js

Is there a way to automatically update the database whenever my node.js server crashes or stops? Similar to how try{}catch(){}finally(){} works in JAVA. I am new to this. Does Node emit any events before shutting down so that I can run my function then? ...

Retrieving custom data attributes from slides within a slick carousel

After the recent Slick carousel update to version 1.4, there have been changes in how data attributes are accessed from the current slide. The previous method that was working fine is as follows: onAfterChange: function(slide, index) { $('.projec ...

How many server queries does a single web application require?

As someone new to web app development, my main goal is to optimize speed as much as possible. I am faced with two options: The first option is to fetch data from the database individually every time a refresh is needed in the app. Alternatively, I c ...

Accessing a variable from an external JavaScript file using jQuery

Can someone help me out with this issue I'm facing? I am having trouble getting a string returned to a variable in my embedded Javascript code. token.js: function token () { return "mysecretstring"; } HTML Code: <!DOCTYPE html> <h ...

Combining the Powers of Angular JS and Symfony2

Currently working on a project involving Symfony2 and in need of some advice. Considering a hybrid application approach in two ways: a) Using a traditional form with CSRF Token for the Login Page handled by Symfony2, and b) Inner pages (potentially module ...

What would be the counterpart of setLocale in Yup for the zod library?

How can I set default custom error messages for Zod validation? If I want to use i18n for error messages in Yup, I would do the following: import { t } from "i18next"; import * as yup from "yup"; import "./i18next"; yup.setL ...

Investigate the presence of a vertical scrollbar using JQuery or JavaScript

Within an HTML report, I have applied the style "overflow:auto" to allow for dynamic data filling. I am now facing the challenge of detecting whether a vertical scrollbar exists within the report. After scouring various forums for solutions, I came across ...

Transforming a high chart into an image and transmitting it to the server through an ajax request

I am looking for a way to save multiple charts as PDF files on the server using an AJAX call. Each chart is rendered in a distinct container on the same page, and I need to convert them into images before sending them to the server for export. Any assist ...

What is the best way to activate the default action/event of an HTML link (anchor element)?

Is there a way to programmatically trigger the default action of an HTML link using JavaScript or jQuery? Essentially simulating a user click on the link. Simply using .click() does not seem to do the trick. $('#alink').click(); // nothing happ ...

A guide on how to efficiently retrieve a string within a function in a native module in a React Native

I'm currently tackling a function related to the native elements of iOS that is coded in Objective-C, My goal is to create a method that will output a string in Objective-C, However, I've hit a roadblock while trying to implement this method: T ...

The Vue.js application is experiencing issues with displaying Google Maps functionalities

I have developed an application using Vue.js in Monaca and Cordova with onsenUI. My goal is to display my location on a Google map within the page. I attempted to achieve this by utilizing the npm package named vue2-google-maps, but unfortunately, it' ...

Is there a way to customize Angular's number filter?

I'm trying to achieve a consistent number format with Angular's number filter, regardless of the localization selected. After inspecting the Angular source code on GitHub, I found the implementation of the filter to be like this: function number ...

Exploring JavaScript Regular Expressions in Internet Explorer 11

I am attempting to eliminate all non-digit characters from a string using JavaScript. While this code works properly in FF and Chrome, it does not work in IE11 and no characters are removed. var prunedText = pastedText.replace(/[^\d\.]/g,""); ...

Creating a "Container" component in Vue.js step by step

As a newcomer to Vue, I am facing a challenge in implementing a wrapper component similar to React's 'Wrapper' component. Specifically, I want to create a reusable datagrid component using a 3rd-party some-table component and a pagination co ...

Initially, the OWL Carousel image is not displaying correctly due to incorrect sizing

I am currently working with OWL Carousel and have implemented a code that displays one image at a time, with the next image sliding in every 15 seconds. The width is set to occupy 100% of the screen and I have configured the JavaScript accordingly so that ...

Issue encountered: Object is not functioning properly with Node.js AuthenticationExplanation: A TypeError occurred

As a newcomer to Stack Overflow, I am doing my best to ask this question clearly. I am currently following a tutorial step by step ( http://scotch.io/tutorials/javascript/easy-node-authentication-setup-and-local ) but I encountered an issue after the thir ...

I'm encountering an issue in JavaScript while attempting to convert the following string into a JSON object. Can anyone assist in identifying the problem with this string?

How can I correct this string to make it a valid JavaScript JSON object? txt = '{"Categories" : [{"label":"petifores","id":"1"}, {"label":"wedding cake","id":"2"}, {"label":"shapes of cakes","id":"3"}, ...

Console not displaying any logs following the occurrence of an onClick event

One interesting feature I have on my website is an HTML div that functions as a star rating system. Currently, I am experimenting with some JavaScript code to test its functionality. My goal is for the console to log 'hello' whenever I click on ...

Combine the jQuery selectors :has() and :contains() for effective element targeting!

I am trying to select a list item element that has a label element inside it. My goal is to use the :has() selector to target the list item and then match text within the label using the :contains() selector. Can I achieve this in a single line of jQuery ...