Error message in Three.JS: Texture does not have dimensions that are a power of two and therefore cannot be modified

Seeking assistance with building a dynamic 360 image gallery. When a gallery image is clicked, a modal opens with a 360 viewer inside. However, I am experiencing errors related to image sizes and textures.

THREE.WebGLRenderer: image is not power of two (1920x960). Resized to 2048x1024 
blob:http://nolan.bfdevserver.com/7ca91892-2e3b-4fff-b672-ec250ef13498 new image blob
blob:http://nolan.bfdevserver.com/7788013c-9611-497a-bc12-66a06bb2244f old image blob
THREE.WebGLRenderer: image is not power of two (0x0). Resized to 0x0 
THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. 
THREE.Texture
WebGL: INVALID_VALUE: texImage2D: no canvas

The console shows the following error:

material.minFilter = THREE.LinearFilter;

I am uncertain about why this issue persists.

<div id="container" data="<?php $ThreeSixtyImage = the_field('image'); ?>"></div>

<div id="gallery-modal" class="modal">
</div> 

<div id="gallery" class="gallery">
    <div class="gallery-item">
        <img src="https://www.bluefire360.com/wp-content/uploads/V4260450-min.jpg" />
    </div>
    <div class="gallery-item">
        <img src="http://nolan.bfdevserver.com/wp-content/uploads/pano_2048.jpg" />
    </div>
    <div class="gallery-item">
        <img src="http://nolan.bfdevserver.com/wp-content/uploads/pano_2048.jpg" />
    </div>
</div>

        <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r79/three.min.js"></script>

  var camera, scene, renderer;
        var Container = document.getElementById('container');
        var imageFile = Container.getAttribute('data');

        var isUserInteracting = false,
        onMouseDownMouseX = 0, onMouseDownMouseY = 0,
        lon = 0, onMouseDownLon = 0,
        lat = 0, onMouseDownLat = 0,
        phi = 0, theta = 0;

        init();
        animate();


        function init() {

            var container, mesh;

            container = document.getElementById( 'gallery-modal' );

            camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1100 );
            camera.target = new THREE.Vector3( 0, 0, 0 );

            scene = new THREE.Scene();

            var geometry = new THREE.SphereGeometry( 500, 60, 40 );
            geometry.scale( - 1, 1, 1 );

            var material = new THREE.MeshBasicMaterial( {
                map: new THREE.TextureLoader().load(  imageFile )
            } );

            material.minFilter = THREE.LinearFilter;

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

            scene.add( mesh );

            renderer = new THREE.WebGLRenderer();
            renderer.setPixelRatio( window.devicePixelRatio );
            //renderer.setSize( window.innerWidth, window.innerHeight );
            renderer.setSize( window.innerWidth, 500);
            container.appendChild( renderer.domElement );


            // Controls to move the image
            document.addEventListener( 'mousedown', onDocumentMouseDown, false );
            document.addEventListener( 'mousemove', onDocumentMouseMove, false );
            document.addEventListener( 'mouseup', onDocumentMouseUp, false );
            document.addEventListener( 'wheel', onDocumentMouseWheel, false );

            document.addEventListener( 'dragover', function ( event ) {

                event.preventDefault();
                event.dataTransfer.dropEffect = 'copy';

            }, false );

            document.addEventListener( 'dragenter', function ( event ) {

                document.body.style.opacity = 0.5;

            }, false );

            document.addEventListener( 'dragleave', function ( event ) {

                document.body.style.opacity = 1;

            }, false );

            /// ADDITIONAL CODE STARTS HERE

            var galleryDOM = document.getElementById('gallery');
            var modal = document.getElementById('gallery-modal');

                galleryDOM.addEventListener('click', function(e) {

                    if(e.target.localName == 'img') {

                        // Show Modal
                        modal.style.display = "block";

                        // Create blob from image url
                        var blob = new Blob([e.target.src], {type: 'url'});             
                        var newestImage = window.URL.createObjectURL(blob);

                        console.log(newestImage,  "new image blob")
                        console.log(material.map.image.src,  "old image blob")

                        // Apply newestImage to material object in THREEjs
                        if(newestImage) {
                            material.map.image.src = newestImage;
                            material.map.needsUpdate = true;

                        }

                    }
                });

                window.onclick = function(event) {
                    if (event.target == modal) {
                        modal.style.display = 'none';
                    }
                }

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

        }

        function dataURItoBlob(dataURI) {
            var mime = dataURI.split(',')[0].split(':')[1].split(';')[0];
            var binary = atob(dataURI.replace(/^data:image\/(png|jpeg|jpg);base64,/, ''));
            var array = [];
            for (var i = 0; i < binary.length; i++) {
                array.push(binary.charCodeAt(i));
            }
            return new Blob([new Uint8Array(array)], {type: mime});
        }

        function onWindowResize() {

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

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

        }

        function onDocumentMouseDown( event ) {

            event.preventDefault();

            isUserInteracting = true;

            onPointerDownPointerX = event.clientX;
            onPointerDownPointerY = event.clientY;

            onPointerDownLon = lon;
            onPointerDownLat = lat;

        }

        function onDocumentMouseMove( event ) {

            if ( isUserInteracting === true ) {

                lon = ( onPointerDownPointerX - event.clientX ) * 0.1 + onPointerDownLon;
                lat = ( event.clientY - onPointerDownPointerY ) * 0.1 + onPointerDownLat;

            }

        }

        function onDocumentMouseUp( event ) {

            isUserInteracting = false;

        }

        function onDocumentMouseWheel( event ) {

            camera.fov += event.deltaY * 0.05;
            camera.updateProjectionMatrix();

        }

        function animate() {

            requestAnimationFrame( animate );
            update();

        }

        function update() {

            if ( isUserInteracting === false ) {

                lon += 0.1;

            }

            lat = Math.max( - 85, Math.min( 85, lat ) );
            phi = THREE.Math.degToRad( 90 - lat );
            theta = THREE.Math.degToRad( lon );

            camera.target.x = 500 * Math.sin( phi ) * Math.cos( theta );
            camera.target.y = 500 * Math.cos( phi );
            camera.target.z = 500 * Math.sin( phi ) * Math.sin( theta );

            camera.lookAt( camera.target );

            /*
            // distortion
            camera.position.copy( camera.target ).negate();
            */

            renderer.render( scene, camera );

        }

Any assistance or guidance would be greatly appreciated as I continue to work through these challenges. Thank you!

Answer №1

To correct the power of two error, simply modify this line:

material.minFilter = THREE.LinearFilter;

to

material.map.minFilter = THREE.LinearFilter;

Additionally, in order to ensure the texture updates correctly, switch from using a blob url to a standard image url and implement the following code:

if(newestImage) {
   material.map = new THREE.TextureLoader().load(newestImage);
}

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

AngularJS directive that allows for either a click action to be passed or a ui-router state change to

I have a button (an a tag) that is displayed in multiple locations on my website. It is labeled "View Demo", and sometimes it directs to a demo page using an ui-sref: <a class="btn btn-primary" ui-sref="hamburger-push" target="_blank"> View Demo ...

Combining mouse interactions with animated bar transitions

I want to create a graph with dynamic bar height transitions whenever it is drawn or redrawn. Once the bars are displayed, I would like mouse events (mouseenter, mouseleave, and mousemove) to trigger a tooltip showing information about the specific bar bei ...

Should I consider using Derby.js or Meteor for a production app with authentication capabilities?

Recently, I delved into researching Derby.js and Meteor for a project I'm currently working on. Both frameworks offer real-time functionalities that could be quite useful. However, I have some reservations and am contemplating whether it's the ri ...

Python Selenium driver.execute_script() is not returning expected values even though a return value is provided in the JavaScript script that is passed in

I am currently facing an issue with a selenium webdriver object while using the execute_script method. Despite inputting this JavaScript script: var data = document.getElementsByClassName("assignment__row break-word clickable flex--space-between ng-st ...

Tips for creating multiple files using nodejs and express

I am currently working on developing a personalized code editor that consists of 3 textareas: html, css, and javascript. The objective is to save the data from each textarea into individual files. With the help of express and nodejs, I have successfully m ...

Maintain only specific elements in jQuery by filtering out the rest

Here is a scenario with a page layout to consider: <div id="page-container" class=""> <div id="scroller"> <!-- This page should be removed --> <div id="page_1" class="pagina"></div> <!-- These pages should be kept --&g ...

Switching a class component to a functional component with react hooks (specifically useRef) - tips for preventing the dreaded "undefined" error

I have a code snippet that works as a class component and I'm trying to convert it into a functional component using the react-rewards library. Class component (working): import { Checkbox } from "@chakra-ui/react"; import React, { Compone ...

What is preventing TypeScript from identifying the type of a parent based on its child?

Take a moment to explore the following example: type Num = { type: 'NUMBER' numberValue: number } type Str = { type: 'STRING', stringValue: string } type B_Num = { a: Num; numberData: number; } type B_Str = { ...

The function fails to execute on the initial attempt

Currently, I am utilizing Kendo controls, specifically focusing on the Grid and Drop Down Lists. Since the Kendo Grid components do not come with a built-in handler for double click events, I have implemented some JQuery code to work around this limitatio ...

The jQuery load() callback triggering a POST request unexpectedly instead of a GET request

Utilizing jQuery's load() method, I am attempting to insert a page fragment into a new page. It appears that this can only be achieved with load(), as get() does not support page fragments. Upon completion of the load, it is necessary for me to invok ...

Trouble with AJAX request when trying to connect to a distant server

I am facing an issue with my AJAX request. When I test it on localhost, everything works perfectly fine. However, when I upload the code to a remote server, the request fails without any error messages. Even after checking in Firefox and Chrome, there ar ...

Discovering the URL of an AJAX request on any given website

Is there a way to retrieve the URLs of AJAX requests that are sent by the current page on a website using a browser or another tool? ...

Utilizing AngularJS to iterate through an array of dictionaries

Within a specific section of my HTML code, I am initializing a scope variable like this: $scope.my_data = [ { c1: "r1c1", c2: "r1c2", c3: "r1c3", ...

A collection of jQuery objects that consist of various DOM elements as their properties

Seeking a more concise and potentially more streamlined approach using jQuery. I have an object called lbl which represents a div. Inside this div, there is a span tag that contains the properties firstName and lastName of the lbl object. Here's how t ...

Java persistence with AJAX technology

Being a beginner in server side development, I am currently working on creating a database application for my company that will store links to all our marketing videos. Each entry consists of a URL (link to video), description, industry, and more. So far, ...

The RxJs Observer connected to a websocket only triggers for a single subscriber

Currently, I am encapsulating a websocket within an RxJS observable in the following manner: this.wsObserver = Observable.create(observer=>{ this.websocket.onmessage = (evt) => { console.info("ws.onmessage: " + evt); ...

Developing a Node.js API using Express and MySQL involves utilizing the WHERE IN clause and binding parameters with multiple comma-separated values

Having a URL structure as shown below, where multiple comma-separated values can be added to the URL: localhost:4001/api/v1/users/search?title=mr,dr This is my query implementation: router.get('/search?', function(req, res, next) { var ...

Is it possible to pass an HTML element's id attribute to a function in JavaScript?

In the following code snippet, I am looking to send the id=content to the function mr and then display the result in the passed id=result. While this functionality is currently limited to this HTML file, I aim to extend it to other HTML pages by adding the ...

PHP redirect malfunctioning, yet still functioning?

After making some changes to the structure of my website, I seem to have broken the script somehow. When a user fills out a form correctly, they should be redirected to the appropriate page. However, the page just hangs. Strangely, the form works fine when ...

Is it possible to invoke Bootstrap modal functions without using jQuery?

I'm in the process of removing jQuery dependencies from my app, but I still rely on Bootstrap. Is there a way to trigger modal functions like $('#myModal').modal('show') without using jQuery now? ...