Issue with Three.js failing to display textures

I'm a beginner with three.js and I'm struggling to get my texture to render properly in my scene. Despite following the documentation closely, all I see is a blank canvas with no errors in the console. Can anyone offer any guidance on why my code isn't rendering the texture as expected? Any help would be greatly appreciated. Here is the JavaScript code I'm using:

`var camera, scene, renderer, texture, fog; var mesh, geometry, material, buffer;

        var start_time = Date.now();

        init();
        animate();

        function init() {

            var container = $('#clouds');

            // Background gradient

            var canvas = document.createElement('canvas');
            canvas.width = 32;
            canvas.height = window.innerHeight;

            var context = canvas.getContext('2d');

            var gradient = context.createLinearGradient(0, 0, 0, canvas.height);
            gradient.addColorStop(0, "#1e4877");
            gradient.addColorStop(0.5, "#4584b4");

            context.fillStyle = gradient;
            context.fillRect(0, 0, canvas.width, canvas.height);

            container.css('background', 'url(' + canvas.toDataURL('image/png') + ')');
            container.css('background-size', '32px 100%');

            //

            camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 3000);
            camera.position.z = 6000;

            scene = new THREE.Scene();

            geometry = new THREE.Geometry();

            var texture = new THREE.TextureLoader().load('/media/cloud-element.png', animate);
            THREE.LinearMipMapNearestFilter;
            THREE.LinearMipMapLinearFilter;

            var fog = new THREE.Fog(0x4584b4, -100, 3000);

            material = new THREE.ShaderMaterial({

                uniforms: {

                    "map": { type: "t", value: texture },
                    "fogColor": { type: "c", value: fog.color },
                    "fogNear": { type: "f", value: fog.near },
                    "fogFar": { type: "f", value: fog.far },

                },
                depthWrite: false,
                depthTest: false,
                transparent: true,
                color: 0xf2f2f2

            });

            var plane = new THREE.Mesh(new THREE.PlaneGeometry(64, 64));

            for (var i = 0; i < 8000; i++) {

                plane.position.x = Math.random() * 1000 - 500;
                plane.position.y = - Math.random() * Math.random() * 200 - 15;
                plane.position.z = i;
                plane.rotation.z = Math.random() * Math.PI;
                plane.scale.x = plane.scale.y = Math.random() * Math.random() * 1.5 + 0.5;

                THREE.GeometryUtils.merge(geometry, plane);
            }

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

            mesh = new THREE.Mesh(geometry, material);
            mesh.position.z = -8000;
            scene.add(mesh);

            renderer = new THREE.WebGLRenderer();
            renderer.setSize(window.innerWidth, window.innerHeight);

            container.append(renderer.domElement);

            window.addEventListener('resize', onWindowResize, false);

        }

        function onWindowResize(event) {

            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();

            renderer.setSize(window.innerWidth, window.innerHeight);

        }

        function animate() {

            requestAnimationFrame(animate);

            var position = ((Date.now() - start_time) * 0.03) % 8000;

            camera.position.x += (camera.position.x) * 0.01;
            camera.position.y += (camera.position.y) * 0.01;
            camera.position.z = -position + 8000;

            renderer.render(scene, camera);

        }

    }`

Answer №1

You've got multiple warnings that need to be addressed before proceeding. For example, color is not an attribute of THREE.ShaderMaterial. Additionally, the method

THREE.GeometryUtils.merge(geometry, plane);
has been relocated to a new API on Geometry. There are other issues that need attention as well.

I've simplified your code into a snippet that can be executed here (since we don't have access to your texture files).

Here are some key takeaways from the modifications I made:

  • I removed the initial canvas in your code. You can always add it back later. I also included { alpha: true } in the WebGLRenderer parameters, allowing content behind the renderer canvas to be visible.
  • Although I understand the use of
    new THREE.Mesh( new THREE.Plane(...) )
    , it might be more efficient to create individual plane meshes despite the increase in draw calls.
  • To get your code functioning, I replaced your shader definition with a basic color. If this updated code is working, we can explore the texture issue further. It's worth noting that you may not necessarily need a shader for this task. THREE.MeshBasicMaterial has a map property that can accept a THREE.Texture (provided by THREE.TextureLoader).
  • I managed the merging of geometries differently. The transformation properties of your plane do not update its vertices, which are needed for merge. Instead, I created a temporary THREE.Geometry object to store the updated vertices of your plane, applying the transformation matrix to them. This approach ensures the merged vertices are correctly positioned.

Outside of these adjustments, the core of your code remains unchanged. I recommend trying out these techniques in your own code. If you encounter difficulties with your textures, please leave a comment so we can revisit that aspect.

var camera, scene, renderer, texture, fog;
var mesh, geometry, material, buffer;

var start_time = Date.now();

init();
animate();

function init() {

  var container = $('#clouds');

  camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 3000);
  camera.position.z = 6000;

  scene = new THREE.Scene();

  geometry = new THREE.Geometry();

  material = new THREE.MeshBasicMaterial({color: 0xf2f2f2, opacity: 0.5, transparent: true});

  var plane = new THREE.Mesh( new THREE.PlaneGeometry(64, 64) ),
    tempGeometry = new THREE.Geometry();

  for (var i = 0; i < 8000; i++) {

    plane.position.x = Math.random() * 1000 - 500;
    plane.position.y = -Math.random() * Math.random() * 200 - 15;
    plane.position.z = i;
    plane.rotation.z = Math.random() * Math.PI;
    plane.scale.x = plane.scale.y = Math.random() * Math.random() * 1.5 + 0.5;
    // Warning: THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.
    //THREE.GeometryUtils.merge(geometry, plane);
    plane.updateMatrix();
    tempGeometry.copy(plane.geometry);
    tempGeometry.applyMatrix(plane.matrix);
    geometry.merge(tempGeometry);
  }

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

  mesh = new THREE.Mesh(geometry, material);
  mesh.position.z = -8000;
  scene.add(mesh);

  renderer = new THREE.WebGLRenderer({ alpha: true });
  renderer.setSize(window.innerWidth, window.innerHeight);

  container.append(renderer.domElement);

  window.addEventListener('resize', onWindowResize, false);

}

function onWindowResize(event) {

  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();

  renderer.setSize(window.innerWidth, window.innerHeight);

}

function animate() {

  requestAnimationFrame(animate);

  var position = ((Date.now() - start_time) * 0.03) % 8000;

  camera.position.x += (camera.position.x) * 0.01;
  camera.position.y += (camera.position.y) * 0.01;
  camera.position.z = -position + 8000;

  renderer.render(scene, camera);

}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://threejs.org/build/three.js"></script>
<div id="clouds" style="background: lightBlue;"></div>

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

Variable unique to the specific function in universal function

Can you explain why the alert displays "AAA" instead of "BBB"? http://jsfiddle.net/Lp4cS/ var z = "AAA"; function xx() { var z = "BBB"; yy(); } function yy() { alert(z); } xx(); ...

Position a div relative to another div with a static position

I am attempting to create a site that is fullscreen and responsive, but I am having issues with elements in the container overflowing on smaller screens, causing it to not be 100% as desired. I have tried using: top:100%; position:relative; width:100%; he ...

How can I obtain the model values for all cars in the primary object?

const vehicles={ vehicle1:{ brand:"Suzuki", model:565, price:1200 }, vehicle2:{ brand:"Hyundai", model:567, price:1300 }, vehicle3:{ brand:"Toyota", model ...

The ajaxForm function is failing to execute properly and is not providing any error messages

When trying to use jQuery ajaxForm, I encounter a strange issue. I am attempting to set up a form for file upload with progress percentage tracking. However, my ajaxForm function does not seem to be triggering at all. Below is the code snippet I am usin ...

Performing simultaneous document queries within a single API in MongoDB

I am currently working with an API written in typescript and attempting to execute parallel queries for the same document by using Promise.allSettled. However, I have noticed that it is performing poorly and seems to be running sequentially instead of in p ...

Tips for updating and triggering useEffect when the router changes in React JS

I have a ChartPage function that is being called three times within three different routers. Inside the ChartPage function, I am using "useEffect" to update some variables based on the selected route. However, for some reason, it only triggers once, and wh ...

Please include the document with a name that contains spaces

I am facing an issue where I cannot attach files with spaces in the name. However, when a file with no space in the name is successfully attached. I am using CodeIgniter for this purpose, uploading the file to the server before attaching it. I use the help ...

Is it necessary to use Hapi.js on the client side in order to establish a websocket connection using the Hapi.js protocol?

Currently, I am in the process of developing an API using Hapi and requiring WebSocket functionality. After some research, it appears that Nes is the preferred choice to integrate with Hapi for this purpose. Fortunately, Nes simplifies the process signific ...

the status of the XMLHttpRequest Object within the realm of jQuery AJAX

When using traditional JavaScript AJAX, we monitor the readystate property to determine the status: 0 - The request is not initialized 1- The request has been set up 2 - The request has been sent 3 - The request is in process 4 - The request is compl ...

Dynamically importing files in Vue.js is an efficient way to

Here's the code snippet that is functioning correctly for me var Index = require('./theme/dir1/index.vue'); However, I would like to utilize it in this way instead, var path = './theme/'+variable+'/index.vue'; var Inde ...

The Magnificent jQuery Widget Factory's _trigger Instance

When utilizing the _trigger function to initiate events, I often come across a recurring issue that I struggle to fully comprehend. The problem arises when there are multiple instances of my widget on the same page. In such cases, the most recently instan ...

Converting Callbacks to Promises in Node.js

I am facing a challenge with my node js application as I am attempting to promisify multiple callback functions without success. It has reached a point where I am unsure if it is even feasible. If you can assist me in promisifying the code provided below, ...

What is the best way to handle an ajax call while working with the main Vue instance?

I have a VueJS component that makes an AJAX call to GitHub using the following code: (Child) Component Vue.http.get('user/repos').then((response) => { console.log(response); }, (response) => { console.log(response); }); The issue ...

I am looking for a specific task to be carried out, without any need for returning a value or any additional items

I am trying to remove an element from the canvas using Selenium. The command I am currently using is "window.app.design.internalLayer().find('.deletebutton').fire('click')". Despite my efforts, this command does not seem to be working a ...

What is the best way to identify the type of an element using AngularJS?

Is it possible to use ng-model to identify the type of an element? For example: How can we determine if a specific element is a dropdown or a checkbox? HTML Code Snippet <select multiple ng-model='p.color'> <option value="red">Re ...

Error encountered: Difficulty rendering Vue 3 components within Google Apps Script

Currently delving into Vue and Vue 3 while coding an application on Google Apps Script. Following tutorials from Vue Mastery and stumbled upon a remarkable example by @brucemcpherson of a Vue 2 app functioning on GAS, which proved to be too challenging in ...

Using a variable in Ajax URL with Action razor syntax

I have a function that calls a method in the controller through an Action URL. However, I need to use a parameter as the name of the method, but unfortunately, this is not possible in the current implementation. function changeDropDownList(id, dropNameToC ...

Struggling to fill in fields using express and Mongodb

I am facing an issue with populating the fields of two models, Post and User. const PostSchema = new Schema({ text: { type: String }, author: { type: mongoose.Schema.Types.ObjectId, ref: 'user' } }) cons ...

What factors determine when Angular automatically triggers a setTimeout function compared to another?

Sorry if this all seems a bit odd, but I'll do my best to explain the situation. We have been given access to a small service that provides a simple form UI which we collect results from using an event. We've successfully implemented this in two ...

What are the necessary headers that must accompany a post request?

While testing the server with Postman, everything seems to be working fine as I receive a response: https://i.stack.imgur.com/yMRfj.png However, when attempting to make a POST request from the browser using the same address, it results in an error and th ...