Can a THREE.Texture be created using a byte array instead of a file path?

In my server client system, the server parses a model file and sends vertex data to the client using a socket. I run into trouble when the model contains textures. I am able to read the texture (PNG file) into a byte array and send it to the client via socket. However, I am unsure how to create a THREE.Texture from the byte array.

My question is: Is it feasible to build a THREE.Texture from the byte array? If so, how can I accomplish this?

Additionally, feel free to propose alternative methods for transferring textures from server to client.

Thank you.

Answer №1

If you happen to already possess a byte-array from the WebSocket, there is a more refined solution available using Blobs:

// assuming `byteArray` was received from the websocket
var texture = new THREE.Texture();
var imageBlob = new Blob([byteArray.buffer], {type: "image/png"});
var url = URL.createObjectURL(imageBlob);

var image = new Image();
image.src = url;
image.onload = function() { 
    texture.image = image; 
    texture.needsUpdate = true; 
};

Now, you will have a valid URL (similar to blob:http://example.com/$uuid) that can be utilized anywhere you need it. The major advantage of this approach is that it eliminates the time required for converting data to base64 and prevents crashing devtools when attempting to display lengthy base64-url strings.

Additionally, there is another option available (although not widely supported yet): createImageBitmap(). If used, it simplifies the process even further:

var texture = new THREE.Texture();
var imageBlob = new Blob([byteArray.buffer], {type: "image/png"});

createImageBitmap(imageBlob).then(function(imageBitmap) {
    texture.image = imageBitmap;
    texture.needsUpdate = true;
});

Answer №2

After researching different methods online, I finally discovered a solution to the problem at hand. The key is to convert the byte array into a data URI and then pass it to the THREE.TextureLoader. Below is the code snippet that achieves this:

        let data_uri = "data:image/png;base64," + convert_to_base64_string(my_byte_array);

        // create a loader instance
        let loader_t = new THREE.TextureLoader();
        loader_t.load(
            // specify the resource URL
            data_uri,
            // Callback function upon successful resource loading
            function ( texture ) {


                let plane = scene.getObjectByName("test-texture");
                plane.material.map = texture;

                plane.material.needsUpdate = true;
            },
            // Callback function for download progress
            function ( xhr ) {
                console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
            },
            // Callback function for download errors
            function ( xhr ) {
                console.log( 'An error occurred' );
            }
        );

Answer №3

Here are the necessary steps to achieve your goal:

To start, you need to convert bytes into base64 format. You can easily accomplish this by utilizing a library such as https://github.com/beatgammit/base64-js.

Next, create an image using the base64 data:

var image = new Image();
image.src =  "data:image/png;base64," + myBase64Data;

Then, generate a texture from the created image:

var texture = new THREE.Texture();
texture.image = image;
image.onload = function() {
    texture.needsUpdate = true;
};

If you encounter any difficulties during this process, you can verify the conversion of bytearray to base64 using an online base64 viewer like the one available at:

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 are some strategies for minimizing code repetition when implementing login functionality across various OAuth2 providers?

Currently, I am utilizing various node modules such as Node.js, Express, Passport, and Mongoose. When a user clicks on "sign in with provider", there are two scenarios to consider. Let's take an example of using GitHub Strategy: 1. If the user is al ...

Animations are failing to run within a Bootstrap card when using Vue rendering

I have utilized Bootstrap cards to display pricing information in my project. I implemented a collapse feature for half of the card when the screen size is equal to mobile width. While using vanilla Bootstrap, the animation worked seamlessly with the col ...

Is there a way to retrieve and gather all data from various scopes and then access them collectively?

I attempted to scrape information from a website using Node.JS + Cheerio + Axios. I was able to retrieve all the necessary data, but encountered an issue with returning the data from different scopes in order to receive it. Currently, I can only obtain the ...

"Discovering issues with the functionality of Antd Table's search and reset capabilities

I'm currently working on integrating search and reset functions in an Antd table. However, I am encountering an issue with the reset (clearAll) function as it does not revert the table back to its initial state when activated. The search functionality ...

Why is it that I cannot use the .get method on JSON data? And what is the best way to convert JSON into a map?

I'm currently in the process of creating a test for a function that accepts a map as an argument, Under normal circumstances when the code is executed outside of a test, the parameter would appear like this (when calling toString): Map { "id": "jobs ...

retrieve the chosen option from the dropdown menu

Whenever I try to display the input type based on the selection from a select element, I encounter an issue Here is the select element within my view: <select id="type" name="type_id" class="form-control" required> @foreach($type as $row) & ...

Gulp encountered an issue - Module 'sigmund' not found

After installing browser-sync, my previously working Gulp encountered an error: Error: Cannot find module 'lru-cache' To resolve this issue, I utilized the following solution: npm link lru-cache as suggested in this thread However, upon atte ...

Maximizing the potential of a single .js file for multiple .html pages with AngularJS

I have a JavaScript file containing a function that I want to be accessible by multiple HTML pages without duplicating it in another file. Currently, the JS file starts with the following code snippet: (function(){ var app = angular.module('Proj ...

Technique for identifying a sequence within a longer numerical series

As I ponder this puzzle for what seems like an eternity, I humbly turn to you for a possible solution. A lengthy number resembling this one: 122111312121142113121 It is crucial to note that no numbers exceed four or fall below one. Now my quest is to une ...

Navigating through Objects in Angular 9

I am facing a challenge in Angular 9/Typescript while trying to iterate through the object response from my JSON data. Despite searching for solutions, I haven't found any that work for me. In my JSON, there is a section called "details" which contain ...

Value as a String inside an Object

I am encountering an issue with using the obj to store string values in my project. The strings contain commas, and for some reason, it is not working as expected. const resizedUrl ={ 'mobile': "'images','400x/images' ...

Updating the parent's data by modifying data in the child component in VueJS

When I use multiple components together for reusability, the main component performs an AJAX call to retrieve data. This data is then passed down through different components in a chain of events. <input-clone endpoint="/api/website/{{ $website->id ...

Guide on building a "like" button using a Node.js Express application

I am in the process of developing a website using node, express, and mongodb. I am facing an issue with passing a variable value from my ejs file to the server side. Can someone help me solve this problem? Here is what I have attempted so far: Example Ht ...

The download attribute does not seem to function properly when used within the <a></a> tag in ReactJS

I've been attempting to download a PDF using the "download" attribute within an <a> tag: <a className="dl_link" href={'./myfiles/abc.pdf'} target="_blank" download/> However, instead of downloading, it only opens in the next ...

Unlock the power of React Testing Library with the elusive waitFor function

I came across an interesting tutorial about testing React applications. The tutorial showcases a simple component designed to demonstrate testing asynchronous actions: import React from 'react' const TestAsync = () => { const [counter, setC ...

Getting the total number of child elements in a web page using Selenium web-driver with Node.js

I've been looking everywhere, but I can't seem to find the answer Here's my HTML code: <form id="search_form_homepage" > ... <div class="search__autocomplete" style="display: block;"> &l ...

The initial row's Id will be used as the Id for all subsequent rows within a JSON object

After dragging a tr in a table and confirming by clicking a button, I need the order list to be updated in the database. To achieve this, I created a JSON object where I intend to save the ids and their corresponding new orders. The issue I am facing is t ...

The v-select menu in Vuetify conceals the text-field input

How can I prevent the menu from covering the input box in Vuetify version 2.3.18? I came across a potential solution here, but it didn't work for me: https://codepen.io/jrast/pen/NwMaZE?editors=1010 I also found an issue on the Vuetify github page t ...

Issue with Dijit form fields failing to render correctly following dojo.destroy and dojo.place operations

Within my form, there is a table labeled as table0 which contains various dijit form controls. Additionally, there are buttons for adding and removing tables where each new table is assigned an ID incremented by 1. For instance, the first click on the add ...

Bootstrap tab requires double taps to switch on iPhone when using meteor platform

One recurring issue I have encountered with my current website involves iPhone users and their difficulty in switching between two weeks on my site. <ul class="nav nav-tabs justify-content-center" id="myTab" role="tablist"> <li class="nav-item" ...