1
votes

Using three.js r71. I can't figure out why my texture is not being read by the ShaderMaterial. The plane is just black. I need a pair of fresh eyes to help me pinpoint what is wrong.

Thanks a lot !

Here's the HTML:

<!DOCTYPE html>

<html>
  <head>
    
    <script src="jquery.min.js"></script>
    <script src="three.min.js"></script>
    <script src="testshdr.js"></script>
    
  </head>
  
  <body>
   
    <!-- Shaders -->
    <script id="vertexShader" 
            type="x-shader/x-vertex" >

    varying vec2 vUv;

    void main(){
      vUv = uv;
      gl_Position = projectionMatrix * 
                    modelViewMatrix * 
                    vec4(position, 1.0);

    }

    </script>

    <script name="no_effect"
            id="fragmentShader_0"
            type="x-shader/x-fragment" >

    varying vec2 vUv;

    uniform sampler2D editImg;

    void main(){
      vec4 myTexture = texture2D(editImg, vUv);
      gl_FragColor = vec4 (myTexture.r, 
                           myTexture.g, 
                           myTexture.b, 
                           1.0);

    }

    </script>
   
    <script type="text/javascript">
      var tst = new TestShdr();
    </script>

  </body>
  
</html>

And here's the JS:

var TestShdr = function () {
  'use strict';
  
  var
    SCENE,
    RENDERER,
    CAMERA,
    GEO,
    MAT,
    OBJ,
    TEX,
    UNIFS,
    VS,
    FS;
  
  SCENE = new THREE.Scene();
  RENDERER = new THREE.WebGLRenderer();
  RENDERER.setSize(256, 256);
  
  CAMERA = new THREE.PerspectiveCamera(56, 1, 0.1, 1000);
  
  SCENE.add(CAMERA);
  CAMERA.position.z = 5;
  
  TEX = THREE.ImageUtils.loadTexture('1107.jpg');
  
  UNIFS = {
    editImg: { type: 't', value: TEX}
  };
  VS = $('#vertexShader').html();
  FS = $('#fragmentShader_0').html();
  
  GEO = new THREE.PlaneBufferGeometry(1, 1, 1, 1);
  MAT = new THREE.ShaderMaterial({uniforms: UNIFS,
                                  vertexShader: VS,
                                  fragmentShader: FS
                                 });
  OBJ = new THREE.Mesh(GEO, MAT);
  SCENE.add(OBJ);
  
  document.body.appendChild(RENDERER.domElement);
  
  RENDERER.render(SCENE, CAMERA);
  
};
1
Well for one you aren't waiting for the texture to load. textures load asynchronously. It won't be available at the time you render given your code above.gman

1 Answers

2
votes

You should be doing:

TEX = THREE.ImageUtils.loadTexture('1107.jpg', {}, function() {
    RENDERER.render(SCENE, CAMERA);
});