Issue with texture in three.js causing it to appear completely white

UPDATE: After taking advice from gaitat, I encountered a new issue: now the box is not visible at all. To illustrate this problem, I have created another question.

I have a basic box geometry that I am attempting to apply a texture to. However, all I am getting is a completely white box. To showcase this problem, I have set up a simple test page. Below is the content of that page:

"use strict";

// create DOM elements:
var container = document.createElement('div');
document.body.appendChild(container);
var info = document.createElement('div');
container.appendChild(info);

// define a 'Box2' geometry instance: (see implementation below)
var myBox2geom = new THREE.BoxGeometry(100, 100, 100, 10, 10, 10); // parameters: x,y,z dimensions and segment widths

// create a 'Box2' mesh with texture:
var texture = new THREE.TextureLoader().load("crate.gif");
console.log("texture: ", texture);
var material = new THREE.MeshLambertMaterial({ map: texture, side: THREE.DoubleSide, emissive: 0xffffff });
texture.minFilter = THREE.NearestFilter;
var myBox2mesh = new THREE.Mesh(myBox2geom, material);

// add mesh to scene:
var scene = new THREE.Scene();
scene.add(myBox2mesh);

// add light source:
var light = new THREE.PointLight(0xffffff);
light.position.set(100, 200, 300);
light.lookAt(new THREE.Vector3(0, 0, 0));
scene.add(light);

// set up camera:
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.x = 100;
camera.position.y = 200;
camera.position.z = 300;
camera.lookAt(new THREE.Vector3(0, 0, 0));
scene.add(camera);

// create renderer:
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);

// render the scene!
renderer.render(scene, camera);

THREE.Box2Geometry = function(width, height, depth, widthSegments, heightSegments, depthSegments) {
    ...geometry implementation...
};

THREE.Box2Geometry.prototype = Object.create(THREE.Geometry.prototype);
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
  </head>
  <body>
    <script src="https://raw.githubusercontent.com/mrdoob/three.js/master/build/three.js"></script>
    <script src="main.js"></script>
  </body>
</html>

Answer №1

After some investigation, it was discovered that the code contained three mistakes, as pointed out by individuals like Falk Thiele and 2pha/gaitat in a subsequent question I posed: the follow-up question.

  1. An issue with Cross-origin resource sharing (CORS) caused an error in Firebug:

    SecurityError: The operation is insecure.
    gl.texImage2D.apply( gl, arguments );
    

    To resolve this error, Falk Thiele recommended setting the CrossOrigin attribute to empty:

    var loader = new THREE.TextureLoader();
    loader.crossOrigin = "";
    loader.load(
        "http://mrdoob.github.io/three.js/examples/textures/crate.gif",
        function( texture ) {
            //...
        },
        function () {},  
        function ( error ) { console.log( error ) } 
    );
    

    Interestingly, even loading the texture locally could result in a CORS error in Chrome if the loader.crossOrigin = ""; line was included. This indicates that this line should only be used when the origin is indeed cross-site.

  2. The scene was being rendered only once before the texture was loaded due to the asynchronous nature of the TextureLoader.load() call. This led to the line

    renderer.render( scene, camera );
    executing before the loading process completed.

  3. In Chrome, the script failed for two reasons: the aforementioned CORS issue and the failure to load the THREE library (

    Uncaught ReferenceError: THREE is not defined
    ). It's unclear why THREE failed to load in Chrome, but in the corrected code snippet provided below (also available here), the error no longer occurs.

A demo showcasing the updated code can be found onJS fiddle.

Below is the corrected code snippet without errors 1, 2, and 3:

"use strict";

// create DOM elements:
var container = document.createElement('div');
document.body.appendChild(container);
var info = document.createElement('div');
container.appendChild(info);

// instantiate a 'Box2' geometry:
var myBox2geom = new THREE.BoxGeometry(100, 100, 100, 10, 10, 10);  

// create a scene:
var scene = new THREE.Scene();

// generate a corresponding 'Box2' mesh:
var loader = new THREE.TextureLoader();
loader.crossOrigin = "";
loader.load("http://mrdoob.github.io/three.js/examples/textures/crate.gif",
function(textur   e) {
texture.minFilter = THREE.NearestFilter;
var material = new THREE.MeshLambertMaterial({ map: texture, side: THREE.DoubleSide });
var myBox2mesh = new THREE.Mesh(myBox2geom, material);
scene.add(myBox2mesh);
},
function() {},  
function(error) { console.log(error) }
);

// add lighting:
var light = new THREE.PointLight(0xffffff);
light.position.set(100, 200, 300);
light.lookAt(new THREE.Vector3(0, 0, 0));
scene.add(light);

// setup camera:
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.x = 100;
camera.position.y = 200;
camera.position.z = 300;
camera.lookAt(new THREE.Vector3(0, 0, 0));
scene.add(camera);

// initialize renderer:
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);

// render loop:
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();


THREE.Box2Geometry = function(width, height, depth, widthSegments, heightSegments, depthSegments) {...}
THREE.Box2Geometry.prototype = Object.create(THREE.Geometry.prototype);
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
  </head>
  <body>
    <script src="https://raw.githubusercontent.com/mrdoob/three.js/master/build/three.js"></script>
    <script src="main3.js"></script>
  </body>
</html>

Additional Errors:
4. A texture may appear white or black if there are no lights, lights not added to the scene, misaligned light directions, or lights too distant from the mesh.
5. Face normals pointing incorrectly from the geometry might also cause texturing issues. More details can be found in this related question.

Answer №2

To ensure that your texture is properly loaded, you must utilize the THREE.Textureloader() .onLoad() method.

Below is an example demonstrating how this would be implemented:

// create DOM elements:
var container = document.createElement('div');
document.body.appendChild(container);

var scene = new THREE.Scene();

// define a 'Box2' geometry instance: (see implementation of geometry below)
var myBox2geom = new THREE.BoxGeometry(100, 100, 100, 10, 10, 10); // arguments: x, y, z-dimensions and segment widths

// instantiate a loader
var loader = new THREE.TextureLoader();

// load a resource
loader.load(
    'crate.png', // resource URL

    function(texture) {
        texture.minFilter = THREE.NearestFilter;

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

        var myBox2mesh = new THREE.Mesh(myBox2geom, material);

        // add mesh to the scene:
        scene.add(myBox2mesh);
    },
);

// create light:
var light = new THREE.PointLight(0xffffff);
light.position.set(100, 200, 300);
light.lookAt(new THREE.Vector3(0, 0, 0));
scene.add(light);

// set up camera:
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(100, 200, 300);
camera.lookAt(new THREE.Vector3(0, 0, 0));

// initialize renderer:
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);

animate();

function animate() {

    requestAnimationFrame(animate);
    renderer.render(scene, camera);

}

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 is the process for converting an array of integers into a byte stream and sending it to the client using Node.js?

How can I convert an array of integers into a bytestream and send it to the client using Nodejs? Let's say I have the array [17, 256, 82]. I am setting the content-type as application/octet-stream. My goal is to send a response with the binary stre ...

Why does my JSON variable contain "type" and "data" values instead of something else?

After using JSON.stringify() on my object to save it to a file, I noticed that one of the parameters does not have the expected string value assigned. Instead, it has a "type" and "data". Code: fs.writeFileSync('myjson.json', JSON.stringify(myjs ...

How can I utilize columns from a junction table in the "where" clause in sequelize?

Looking to execute a Sequelize query on multiple related models: SELECT Cou.country_id, cou.country_name, Sta.state_id, Sta.state_name, Dis.district_id, Dis.district_name, Cit.city_id, Cit.city_name, Loc.location_id, Loc.location_name, Sub_Loc.sub_locatio ...

What causes an ajax request to submit "none" as the value of a dom element?

Seeking assistance! I've encountered a frustrating issue with my simple input box in a form. I am attempting to send the value from this input box to Django using Ajax post, but keep encountering a 500 error that reads ValueError at /rest/ Cannot use ...

Display a button only when hovering over it

Seeking assistance for a simple task that is eluding me at the moment. I am currently using scss and trying to make a button only appear when hovered over. The button is hidden in the code snippet below, nested within a block alongside some svgs. Any hel ...

What is the proper way to arrange this particular array?

I'm having trouble with sorting this array. The array contains objects with SortTime and Operation values like this: array = [ {SortTime : 123456, Operation : Assigning}, {SortTime : 4567 , Operation: Assigning}, {SortTime : 123456 , Operation: Assi ...

Populate the dropdown menu with data from a JSON file

Recently, I created a custom JSON file and wanted to populate a select>option using this data. However, I encountered an error message saying: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at file:///C:/.../p ...

Having trouble getting my Node.js application to deploy properly on Heroku

Check out my repository here: https://github.com/jacklemasters/tech-blog Although the app runs smoothly on my local machine, I can't figure out why it's not working on Heroku. I've tried moving the code completely and creating a new reposit ...

Animating content with Jquery Waypoints for a seamless and elegant user experience

Currently tackling a project that requires some jQuery functions beyond my current skill set. Hoping to find some solutions here! The project in question is a one page scroll site, with existing jquery and waypoints functions implemented. Check out the c ...

After removing an item from the array, React fails to display the updated render

As a newcomer, I am struggling with a particular issue. I have implemented a delete button for each item in a list. When the button is clicked, the object in the firstItems array is successfully deleted (as confirmed by logging the array to the console), b ...

JavaScript form validation issue unresolved

When I attempt to validate form fields using Javascript functions, they seem to not load or check the field upon clicking the submit button. <html> <body> <?php require_once('logic.php'); ?> <h1>New Region/Entit ...

Is there a way to update the href attribute within the script section in vue.js?

I need to dynamically set the href attribute of a link based on data retrieved from a database and rendered in the methods section. <template v-if="header.value == 'ApplicationName'"> <a id="url" href="#" target="_blan ...

What is the best way to structure a JSON object with keys that can change dynamically?

var data= [{_id: "5a93cbd49ae761a4015f6346", nombre: "Chicago - Missouri", longitud: "-94.6807924", latitud: "38.287606"}, { _id: "5a93ca539ae761a4015f6344", nombre: "Boston - Central Falss", longitud: "-71.4111895", latitud: "41.8902971"}, { _id: "5a93cc ...

Tips for displaying dynamic data using innerHTML

Recently, I set out to implement an infinite scroll feature in Angular 2 using JavaScript code (even though it may seem a bit unusual to use JavaScript for this purpose, it's actually working perfectly). Initially, I was able to create an infinitely s ...

Is there a plethora of new content waiting to be discovered as you scroll through the old using Vue and

I have been working on a code that looks like this: <template> <div class='sights-list'> <div v-for='(sight, index) in sights'> <p>{{ sight.name }}</p> </div> < ...

When you click on a single checkbox, it automatically selects all of them

Struggling with a form that uses HTML PDO and AngularJS for validation. When clicking one checkbox, all other checkboxes get checked as well. Here is my form: <input type="checkbox" name="declaration" id="declaration" ng-m ...

GraphQL query excluding empty fields for various types of objects

Utilizing Apollo Graphql, I attempted to employ inheritance for retrieving various types of models without success. My goal is to extract specific fields from the objects while omitting those that are unnecessary. To address the issue of incomplete object ...

Receiving alerts as soon as the page DOM is fully loaded, prior to the window.onload event

Is there a consistent way to get notified when the page body has loaded across all browsers, regardless of differences in implementation? Here are some methods I'm aware of: DOMContentLoaded: Supported in Mozilla, Opera 9, and newer WebKits. This i ...

Can you explain the purpose of the window.constructor and global.constructor functions in JavaScript?

Can someone explain the purpose of this function? I've been searching for information but can't find anything. I tested it in Firefox: window.constructor() // TypeError: Illegal constructor new window.constructor() // TypeError: Illegal constru ...

Simple steps to change JSON Object to JavaScript array

Referring to this question and this other one, I am seeking advice on how to handle a JSON object structure different from the examples provided: This is my JSON Object: var myData = { "04c85ccab52880": { "name": "name1", "firstname": ...