Is it possible to combine Sprites as Geometries in Three.js?

My dilemma involves placing labels with the names of cities on a terrain. However, once the number of labels exceeds ten, the frames per second drastically decrease.

I've tried implementing the code provided at

My code looks something like this:

var canvas = document.createElement('canvas');
var canvasSize = 250;
canvas.width = canvasSize;
canvas.height = canvasSize;
var context = canvas.getContext('2d');
context.font = "Bold " + size + "px " + font;
context.textAlign = 'center';

context.fillStyle = "rgba(10, 10, 10, 1.0)";

context.fillText(text, canvasSize / 2, canvasSize / 2);

var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;

var labelMaterial = new THREE.SpriteMaterial(
        {map: texture, useScreenCoordinates: false});
var label = new THREE.Sprite(labelMaterial);

label.position.x = this._vector.x;
label.position.y = this._vector.y;
label.position.z = this._vector.z;

label.scale.set(10, 10, 1.0);

scene.add(label);

I believe the issue with the decreasing fps when merging sprites is due to each label having a different texture.

Thank you in advance!

Answer №1

In order to achieve maximum performance enhancement (requiring more effort than suggested by @raphaelRauwolf, we're talking about a significant amount of work here), one would need to utilize the ParticleSystem (rendered with GL_POINT) along with a dynamically allocated TextureAtlas that incorporates subimaging (https://github.com/mrdoob/three.js/pull/4661) based on the camera's nearest neighbors (). For the nameplates that are not within the camera's vicinity, a separate TextureAtlas with smaller preview nameplates can be used.

If you have roughly 1,000 nameplates, you can achieve similar results without using nearestneighbour and subimaging. Simply create a TextureAtlas containing all the nameplates and render them with the THREE.ParticleSystem :)

If you're interested in implementing either of these approaches, let me know, and I can provide further details.

Answer №2

Essentially, you can create a canvas object for each label to improve performance. By encoding the image in Base64 format from the canvas and passing it to the texture, you can write the next label onto the same canvas. Here's an example:

// initialize the canvas once
var canvas = document.createElement('canvas');

// set the canvas size
var sizeCanvas = 250;
canvas.width = sizeCanvas;
canvas.height = sizeCanvas;

// set the context and styles
var context = canvas.getContext('2d');
context.font = "Bold " + size + "px " + font;
context.textAlign = 'center';
context.fillStyle = "rgba(10, 10, 10, 1.0)";

// loop through the labels
for(var i = 0, j = myLabels.length; i < j; i++){
  contex.fillText(myLabels[i].text, sizeCanvas / 2, sizeCanvas / 2);

  // create the texture
  var texture = new THREE.Texture(canvas.toDataURL());
  texture.needsUpdate = true; // unsure if this is necessary

  // assign the texture to the material
  var labelMaterial = new THREE.SpriteMaterial({map: texture, useScreenCoordinates: false});

  var label = new THREE.Sprite(labelMaterial);

  // set the label position to the vector
  label.position = this._vector.clone();

  // add the label to the scene
  scene.add(label);

  // clear the canvas for the next text
  context.clearRect(0,0,sizeCanvas,sizeCanvas);
}

etiqueta.scale.set(10, 10, 1.0);

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

Using JavaScript to search JSON objects based on key value pairs

Consider a scenario where you have an array of objects in users.json: {"key":"userSubscriptions","value": [{"channel":"Netflix","user":"Bobby","region":"NA"}, [{" ...

Tips for attaching inline styles to the body element with a vuejs component

I am new to vue.js and have been learning for a couple of days now. There are still some concepts that I am struggling to understand. I am currently working on creating a dropdown menu that appears when the user clicks on three dots. However, I am facing a ...

Sliding in images with JQuery

I need help with animating the slide-in effect of 7 "card" images from the left to the center of the screen. I attempted to achieve this using the following code: function FetchCards() { $("#pack").css('margin-left', 0); $("#pack").css(& ...

Eliminating any spaces in the password prior to finalizing the form submission

After submitting the Form, I am trying to remove all spaces from the Password field. This is my current code: $(document).on("submit", "form#user-login", function(e){ e.preventDefault(); var emailAdd = $("#edit-pass").val().replace(/ / ...

Tips for minimizing the transfer time of large arrays using ajax

https://i.stack.imgur.com/IP0oe.pngDescription I am currently working on transferring a JSON object from the server to the client using PHP and JavaScript via AJAX. The JSON object contains a large array (200x200) of integers. The server is running on lo ...

Tips for removing unnecessary debugging code from JavaScript when compiling or minifying your code

Back in the day, I would always include tons of debug code in my JavaScript app. However, I'm now searching for a method that will eliminate debug code during the compilation/minification phase. Does the world of JavaScript have something similar to ...

Building New Web Pages with Express in Node.JS

I want to dynamically generate a new page on Node.JS with Express upon user form submission. Here is my initial approach, but it's not working as expected: var app = require('express')(); var server= require('http').createServer(a ...

Analyzing an Object through Functions

var Car = function(name, year) { this.name = name; this.year = year; this.print = function() { console.log(name+" "+year); } } var tesla = new Car("tesla", 2018); tesla.print(); tesla = JSON.parse(JSON.stringify(tesla)); console.l ...

Having trouble getting the Pokemon modal to show both the type and image?

HTML: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>My First JS App</title> <lin ...

What is the best method to securely install a private Git repository using Yarn, utilizing access tokens without the need to hardcode them

My initial thought was to utilize .npmrc for v1 or .yarnrc.yml for v2/3/4, but in all scenarios, Yarn does not even attempt to authenticate with Github. nodeLinker: node-modules npmScopes: packagescope: npmAlwaysAuth: true npmAuthToken: my_perso ...

JavaScript - Functions in objects losing reference to previously created object properties

Having trouble with my Candy function. When I create an object of the Candy function, all attributes are created correctly. However, when I try to run the draw function, it always uses the properties of the second object created instead of the one I want. ...

Design a clear button for MUI autocomplete feature

I'm currently working on a project where I need to implement a button that clears the MUI autocomplete value and removes the data from the UI. Although I've managed to delete the data from the UI with the code provided, the onChange value remain ...

Removing Multiple Object Properties in React: A Step-by-Step Guide

Is there a way in React to remove multiple object properties with just one line of code? I am familiar with the delete command: delete obj.property, but I have multiple object properties that need to be deleted and it would be more convenient to do this i ...

Check out the latest enhancements to React and Flask Fullstack right from your web browser

Recently, I ventured into the world of React and Flask development by following a tutorial found at this link. After completing the example fullstack website project, I realized that my code mirrored exactly what was provided by the author on their Github ...

Format a JSON file using clang-format

I'm facing an issue with my json file formatting. When I run clang-format on it, the output is ugly as it treats it like code. { "name" : "My great app", "description" : "It's really cool.", "version" : "0 ...

Just easy highlighting using tags in Javascript

I have come across a code snippet that seems to be functioning well: <html> <head> <title>Testing JS Highlighting</title> <script type="text/javascript"> function highlight() { var t = ...

Leveraging AngularJS $filter in conjunction with ng-disabled

I have a variable in my $scope that contains information about an election, including a list of voters with unique IDs: $scope.election = { voters: [ { _id: '123' }, { _id: '456' }, { _id: '789' } ] } Additio ...

The compatibility between Polymer JS and Rails Turbolinks is problematic

Currently, I am facing a challenge in integrating PolymerJs with a Ruby on Rails project that has Turbolinks enabled. The issue arises when I click on a link - the new page loads correctly but my Polymer components do not reinitialize. They appear as if no ...

What steps do I need to take to adjust this function based on the timezone?

Is there a way to retrieve the current time based on a specific timezone of my choice? let getCurrentTime = () => { var today = new Date(); var hh = String(today.getHours()) var mm = String(today.getMinutes()) //January is 0! var ss = ...

The <script> element failed to close correctly

Within my default.jspx file, which serves as the foundational layout for the page, I am attempting to import several jQuery libraries. The code snippet looks like this: <head> ... <spring:url value="/resources/js/lib/jquery-1.9.1.min.js" ...