title: Plane Flickering on using ShaderMaterial in Threejs
body: <p>I'm trying to apply a texture on a very large plane (1000x1000 which is also scaled 10 times) by using RepeatWrapping. It looks good when I use MeshBasicMaterial but it flickers when I use ShaderMaterial. Below is My Code. </p>
  
  <pre><code>    &lt;!DOCTYPE html&gt;
  &lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;MeshShaderMaterialExample&lt;/title&gt;
    &lt;meta charset="utf-8"&gt;
    &lt;meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0, shrink-to-fit=no"&gt;
  
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/99/three.min.js"&gt;&lt;/script&gt;
    &lt;script src="https://unpkg.com/three@0.85.0/examples/js/controls/TrackballControls.js"&gt;&lt;/script&gt;
  &lt;script src="js/TWEEN.js"&gt;&lt;/script&gt;
    &lt;style type="text/css"&gt;
      body {
        width: 100%;
        height: 100%;
        background-color: #000;
        color: #fff;
        margin: 0px;
        padding: 0;
        overflow: hidden;
      }
    &lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
  &lt;script&gt;
    var camera, scene, renderer;
  var container, mesh, geometry;
  var controls, effect;
    var tweenUpdate="false";
    var tweenOver="true";
    var textureData=
  {
    "texture_0":
    {
      "img":"gman.png"
    },
    "texture_1":
    {
      "img":"gman.png"
    }}
  var magicPosition = { magicTrans:0 };
  var magicTarget = { magicTrans:1 };
  var magicTween = new TWEEN.Tween(magicPosition).to(magicTarget, 1000);
  magicTween.easing(TWEEN.Easing.Linear.None);
  var currentTexture=0;
  var nextTexture=0;
  var uniforms = {
    textures: {
      value: []
    },
    repeat: {
        type: 'f',
        value: 100
    },
    transition: { 
      value: 0
    },
    currentUniform: { 
      value: 0
    },
    nextUniform: { 
      value: 0
    }
  };
  
  var textureLoader = new THREE.TextureLoader();
  
  var pics=[];
  for (var i = 0; i &lt; Object.keys(textureData).length; i++) {
    var ass="texture_"+i;
    pics[i]= textureData[ass].img;
    console.log(pics[i]);
  }
  pics.forEach((p, idx)=&gt;{
    textureLoader.load(p, function(tex){
      tex.needsUpdate = true;
      uniforms.textures.value[idx] = tex;
  uniforms.textures.value[idx].needsUpdate = true;
  // console.log(tex);
          uniforms.textures.value[idx].minFilter = THREE.LinearFilter;
  
    })
  });
  var vertShader = `
      varying vec2 vUv;
      uniform float repeat;
      void main()
      {
  
        vUv = repeat * uv;
  
        vec4 mvPosition = modelViewMatrix * vec4(position, 1 );
        gl_Position = projectionMatrix * mvPosition;
  
      }
    `;
  var fragShader = `
      uniform sampler2D textures[` + pics.length + `];
      uniform float transition;
      uniform float currentUniform;
      uniform float nextUniform;
      varying vec2 vUv;
  
      vec4 getTexture(int index){
        for(int i = 0; i &lt; ` + pics.length + `; i++){
           if (i == index){ return texture2D(textures[i],vUv); }
        }
      }
      void main()
      {
  
          float chunk = 1. / ` + 1 + `.; // amount of transitions = 1
          float t = floor(transition / chunk);
          int idx0 = int(currentUniform);
          int idx1 = int(nextUniform); 
          gl_FragColor = mix(
            getTexture(idx0),
            getTexture(idx1),
            (transition - (float(t) * chunk)) * ` + 1 + `.
          );
  
  
      }
    `;
  
    window.onload=function()
  {
    init();
    animate();
  }
  
  function init(){
  
  
    renderer = new THREE.WebGLRenderer();
    renderer.setPixelRatio( window.devicePixelRatio );
    renderer.setSize( window.innerWidth, window.innerHeight );
    document.body.appendChild(renderer.domElement);
  
    camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );
  
    controls = new THREE.TrackballControls( camera,renderer.domElement  );
  camera.position.z = 500;
    console.log(camera.fov);
  
    scene = new THREE.Scene();
  
  
    scene.add(camera);
    var magicPlaneMaterial = new THREE.ShaderMaterial({
    uniforms: uniforms,
    vertexShader: vertShader,
    fragmentShader: fragShader,
      side: THREE.DoubleSide
    });
  
    for (var i = 0; i &lt; Object.keys(textureData).length; i++) {
      uniforms.textures.value[i].wrapS = uniforms.textures.value[i].wrapT = THREE.RepeatWrapping;
      uniforms.textures.value[i].needsUpdate = true;
  
    }
    // for (var i = 0; i &lt; Object.keys(textureData).length; i++) {
    //   uniforms.textures.value[i].wrapS = uniforms.textures.value[i].wrapT = THREE.RepeatWrapping;
    //   uniforms.textures.value[i].needsUpdate = true;
  
    // }
  
  
    var magicPlaneGeometry = new THREE.PlaneBufferGeometry(1000, 1000, 16, 16);
  
    var magicPlaneMesh = new THREE.Mesh(magicPlaneGeometry, magicPlaneMaterial);
    magicPlaneMesh.position.y = -500;
    magicPlaneMesh.rotation.x = Math.PI / 2;
    magicPlaneMesh.scale.x=10;
    magicPlaneMesh.scale.y=10;
    scene.add(magicPlaneMesh);
    changeMagicPlane(currentTexture);
    document.addEventListener( 'wheel', onDocumentMouseWheel, false );
  
    window.addEventListener( 'resize', onWindowResize, false );
  }
  
  
  function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize( window.innerWidth, window.innerHeight );
  }
  
  function onDocumentMouseWheel( event ) {
    var fov = camera.fov + event.deltaY * 0.05;
  
    camera.fov = THREE.Math.clamp( fov, 10, 75 );
    console.log(camera.fov);
  
    camera.updateProjectionMatrix();
  }
  
  function animate() {
      if(tweenUpdate=="true")
    {
      TWEEN.update();
    }
      renderer.render( scene, camera );
    controls.update();
    requestAnimationFrame( animate );
  }
  function changeMagicPlane(asset){
    var assNum= parseInt(asset);    
    nextTexture = assNum;
    uniforms.nextUniform.value = nextTexture;
    console.log("Cuurent: "+currentTexture);
    console.log("Next: "+nextTexture);    
    magicTween.start(); 
    tweenUpdate="true";
    tweenOver="false";
  }
  magicTween.onUpdate(function(){
  uniforms.transition.value = magicPosition.magicTrans;
  });
  magicTween.onComplete(function(){
    tweenUpdate="false";
    tweenOver="true";
      clicked="false";
      //console.log("Am i complete?");
      magicPosition.magicTrans=0;
      currentTexture=nextTexture;
      uniforms.currentUniform.value = currentTexture;
      console.log("Current: "+currentTexture);
  });
  &lt;/script&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>I'm trying to use ShaderMaterial for crossfading effect. My texture image is 256*256 pixels.</p>
  
  <p>Working snippet. Tween.js is used from here (<a href="http://learningthreejs.com/blog/2011/08/17/tweenjs-for-smooth-animation/" rel="nofollow noreferrer">http://learningthreejs.com/blog/2011/08/17/tweenjs-for-smooth-animation/</a>). gman.png is from here (<a href="https://i.imgur.com/ZKMnXce.png" rel="nofollow noreferrer">https://i.imgur.com/ZKMnXce.png</a>)</p>