How to Efficiently Load Large Amounts of Texture Data in Three.js and WebGL

During a recent project, I found myself creating numerous large textures using canvas and then uploading them to the GPU. However, I encountered issues with memory depletion (resulting in Chrome crashing) and performance slowdowns when all the textures were sent through the GPU bus at once upon page load.

To address this problem, I opted to stagger the texture.needsUpdate = true; calls to distribute the texture uploads across multiple render updates rather than overwhelming the GPU in one go.

While this solution proved effective, I'm interested in exploring other potential approaches...

I decided to share my experience here as it may benefit others facing similar challenges of loading all textures at the launch of their projects.

Answer №1

Reducing textures to minimize excessive load is a key strategy. Starting with smaller textures at the source can greatly enhance performance downstream.

Even though this post is dated, it still appears as a top search result on Google. Here are some valuable tips for beginner 3D game/web developers.

Textures are processed in fixed bit chunks, so fewer chunks mean better efficiency. Creating textures with resolutions that are powers of two helps avoid loading incomplete chunks and wasting resources. Following this pattern prevents data loss.

Consider the actual size of your texture on the screen. If your original image is 1024x1024 but only occupies a small portion of the screen or output canvas, all the extra detail is unnecessary. Scale down your textures to match their on-screen appearance.

If certain colors in your textures are not being utilized, consider using vertex coloring or lighting effects instead. For such cases, save your texture as grayscale or limit the color palette by indexing them.

.gif format works well for smaller textures, while JPEG is more effective for compressing larger ones. With .gif files, you can also conserve space by combining multiple textures into one image and matching them with a shared palette. Keep in mind that classics like Zelda LTTP operated using just 256 colors. Utilizing an RGB index array and storing images as raw numbers can be efficient.

When importing/exporting images from JSON, remember that images default to raw 32-bit PNG files. These large files become even bigger when embedded as raw data in a JSON object. Consider exporting only mesh data and reapplying the texture via JavaScript in your source code to optimize various formats and textures.

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

Tips for capturing everything in NextJs with getStaticPaths

My current challenge involves utilizing getStaticProps and getStaticPaths to dynamically generate pages at build time. This is my first experience working with CatchAll routes, so I embarked on a search for solutions. Unfortunately, none of the results al ...

What is causing the click function to malfunction after selecting a second item?

I'm struggling to understand why my click function isn't functioning properly. You can view the JSFiddle here: http://jsfiddle.net/adbakke/ve9oewvh/ This is a condensed version of my HTML structure: <div class="projectDisplay"></div&g ...

What is the best way to transform an array of objects into MenuItems for a Material-UI Select component?

I am facing an issue with mapping the values of field choices to create options for an MUI Select field from an array called fieldChoices. Here is how I populate the fieldChoices array: fieldChoices = { choices: filtered_status.map(function (item) { ...

Executing a python script from an html page by providing it with a string input

I've been searching everywhere for a solution to this problem, but I've only been able to find information on either the python side or the javascript side, and I really need both. Currently, I have a python script that I execute in the command ...

What is the best way to link a newly created contact to the current user in Mongoose?

I'm faced with the challenge of creating a contact that is specifically added to the current user's contact array. Currently, my controller only creates a generic contact and doesn't cater to the individual user. Controller: function cont ...

Use Angular.js to perform navigation after clicking the "Ok" button on a confirmation box

I encountered a problem with my requirement. I need a confirm box to appear when the user attempts to navigate to the next state/page. Only if the user clicks on the "Ok" button should it proceed to the next state; otherwise, it should stay as it is. Below ...

In JavaScript, a "switch statement" retrieves a test value from a "input type text" by accessing the value using getElementByName.value

Attempting to test 7 possible values for the variable 'a' by passing it to a function from user input in seven 'input type text' boxes, then checking each value individually with clicks on 7 'input type image' elements. Howeve ...

Using Jquery to drag and drop items into a specific target zone

Check out my Jquery code: $(".list").draggable({helper: 'clone', cursor: 'hand'}); $(".drop1").droppable({ accept: '.list', hoverClass: 'dropareahover', drop: function(ev, ui){ var targetId = $(this) ...

Integrating AJAX feedback messages into Formcarry

I'm currently diving into the world of React as I work on my inaugural website using this framework. My main hurdle right now is creating a contact form. To simplify the process, I opted to use Formcarry and integrate it with my React App. However, I ...

A pop-up modal that remains closed thanks to sessionStorage

I've been working on creating a modal that pops up after a short delay, but once closed, it shouldn't appear again unless the user closes the website and starts a new session. While I have successfully designed the modal, integrating sessionStora ...

Type of result from a function that returns a linked promise

In my class, I have a method that returns a chained promise. The first promise's type is angular.IPromise<Foo>, and the second promise resolves with type angular.IPromise<Bar>. I am perplexed as to why the return type of doSomething is an ...

Dynamic Column Placement in Tabulator with AutoColumns and AJAX Integration

Hey there, I'm currently working on incorporating the autoColumns feature in Tabulator using data retrieved via AJAX. My aim is to dynamically add column definition information based on each column's requirements, like filters, sorting, etc. Desp ...

Using Vue to dynamically bind the source of an HTML audio element and disable it

For a school project, I am creating a small website that sells hip hop beats using Vue.js. One of the pages I'm working on allows users to preview a beat and make a purchase. To enable beat previews, I have included an HTML audio tag. The data for eac ...

AngularJS is experiencing issues with data visibility when generating rows automatically

Having trouble displaying my data in HTML using ng-repeat. I am attempting to dynamically create rows, but the list is not showing up. This is how my controller looks like: app.controller('SearchBusController',['$scope','$session ...

Send a response from socket.io to the client's browser

I am working on a project where I need to retrieve the ID of the current drawer from the server and pass it to the client. Here is the code I have so far: Client Side: socket.emit('returnDrawer'); socket.on('returnDrawer', fu ...

jQuery - harnessing the power of JavaScript events such as "dragover"

I have a JavaScript function that includes an event listener for 'dragover'. Here is the code snippet: document.getElementById("someID").addEventListener("dragover", function(){ //Add your logic here }, fa ...

Maintaining an object's position steady in relation to the camera in Three.js

I am trying to figure out how to maintain an object's position relative to the camera. Specifically, I want one object to be viewable from all angles using a trackball camera, while another object should always stay in the same position relative to th ...

Generate a new perspective by incorporating two distinct arrays

I have two arrays containing class information. The first array includes classId and className: classes = [ {classid : 1 , classname:"class1"},{classid : 2 , classname:"class2"},{classid : 3 , classname:"class3"}] The secon ...

Trying to toggle between two Angular components within the app component using a pair of buttons

Currently, I am developing an application that requires two buttons to display different nested apps. Unfortunately, I am unable to use angular routing for this particular design. These two buttons will be placed within the app.component. When Button A i ...

How to grab JSON data within a CakePHP 2.2 controller

Trying to transmit JSON data from a web page using JQuery, as shown below: $.ajax({ type: "post", url: "http://localhost/ajax/login", data: '{username: "wiiNinja", password: "isAnub"}', dataType: "json", contentType: "applica ...