title: Weird (colorless) texture rendering in THREE.js under Node.js
body: <p>Trying to render GLB file with THREE.js on Node.js but get wrong result.
  Everything is running under Debian on WSL2 with mesa drivers installed (as instructed by headless-gl package description).
  The app runs with <code>xvfb-run -s &quot;-ac -screen 0 1280x1024x24&quot; node --trace-warnings -r esm app.js</code> command.</p>
  <p>I using <code>JSDOM, canvas, node-canvas-webgl, xhr2</code> packages to emulate browser behavior to make THREE and GLTFLoader code running.</p>
  <p><a href="https://i.stack.imgur.com/ZO1lq.jpg" rel="nofollow noreferrer">expected result</a> - <a href="https://i.stack.imgur.com/miqDj.png" rel="nofollow noreferrer">what I get</a></p>
  <p>I also creating panorama with <code>CubemapToEquirectangular</code> but even without this package rendering works incorrect.</p>
  <p><a href="https://i.stack.imgur.com/lSDG4.jpg" rel="nofollow noreferrer">result in browser</a> - <a href="https://i.stack.imgur.com/TJL2B.jpg" rel="nofollow noreferrer">result in node</a></p>
  <p>This initial code helps me run everything I need.</p>
  <pre><code>const { JSDOM } = require('jsdom');
  
  const { window } = (new JSDOM('&lt;!doctype html&gt;&lt;html&gt;&lt;head&gt;&lt;title&gt;&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;/body&gt;&lt;/html&gt;'));
  global.window = window;
  global.self = window;
  
  global.document = window.document;
  
  global.navigator = window.navigator;
  
  global.File = window.File;
  global.FileReader = window.FileReader;
  global.Blob = window.Blob;
  
  const createObjectURL = async object =&gt; {
    if (object instanceof Blob) {
      const convert = new Promise(resolve =&gt; {
        const a = new FileReader();
        a.onload = function(e) { resolve(e.target.result); };
        a.readAsDataURL(object);
      });
      return await convert;
    } else return typeof object === typeof '' ? object : '';
  };
  
  global.URL = window.URL;
  global.URL.createObjectURL = createObjectURL;
  global.URL.revokeObjectURL = url =&gt; null;
  
  global.XMLHttpRequest = require('xhr2');
  
  global.atob = require('atob');
  
  const nodeCanvas = require('canvas');
  
  global.ImageData = nodeCanvas.ImageData;
  global.Image = nodeCanvas.Image;
  
  global.Image.prototype.addEventListener = function(type, listener, useCapture) {
    this['on' + type] = listener.bind(this);
  };
  global.Image.prototype.removeEventListener = function(type, listener, useCapture) {
    this['on' + type] = null;
  };
  
  global.document.createElementNS = (uri, type) =&gt; {
    if (type === 'img') {
      const image = new global.Image();
      return image;
    }
    return window.document.createElementNS(uri, type);
  };
  
  global.TextDecoder = require('util').TextDecoder;
  </code></pre>
  <p>I also use <code>createCanvas</code> from <code>node-canvas-webgl</code> to create canvas for renderer</p>
  <pre><code>const { createCanvas } = require('node-canvas-webgl/lib');
  
  const canvas = createCanvas(512, 512);
  const renderer = new THREE.WebGLRenderer({ canvas });
  </code></pre>
  <p>BTW <code>node-canvas-webgl/lib/canvas.js</code> is modified on line <code>108</code> to make it work correct</p>
  <pre><code>- if(pixels._image) pixels = pixels._image;
  + if(pixels &amp;&amp; pixels._image) pixels = pixels._image;
  </code></pre>
  <p>The rest of the code is pretty much the same as in every THREE examples.</p>
  <p>I also have to mention that Duck.glb renders correct, but no other big model I have tried.</p>
  <p><a href="https://i.stack.imgur.com/7UN2Y.jpg" rel="nofollow noreferrer">duck is okay</a></p>
  <p>Did someone faced this problem and is there any solution?</p>