Is it possible to replace the image connected to a ThreeJS mesh without needing to remove the mesh object entirely?

I'm working on a ThreeJS game that utilizes cubes as the main play pieces. Each cube has a custom image loaded from a specific JPG URL on one of its faces. Now, when a new game starts, I want to be able to simply swap out the JPG image assigned to each cube face. Is there a way to achieve this without having to completely rebuild each cube? I'd prefer to avoid that because cleaning up a ThreeJS scene and releasing GPU resources can be quite complex according to my research (including the need to remove all references to mesh components).

Here is an example of how I create the cubes:

function makeCardCube(cardImageUrl, textureBackSide, locX, locY, locZ, width, height) {
    let thickness = 0.01 * width;
    let cubeGeometry = new THREE.BoxBufferGeometry(width, thickness, height);
    let loader = new THREE.TextureLoader();

    let materialArray = [
        new THREE.MeshBasicMaterial( { map: loader.load('/images/cards/white-square-400x400.png') } ),
        new THREE.MeshBasicMaterial( { map: loader.load('/images/cards/white-square-400x400.png') } ),
        // Card face.
        new THREE.MeshBasicMaterial( { map: loader.load(cardImageUrl) } ),
        // Card back side.
        new THREE.MeshBasicMaterial(
            {
                map: textureBackSide
            }
        ),

        new THREE.MeshBasicMaterial( { map: loader.load('/images/cards/white-square-400x400.png') } ),
        new THREE.MeshBasicMaterial( { map: loader.load('/images/cards/white-square-400x400.png') } ),
    ];

    cube = new THREE.Mesh( cubeGeometry, materialArray );
    cube.position.set(locX, locY, locZ);
    // Rotate the card 90 degrees upwards around the X axis so it faces the camera.
    cube.rotateX(THREE.Math.degToRad(90));

    return cube;
}

Answer №1

Swapping out the JPG image assigned to one face of each cube is a key feature I am looking for.

The typical way to achieve this is by creating a new instance of Texture and then assigning it to Material.map. It is also advisable to free up memory related to the previous texture by calling Texture.dispose() if you no longer need it.

Below is a comprehensive live example demonstrating how to replace textures:

var camera, scene, renderer, mesh;

init();
animate();

function init() {

    camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
    camera.position.z = 5;

    scene = new THREE.Scene();

    geometry = new THREE.BoxGeometry();

    var loader = new THREE.TextureLoader();
    var texture = loader.load( 'https://threejs.org/examples/textures/crate.gif' );

    var material = [
        new THREE.MeshBasicMaterial( { map: texture } ),
        new THREE.MeshBasicMaterial( { map: texture } ),
        new THREE.MeshBasicMaterial( { map: texture } ),
        new THREE.MeshBasicMaterial( { map: texture } ),
        new THREE.MeshBasicMaterial( { map: texture } ),
        new THREE.MeshBasicMaterial( { map: texture } )
    ];

    mesh = new THREE.Mesh( geometry, material );
    scene.add( mesh );

    renderer = new THREE.WebGLRenderer( { antialias: true } );
    renderer.setSize( window.innerWidth, window.innerHeight );
    document.body.appendChild( renderer.domElement );

    // change the material of one cube side by replacing its texture

    setTimeout( () => {

        var newTexture = loader.load( 'https://threejs.org/examples/textures/colors.png' );
        material[ 0 ].map = newTexture;

        // in this case we do not call dispose() because crate.gif is still used by five other sides of the cube 

    }, 1000 );

}

function animate() {

    requestAnimationFrame( animate );

    mesh.rotation.x += 0.01;
    mesh.rotation.y += 0.02;

    renderer.render( scene, camera );

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.js"></script>

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

Leveraging Parameters from URL in Javascript

I'm facing an issue with my area shape, the href="/kosmetikstudios/deutschland/Bayern" tag seems to be causing a problem. I want to utilize the parameter "Bayern" (which is the last parameter in the URL). I need this to be dynamic. Below is my JavaS ...

How can I use str.match to strip out the "$" symbol and display only the numerical value?

Check out this code snippet: value = str.match(/$(\d+)/); Take for instance, Example 1: HK$999 Result to Display = 999 Consider Example 2: HK$1,999.20 Displayed result = 1 (not the desired outcome) How can I show Example 2 as 1999? Thank you every ...

Executing Python script via AJAX or jQuery

I need to execute Python scripts from JavaScript. The goal is to provide an input String to the Python script as an argument and then showcase the output on our webpage. Below is the Python code that runs smoothly on my Linux box: ./sample.py 12345 produc ...

Exploring the handling of the nth element within a jQuery each loop

In the process of looping through elements using an each loop, function test(){ $('#first li').each(function(n){$(this).//jQuery effects for nth li of first \\ need to process nth li of id="second" simultaneously }); Is there a wa ...

Accessing environmental variables from pug template

Currently, I am utilizing pug to generate static HTML for my own customized static site builder. In my package.json file, the only line of Node.js server code present is: "watch-pages": "pug -O options.json -w pages/ --out _static-website/" However, the ...

Tips on converting comma-separated values into HTML table rows using <tr> tags

JSON Data { "catalog_name": ["Sistem Autodownline ", "Karipap Pusing Ayu"], "price": ["100", "8"], "qty": "", "qty2": ["", ""], "total_qty": "", "total": "", "mem": "10", "email_2": "", "ic_add": "890527-08-6136", "c ...

Securely Saving JWT Tokens from Auth0 Login in Node.js Express

As a novice in the world of Auth0, I am currently working on integrating it into my regular express web application. My main goal is to secure and validate users before they are able to access certain endpoints. From what I have gathered, this can be achie ...

Initialize global variables for jQuery objects

Here is an example of some jQuery code that I have been working on. In this code, variables are declared at a global scope, but I have been wondering if it is possible to declare jQuery objects in a similar way to how classes are declared with the cn prefi ...

Is there a way to disable or deactivate all jQuery functions at once?

I have developed an application with push state functionality and it is running smoothly. However, I am facing an issue where my jQuery functions are being triggered multiple times in certain cases. This happens because every time I call push state, the sp ...

Unable to transform into a tangible entity

When I run the code below, I encountered an error stating: Uncaught exception: TypeError: Cannot convert 'validation.messages.field' to object $.fn.validate = function(validation) { $.each(validation.rules, function(field, fieldRules){ ...

I'm wondering, on a storybook, where is the best place to set my MUI X license key

Can you help with where to specify my license key in Storybook? I need guidance on where to set the license key in Storybook. According to MUI Docs, it should be done before React renders the first component and only once in the application. However, I ...

Updating the state on a click event triggered by a MenuItem in React using Material UI

I'm currently working on implementing state changes based on dropdown selections using Material UI. However, I've encountered an issue where the code snippet below (simplified) only returns the list item, and I'm unsure what steps to take n ...

Develop a scrambled PHP webpage for a CAPTCHA system

I've implemented the cool-captcha feature in my registration form. Here's the code snippet that generates the Captcha image: <img src="captcha.php" id="captcha" /> However, there is an issue where anyone can easily access the "captcha.ph ...

Is it possible to transform an array into a JSON file and securely store/upload it in an AWS S3 bucket?

Recently, I started exploring aws and its capabilities. Currently, my focus is on developing a web application that allows users to input text in two separate fields. Subsequently, this text will be converted into a Json file and stored in the S3 bucket. ...

Tips on customizing the appearance of two Material-UI Sliders across separate components

Looking to customize two sliders, each within their own react component. Slider in the first component const customizedThemeSlider1 = createTheme({ overrides:{ MuiSlider: { thumb:{ color: "#4442a9", marg ...

The CSRF token is mysteriously altering in places it should remain unchanged

Implementing the code below to prevent CSRF vulnerability if (!isset($_POST['_token'])) { $_SESSION['_token'] = bin2hex(random_bytes(20)); } I then use the token in hidden inputs named _token. In my main.js file, I include the foll ...

Encountering an issue while fetching data from the server - Unable to access properties of undefined (specifically 'toString')

I have encountered an issue where I am trying to set the default value of a select element to the data received from the server. Despite knowing that user.roleId is not undefined, I am getting an error specifically with the select element. Other input elem ...

The jquery selector fails to retrieve all elements

On the upcoming web page, I am attempting to use Jquery to select all <li> elements. Specifically, I want to target all the products contained within <ul class=search-result-gridview-items">. You can find the products here: I have made attempt ...

Struggling to create an accurate regular expression for validating URLs

I am currently working on a project where I need to create rules to avoid accepting incorrect URLs. I have decided to use regex for this purpose. My URL format is "http://some/resource/location". This URL should not contain any spaces at the beginning, m ...

"Enhance your website with the powerful autocompletion feature of

I am using Zend Framework to create a form element that utilizes Zend_Dojo_Form_Element_ComboBox. By setting dojox.data.QueryReadStore as the store type, I am able to generate a list of selectable values in my HTML input field. This allows me to either cho ...