The custom geometry in Three.js showcases a single color textured mesh

After adding texture to my triangle geometry, I noticed that it was all one plain color based on the lightest value. Upon further research, I discovered that assigning UVs might help. However, I encountered the same issue with the darkest color of my texture (refer to the picture).

Below is the code snippet:

var material = new THREE.MeshBasicMaterial( { map: new THREE.TextureLoader().load(texture), overdraw: true } );
var geometry = new THREE.Geometry();
// First step of 3 (30 degrees)
geometry.vertices.push(new THREE.Vector3(0.0, 0.0, 0.0));
geometry.vertices.push(new THREE.Vector3(totalLengthFactor, width, 0.0));
geometry.vertices.push(new THREE.Vector3(0.0, width, 0.0));
geometry.vertices.push(new THREE.Vector3(0.0, 0.0, -thickness));
geometry.vertices.push(new THREE.Vector3(totalLengthFactor, width, -thickness));
geometry.vertices.push(new THREE.Vector3(0.0, width, -thickness));
geometry.faces.push(new THREE.Face3(0, 1, 2)); // Top
geometry.faces.push(new THREE.Face3(5, 4, 3)); // Bottom
geometry.faces.push(new THREE.Face3(3, 1, 0)); // Long side
geometry.faces.push(new THREE.Face3(4, 1, 3)); // Long side
geometry.faces.push(new THREE.Face3(4, 2, 1)); // Short side
geometry.faces.push(new THREE.Face3(5, 2, 4)); // Short side
geometry.faces.push(new THREE.Face3(5, 0, 2)); // Medium side
geometry.faces.push(new THREE.Face3(3, 0, 5)); // Medium side

assignUVs(geometry);
... (snipped)...
function assignUVs(geometry) {
    geometry.faceVertexUvs[0] = [];
    geometry.faces.forEach(function(face) {
        var components = ['x', 'y', 'z'].sort(function(a, b) {
            return Math.abs(face.normal[a]) > Math.abs(face.normal[b]);
        });

        var v1 = geometry.vertices[face.a];
        var v2 = geometry.vertices[face.b];
        var v3 = geometry.vertices[face.c];

        geometry.faceVertexUvs[0].push([
            new THREE.Vector2(v1[components[0]], v1[components[1]]),
            new THREE.Vector2(v2[components[0]], v2[components[1]]),
            new THREE.Vector2(v3[components[0]], v3[components[1]])
        ]);
    });
    geometry.uvsNeedUpdate = true;
}

Here is the current outcome:

https://i.sstatic.net/6xRAq.png

Answer №1

It is not recommended to do it in this manner:

var material = new THREE.MeshBasicMaterial( { map: new THREE.TextureLoader().load(texture), overdraw: true } );

The process of loading a texture is asynchronous. The texture should be applied within the onLoad callback function. Please consult the documentation for THREE.TextureLoader here.

For your specific scenario:

var material = new THREE.MeshBasicMaterial( { overdraw: true } );
var url = //your texture path...
var onLoad = function(texture){
    material.map = texture;
    material.needsUpdate = true;
}
var loader = new THREE.TextureLoader();
loader.load(url, onLoad);

UPDATE

When calculating UVs, remember to incorporate offset and range adjustments. Take a look at the computeUVs function from this example fiddle; you may need to customize it for your stairs geometry...

function computeUVs(geometry) {

  geometry.computeBoundingBox();

  var max = geometry.boundingBox.max,
      min = geometry.boundingBox.min;
  var offset = new THREE.Vector2(0 - min.x, 0 - min.y);
  var range = new THREE.Vector2(max.x - min.x, max.y - min.y);
  var faces = geometry.faces;
  var vertices = geometry.vertices;

  geometry.faceVertexUvs[0] = [];

  for (var i = 0, il = faces.length; i < il; i++) {

    var v1 = vertices[faces[i].a],
        v2 = vertices[faces[i].b],
        v3 = vertices[faces[i].c];

    geometry.faceVertexUvs[0].push([
      new THREE.Vector2((v1.x + offset.x) / range.x, (v1.y + offset.y) / range.y),
      new THREE.Vector2((v2.x + offset.x) / range.x, (v2.y + offset.y) / range.y),
      new THREE.Vector2((v3.x + offset.x) / range.x, (v3.y + offset.y) / range.y)
    ]);
  }
  geometry.uvsNeedUpdate = true;
}

This implementation is inspired by this stackoverflow response.

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

Creating an HTML table to showcase array data stored in a session

After successfully storing data from an HTML table on page 1 in an array object (arrData) and saving it to session storage, the next challenge is how to display this data on a new HTML table on page 2. I am new to JavaScript, so any help would be appreciat ...

"The issue seems to stem from a snippet of compact JavaScript

I am facing an issue with a list item that contains both an image and text. The text is overlapping the image, but when I hover over the text, it disappears and only the picture is visible. Here is the HTML code snippet: <ul> <li><img ...

Angular 2 TypeScript: Accelerating the Increment Number Speed

I'm working with a function in Angular 4 that is triggered when the arrow down key is pressed. Each time the arrow down key is hit, the counter increments by 1. In this function, I need to run another function if the counter reaches a certain speed. ...

The functionality of socket.io is not functioning properly on the server, resulting in a 404

I encountered errors while working on a simple socket.io project on my server. The IP address I am using is . All files are stored in public_html and can be accessed through the URL: . Here are the code snippets: <!doctype html> <html> < ...

What is the best way to connect an event in Angular 2?

This is an input label. <input type="text" (blur) = "obj.action"/> The obj is an object from the corresponding component, obj.action = preCheck($event). A function in the same component, preCheck(input: any) { code ....}, is being used. Will it wor ...

The console displays "undefined" when formatting API data

I am attempting to format the data retrieved from an API since there is a lot of unnecessary information. However, when I try to display the formatted data in the console, it always shows as "undefined" or "null." I am importing and calling the fetch API ...

Is SWR failing to provide outdated data?

My understanding was that SWR should display the cached data upon page load before refreshing with new information from the API. However, in my Next.js app with a simple API timeout, the "loading" message appears every time due to the 5-second delay I adde ...

What is the reason behind being able to assign unidentified properties to a literal object in TypeScript?

type ExpectedType = Array<{ name: number, gender?: string }> function go1(p: ExpectedType) { } function f() { const a = [{name: 1, age: 2}] go1(a) // no error shown go1([{name: 1, age: 2}]) // error displayed ...

Interactive real-time search results with clickable option through AJAX technology

Currently, I have implemented a live search feature that displays results based on what the user types in real time using the keyup function. However, one issue I encountered is that the displayed results inside the <div> tag are not clickable. Is th ...

Error occurred in the middle of processing, preventing the headers from being set

I created a custom authentication middleware, but encountered an error. I'm puzzled about what's going wrong because I expected the next() function to resolve the issue? app.use(function(req, res, next){ if(req.user){ res.local ...

Utilizing ease-in effect on show more button clicks in CSS

When I click "show more," I want to have a smooth ease-in/out animation for 3 seconds. However, I am facing difficulties achieving this because I am using overflow: hidden and -webkit-line-clamp: 2; Are there any other methods to accomplish this? https: ...

Utilize Three.js to dynamically rotate objects within a moving Object3D element, ensuring they constantly face the camera

As someone who is relatively new to Threejs, I am curious about how to ensure that a moving mesh always faces the camera in a scene. Within a container Object3D, there are 100 meshes, and I am rotating this container on the x and y axis. Is there a method ...

Is it possible to incorporate two skeletons into a single mesh in Three.js?

Is it possible to have 2 skeletons in one mesh? I am unsure because I have not come across anything like that before. Here is the reference image From the image provided, you can see that there is already one skeleton on the right side of the plane mesh. ...

Bringing in a variable from a component that is dynamically imported

I have a dynamically imported (Map) component on my page. const Map = dynamic(() => import('../components/Mapcomp'), { ssr: false, }) In addition to the component, I also need to import a variable from it. const [taskImg, setTaskImg] = useS ...

Verify the presence of an email in the database utilizing a custom express-validator for node, express, and mysql

//Endpoint to update the user's email address. apiRouter.post('/update-email', [ check('newEmail') .isEmail().withMessage('Please enter a valid email address') .custom(newEmail=> { db.query(`SELECT user ...

Increasing an element in an array of objects using MongoDB and Mongoose

In my possession is a document structured as follows: { "id": "12345", "channels": [ { "id": "67890", "count": 1 } ] } My objective is to increase the count of a specific channel by one. When a user sends a message, I must locat ...

What is the best way to bind the value of total when working with forms and the bind method?

I am working on a form where I need to pass the value of total. Regarding the total: I have successfully passed the value of the cart, which is an array. const [total, setTotal] = useState<number | undefined>(undefined); const calculateTotal = () ...

Converting an array to PHP and fetching the values

Seeking assistance as I am struggling to find a solution. I have a JavaScript array that needs to be passed to a PHP script in order to store all the values (maximum of 3) on Session variables. The JavaScript array is generated from a string.split function ...

The Instant Search feature falls one keystroke short

I’ve implemented a unique "translation" feature on my website which includes an instant search functionality powered by a textarea element. <textarea name="text" onkeydown="searchq();"></textarea> This textarea triggers the execution of the ...

Guide on organizing users into groups and filtering them using Firestore's reference field type

I currently manage a small group of employees with plans to expand in the future. To streamline operations, I am looking to implement a grouping feature that allows users to sort employees based on their assigned groups. Although I thought about using the ...