Guide to implementing a mesh inside a WebGL renderer in Three JS by adding a canvas

Recently, I've been delving into Three JS after stumbling upon an interesting article about using augmented reality with a webcam. In my quest to experiment, I decided to incorporate a simple canvas into a scene where I had previously used webglrender. The goal was to insert a webcam stream for added effect. The article () mentioned the need to create a virtual scene rendered by the webglrenderer object as well as a physical reality scene (the webcam). Within my file testingthreejs.js, between lines 30 and 41, I implemented the code for creating this new virtual scene and inserting the canvas within my mesh object. However, to my disappointment, nothing seemed to happen. How can I successfully insert the canvas as a Mesh object? I attempted to avoid drawing a canvas directly, as it is believed that canvas rendering is slower than webgl rendering (I am also considering the use of the ray class). You can find my gist here: https://gist.github.com/fernandosg/75ec701c0295761a77e6, which includes the files testingthreejs.js and index.html. Thank you in advance for any assistance you can provide.

Answer №1

If you're interested in learning more about textures and canvas in Three.js, I recommend checking out the Stemkoski's website. It offers a variety of examples with detailed explanations that can be really helpful.

Specifically, you might find what you're looking for in this link. Be sure to take a look at the script provided on the page.

For a closer look at the code:

// Drawing text on canvas
var canvas1 = document.createElement('canvas');
var context1 = canvas1.getContext('2d');
context1.font = "Bold 40px Arial";
context1.fillStyle = "rgba(255,0,0,0.95)";
context1.fillText('Hello, world!', 0, 50);

var texture1 = new THREE.Texture(canvas1);
texture1.needsUpdate = true;

var material1 = new THREE.MeshBasicMaterial({ map: texture1, side:THREE.DoubleSide });
material1.transparent = true;

var mesh1 = new THREE.Mesh(
    new THREE.PlaneGeometry(canvas1.width, canvas1.height),
    material1
);
mesh1.position.set(0, 50, 0);
scene.add(mesh1);

// Drawing image on canvas
var canvas2 = document.createElement('canvas');
var context2 = canvas2.getContext('2d');
var texture2 = new THREE.Texture(canvas2);

var imageObj = new Image();
imageObj.src = "images/Dice-Blue-1.png";
imageObj.onload = function() {
    context2.drawImage(imageObj, 0, 0);
    if (texture2)
        texture2.needsUpdate = true;
};

var material2 = new THREE.MeshBasicMaterial({ map: texture2, side:THREE.DoubleSide });
material2.transparent = true;

var mesh2 = new THREE.Mesh(
    new THREE.PlaneGeometry(canvas2.width, canvas2.height),
    material2
);
mesh2.position.set(0, 50, -50);
scene.add(mesh2);

Answer №2

I feel like I'm making progress towards solving the issue at hand. It's great that I was able to successfully incorporate the canvas using a MeshBasicMaterial and PlaneGeometry. However, I encountered a problem where the canvas was drawn but the video was not rendered: canvas rendering issue

Here is the code snippet:

var canvas=document.createElement("canvas");
canvas.width=512;
canvas.height=512;  
var video=document.createElement("video");
streamVideo(video);
var canvasContext=canvas.getContext("2d");
var glCanvas=document.createElement("canvas");
var renderer_webgl=new THREE.WebGLRenderer({canvas:glCanvas});
renderer_webgl.setSize(512,512);
renderer_webgl.autoClear=false;
document.getElementById("container").appendChild(glCanvas);
var camera = new THREE.Camera();
var scene=new THREE.Scene();
var geometry=new THREE.PlaneGeometry(2,2,0);
var texture=new THREE.Texture(canvas);
var material=new THREE.MeshBasicMaterial({
            map:texture,
            depthTest:false,
            depthWrite:false
        });
var mesh=new THREE.Mesh(geometry,material);

canvas_draw=document.createElement("canvas");
        canvas_draw.width=128;
        canvas_draw.height=128;
        ctx=canvas_draw.getContext("2d");
        ctx.fillStyle = "#AAA";
        ctx.fillRect(1,1,20,25);
// INSERT THE CANVAS HERE
var texture_canvas=new THREE.Texture(canvas_draw);
texture_canvas.needsUpdate=true;
var basic_material_canvas=new THREE.MeshBasicMaterial({
    map:texture_canvas
});
var mesh_canvas=new THREE.Mesh(new THREE.PlaneGeometry(2,2,0),basic_material_canvas);
scene.add(mesh);
scene.add(mesh_canvas);
function renderScenes(){
    renderer_webgl.render(scene,camera);
}

function loop(){
    if(video.readyState===video.HAVE_ENOUGH_DATA){
        canvas.changed=true;
        canvasContext.drawImage(video,0,0);
        verifyDetector();
        texture.needsUpdate=true;
        texture_canvas.needsUpdate=true;
        renderScenes();
    }

    requestAnimationFrame(loop);
}
loop();

function verifyDetector(){
    detector = new AR.Detector();
    imageData = canvasContext.getImageData(0, 0, canvas.width, canvas.height);
    var markers = detector.detect(imageData);
    /*if(markers.length>0)
        canvasContext.drawImage(canvas_draw,markers[0].corners[0].x,markers[0].corners[0].y);               
        */
}

Why is this happening?

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

Is there a way for me to determine the exact coordinates of all buttons on a given webpage?

I came across this piece of code, but I'm a bit unsure about where exactly I should input it and how to adjust it to locate the position of each button. Additionally, I'm curious as to where the results (coordinates) will be shown? function find ...

Tips for simultaneously updating a value in multiple collections on firestore?

Currently, I am in the process of developing a forum application using Vue, which is essentially a replica of this platform. In this app, users can post questions, receive answers to those questions, and leave comments on those answers. Each question, answ ...

Incorporating Meteor js into an established user system

I'm completely new to the world of Meteor and I am looking to integrate it with my current system that relies on a MongoDB database. As I explore Meteor, I have discovered that there are packages like accounts-facebook and accounts-twitter which assis ...

Avoid activating jQuery functions based on certain screen widths for menu/navigation system

Recently, I've delved into the world of jQuery and attempted to create a simple menu system. The menu is designed to expand its submenu when hovering over the list item at screen widths larger than 480px, and to expand when clicking on the list item a ...

Dynamic SVG positioning

Looking for a way to make this svg shape relative to its containing div? Fiddle: http://jsfiddle.net/8421w8hc/20/ <div> <svg viewBox="0 0 1000 2112" style="" xmlns="http://www.w3.org/2000/svg" version="1.1"> <path id="ma" st ...

Creating a Step-by-Step Sequential Slider

How can I create a slider with 3 specific positions - 0, 50, and 100, while also implementing restrictions that prompt a confirmation message for each position? <input type='range'> ...

What is the best way to change the class of an input using jQuery when it is not empty?

Utilizing Bootstrap 4. I am working on a feature where I have four text inputs. If any of these inputs contain values, I want to add a specific class to a button. Upon clicking the button, my goal is to clear all input values and remove the aforementione ...

Issue: Unable to locate module 'js-yaml' while executing npm start command

Unable to locate module 'js-yaml' Require stack: D:\REACT NATIVE\portfolio\node_modules\cosmiconfig\dist\loaders.js D:\REACT NATIVE\portfolio\node_modules\cosmiconfig\dist\createExplore ...

What is the best way to transfer data from one function to another file in React without directly calling the component or using props?

filename - Header.jsx import { useEffect, useState } from 'react' import { getValue } from './Input' import TextField from '@mui/material/TextField'; export const Header = () => { const [search, setSearch] = useState( ...

Angular directive has issues with $compile functionality

This Angular directive automatically appends a new HTML item to the page every time my model changes: app.directive('helloWorld', function($compile) { return { restrict: 'AE', replace: true, scope:{ ...

Having trouble getting the jQuery AJAX post syntax to work properly

I am trying to send a post json value to another page using AJAX. However, when I include the "json" parameter in my POST request, the JavaScript code stops working. If I remove the "json" parameter, it works fine. I am still learning jQuery so any help ...

Utilize Browserify to Dynamically Load all Files within a Directory

As a newcomer to Browserify and JavaScript build systems in general, I find myself in a state of utter confusion. I have successfully set up Gulp for my builds, but recently I have been exploring Browserify to bundle my code, mainly to organize my code in ...

Fixing the Angular2 glitch: 'Uncaught TypeError: Cannot read property 'apply' of undefined'

Seeking solutions: How can I fix the "Uncaught TypeError: Cannot read property 'apply' of undefined" error that keeps showing up in the console of my Angular2 application? Any helpful insights are appreciated! ...

Feeling a bit lost on my first JQuery project, could use some

Yesterday, a kind person on this platform assisted me greatly in building my first validation from scratch. I have made significant progress since then. This is my first time working with JQuery, so I apologize in advance for my messy code. Everything work ...

Securing client-side code with AngularJS for enhanced security

It's a known fact that once browsers have downloaded frontend files, there's no way to hide code from the client. However, I've heard that clients can debug JavaScript code, add breakpoints, skip code lines (especially security checks), and ...

Implementing dropdown filtering for nested ng-repeats in Angular application

I currently have the following data structure set up: vm.years = [{ year: number, proevents: [{year: number, division: string, level: string, place: string, names: string}], nonproevents: [{year: number, division: string, level: string, place: st ...

What is the best way to handle errors in the front-end when receiving responses from expressjs?

Here is the issue that I am facing: //express server app.post('/register', (req, res) => { const { password, passwordConfirm } = req.body; if (password === passwordConfirm) { //... } else { ...

"Exclusive Mui sx styles will be applied only when a specific breakpoint

As I update my old mui styling to utilize the sx attribute, I've noticed the ability to specify styles for different breakpoints using sx = {{ someCssProp: { xs: ..., md: ... and so on. Prior to this, I had been using theme.breakpoints.only for some ...

Angular tutorial: Loading Excel file with header located on row n

Is there an easy way to read specific columns from an excel file in Angular, starting from a certain row as the header? Most of the code I found involves complex scripts, and I'm looking for a simpler solution. Below is the code I've come up wit ...