Having difficulty uploading images onto a BufferGeometry surface in THREE.js

Struggling to create a cube in THREE.js using BufferGeometry, but encountering issues with the image not loading correctly. Despite trying various solutions, it seems that the uv coordinates are not functioning as expected.

script.js

//Load the canvas to draw on
var canvas = document.querySelector('#canvas')
// The three.js scene: the 3D world where you put objects
const scene = new THREE.Scene();


function degrees_to_radians(degrees) {
    let pi = Math.PI;
    return degrees * (pi / 180);
}


// The camera
const camera = new THREE.PerspectiveCamera(
    60,
    window.innerWidth / window.innerHeight,
    0.0001,
    10000
);

// The renderer: something that draws 3D objects onto the canvas
const renderer = new THREE.WebGLRenderer({ canvas: canvas });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x4a4a4a, 1);
document.body.appendChild(renderer.domElement);

const controls = new THREE.PointerLockControls(camera, document.body);

document.addEventListener('click', function () {
    controls.lock();
});

var key_map = {}; // You could also use an array
onkeydown = onkeyup = function (e) {
    e = e || event; // to deal with IE
    key_map[e.keyCode] = e.type == 'keydown';
}


const light = new THREE.PointLight( 0xffffff, 2, 0, 2 );
light.position.set( 10, 50, 10 );
scene.add( light );

camera.position.z = 4


const vertices = new Float32Array([
    -1.0, -1.0, 0.0,
    1.0, -1.0, 0.0,
    1.0, 1.0, 0.0,

    1.0, 1.0, 0.0,
    -1.0, 1.0, 0.0,
    -1.0, -1.0, 0.0
]);

const uvs = new Float32Array([
    0.0, 0.0,
    1.0, 0.0,
    1.0, 1.0,

    1.0, 1.0,
    0.0, 1.0,
    0.0, 0.0
]);

let textureLoader = new THREE.TextureLoader();
var texture = textureLoader.load('./images/grass.jpg');

const material = new THREE.MeshLambertMaterial({ map: texture });

const geometry = new THREE.BufferGeometry();
geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
geometry.addAttribute('uv', new THREE.BufferAttribute(uvs, 3));
geometry.computeVertexNormals();

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

scene.add(mesh);


const walk_speed = 0.05;
const sprint_speed = 0.15;
const fly_speed = 0.06;
var speed = 0;
var f_speed = 0;
var b_speed = 0;
var l_speed = 0;
var r_speed = 0;

function render() {
    //handle keypresses
    var cameraDirection = controls.getDirection(new THREE.Vector3()).clone();
    var angle = Math.atan2(cameraDirection.x, cameraDirection.z);

    if (key_map[87]) {
        //forwards
        if (key_map[17]) {
            f_speed = sprint_speed;
        } else {
            f_speed = walk_speed;
        }
        controls.getObject().position.z += (Math.cos(angle)) * f_speed;
        controls.getObject().position.x += (Math.sin(angle)) * f_speed;
    }
    if (key_map[83]) {
        //backwards
        if (key_map[17]) {
            speed = sprint_speed;
        } else {
            speed = walk_speed;
        }
        controls.getObject().position.z -= (Math.cos(angle)) * speed;
        controls.getObject().position.x -= (Math.sin(angle)) * speed;
    }
    if (key_map[65]) {
        //left
        if (key_map[17]) {
            speed = sprint_speed;
        } else {
            speed = walk_speed;
        }
        controls.getObject().position.z -= (Math.sin(angle)) * speed;
        controls.getObject().position.x += (Math.cos(angle)) * speed;
    }
    if (key_map[68]) {
        //right
        if (key_map[17]) {
            speed = sprint_speed;
        } else {
            speed = walk_speed;
        }
        controls.getObject().position.z += (Math.sin(angle)) * speed;
        controls.getObject().position.x -= (Math.cos(angle)) * speed;
    }

    if (key_map[16]) {
        //down
        camera.position.y -= fly_speed;
    }
    if (key_map[32]) {
        //up
        camera.position.y += fly_speed;
    }

    renderer.render(scene, camera);

    // Make it call the render() function about every 1/60 second
    requestAnimationFrame(render);
}


render();

Encountering an odd issue where the texture fails to load properly.

Picture

https://i.sstatic.net/b4AiI.png

Answer №1

It appears that you have not assigned any UV texture coordinates in your code. Without these, the renderer, shader, WebGL program (or wherever the magic happens) won't know how to properly apply the texture to the mesh.

const vertices = new Float32Array([
    -1.0, -1.0, 1.0,
    1.0, -1.0, 1.0,
    1.0, 1.0, 1.0,

    1.0, 1.0, 1.0,
    -1.0, 1.0, 1.0,
    -1.0, -1.0, 1.0
]);

const uvs = new Float32Array([
    0.0, 0.0,
    1.0, 0.0,
    1.0, 1.0,

    1.0, 1.0,
    0.0, 1.0,
    0.0, 0.0
]);

this.geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
this.geometry.addAttribute('uv', new THREE.BufferAttribute(uvs, 2));

If you want to create a cube with different textures on each side, consider using BoxGeometry. It already has different material indices for each side, so you just need to apply an array of 6 materials to the mesh.

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

Looking to make a custom loaded dice using 3D physics? Considering using the Cannon physics engine, but open to any other physics engine examples as well

I am exploring the idea of creating a dynamic dice throw animation that lands on a specific number, chosen randomly from random.org and then incorporated into the animation code. Initially, I considered generating multiple pre-made animations for each pos ...

WebRTC signalling has been successfully completed, however, the remote video functionality is still not functioning as expected

I attempted to set up webRTC and successfully negotiated the peerConnection. However, I am encountering an issue where remote videos are not playing. For more information, you can check the detailed console logs at this link - fb.privetbureau.com Here is ...

What is the process for integrating TypeScript compiling into a JavaScript application?

My project includes a build.js file that is responsible for building the project. It has two main objectives: Compile .ts files and store them in a new directory. Create an asar archive containing the compiled files. Since typescript (or tsc) is availabl ...

Tips for optimizing the sequencing of 3 ajax requests, with the output of one request serving as input for the subsequent two requests

I'm currently working on a solution for chaining 3 ajax calls where the result of one call feeds into the next two. Here's the scenario: // Invoke the ajax calls firstAjax('mypage.gng','john-doe').then(secondAjax, thirdAjax) ...

Guide on verifying the presence of an alert with nodejs webdriver (wd)

I am currently facing a challenge when writing a test where I need to verify the existence of an alert, check its text if it is present, and then accept it. Although I have researched on platforms like Stack Overflow for solutions such as checking for ale ...

Exploring the functionality of jQuery's html() method through multiple interactions

I am currently experimenting with this demo. I'm investigating why the HTML content disappears after using the second button. Everything works fine as long as you only click on btn #from-content-1 or only on #from-content-2. But if you click on #from ...

Tips for changing between two texts within a button when clicked

Seeking a solution for toggling between two different texts inside a button when making an ajax call, with only one text displayed at a time. I'm facing difficulty in targeting the spans within the button specifically. Using 'this' as conte ...

HtmlWebpackPlugin can cause issues with loading relative path files on websites that are not located in the root directory

I have set up webpack and the HtmlWebpackPlugin to automatically include bundled js and css files in an html template. new HtmlWebpackPlugin({ template: 'client/index.tpl.html', inject: 'body', filename: 'index.html' ...

Unable to modify the properties of a stateless child component

I'm completely new to React and I decided to create a basic comments application. My main objective was to let users change their display pictures by clicking the 'Change Avatar' button. https://i.sstatic.net/TqVe4.png However, I encountere ...

How to dynamically update the value of a TextBoxFor in asp.net MVC when a text box value changes

I need some assistance with a specific topic. In my scenario, I have two textboxes on my view. I want the value generated in my controller to be applied to textbox2 when there is a change in textbox1. For instance, if I enter a username in textbox1, textb ...

An error message indicating that the page is currently being unloaded has appeared

While working on a NodeJS-ReactJS Isomorphic App, I encountered an issue when clicking on a Link. An error message popped up saying: Uncaught (in promise) Error: Request has been terminated Possible causes: the network is offline, Origin is not allowed by ...

Skybox images failing to display

Learning THREE.js has been quite challenging for me, especially when trying to display a simple skybox. Despite attempting various strategies, I have not been successful due to insufficient documentation and multiple releases. This struggle has left me fee ...

Add a dynamic "printthis" button to a specific class on the webpage

As a novice in JavaScript, I am struggling with implementing the PrintThis.js JQuery plugin to create a print button for any div with the "printdiv" class. My approach involves using jQuery to handle the numbering of buttons and div classes, appending nece ...

Accept only numeric values that are either exactly 6 digits long or exactly 8 digits long with 2 decimal places

After developing a validator to ensure that a digit is a number and restricts it to having 2 digits after the decimal place, I realized that it does not account for two specific scenarios: a 6-digit number with no decimal places (e.g. 123456) or an 8-digit ...

Display a tooltip when the cursor hovers close to a line in D3 visualizations

Currently, I have a D3js line chart with SVG circles added to the points. When users hover over these circles, they can see a tooltip. https://i.sstatic.net/kYpeg.png https://jsfiddle.net/jhynag08/38/ However, I would like the tooltip to appear when user ...

Accessing the current playback time and setting a function to trigger upon reaching the end with THREE

I have successfully implemented a method in my Three.js app for loading, playing, and analyzing audio that is compatible with both desktop and mobile devices. I must use THREE.Audio instead of HTML5 Audio Analyser, as the latter does not work on mobile dev ...

How can I receive a callback for loop playing in Cordova media?

In my Angular JS service, I am utilizing the cordova media plugin to access media files. MediaSrv.loadMedia(filePath, mediaSuccess, null, status).then(function(media, status, test, status1){ media.play({ numberOfLoops: 999 }); ...

Is the value of the index in the input constantly fluctuating in Vue?

I have a method that generates an array of objects in the following way: onCalculate_a(code) { let data = this.forms.calculate_a.map((p,i) => { return { product_code: code, price: p } }); this.su ...

Unable to bind `this` using `call` method is not functioning as expected

Attempting to modify the Express app's .set function to be case-insensitive. For example, app.set('PORT',80); app.set('port'); // => undefined; aiming for it to return 80 Essentially, it's just a function that changes the ...

Using AngularJS ng-repeat with jQuery find yields a single element result

I'm in the process of developing my very first AngularJS application, and I've run into an issue with the jQuery find function. Essentially, what I'm attempting to do is utilize a custom HTML component that contains a list of buttons generat ...