2013-02-25 70 views
4

我是新來three.js所,並認爲這是很大的。我試圖更好地把紋理數據移動到着色器,所以我主要使用GPU。我立足於杜布先生的神奇的灰塵比如我的計劃,但我不使用存儲在質感顆粒,而加載模型。我目前遇到閃爍問題。下面的代碼是閃爍的一個粗略的例子,有一些貼近我在做什麼。如果有人可以幫助我瞭解我在做什麼錯誤或者閃爍是來自......我敢肯定什麼都在漲,最新,如紋理映射和three.js所修訂。 非常感謝three.js所着色,紋理閃爍

<!doctype html> 
<html> 
    <head> 
     <meta charset="utf-8" /> 
     <title>Sample Three.js</title> 
    </head> 

    <div id="container"> 
    </div> 

    <body> 
     <script type="text/javascript" src="./Scripts/three.js"></script> 

     <script type="text/javascript"> 

     // 
     // as name suggests - utilty functions mostly from Mr.doob from THREE.FBOUtils 
     // 
     UtilityFuncs = function() { 
      this.textureWidth = 0; 
      this.textureHeight = 0; 
      this.scene = null; 
      this.camera = null; 
      this.renderer = null; 
      this.material = null; 
      this.jsonLoader = null; 
      this.jsonModel = null; 
      this.loadCount = 0; 
     } 

     UtilityFuncs.prototype.createScene = function(textureWidth, textureHeight, renderer) { 
      var gl = renderer.getContext(); 

      if(!gl.getExtension("OES_texture_float")) { 
        alert("No OES_texture_float support for float textures!"); 
        return; 
      } 

      if(gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS) == 0) { 
        alert("No support for vertex shader textures!"); 
        return; 
      } 

      var camera = new THREE.OrthographicCamera(-textureWidth/2, textureHeight/2, 
                 textureWidth/2, -textureHeight/2, 
                 -1000, 1000); 
      camera.position.z = 100; 

      // Shader Stuff 
      var vertex_shader = [ 
       "varying vec2 vUv;", 
       "void main() {", 
       " vUv = vec2(uv.x, 1.0 - uv.y);", 
       " gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);", 
       "} " 
      ].join("\n"); 

      var fragment_shader = [ 
       "varying vec2 vUv;", 
       "uniform sampler2D tPositions;", 
       "void main() {", 
       " vec4 pos = texture2D(tPositions, vUv);", 
       " gl_FragColor = pos;", 
       "}" 
      ].join("\n"); 

      var material = new THREE.ShaderMaterial({ 
        uniforms: { 
         tPositions: { type: "t", value: null } 
        }, 
        vertexShader: vertex_shader, 
        fragmentShader: fragment_shader, 
        blending: THREE.NoBlending, 
        depthTest: false, 
        depthWrite: false, 
        side: THREE.DoubleSide 
      }); 

      var plane = new THREE.PlaneGeometry(textureWidth, textureHeight); 
      var quad = new THREE.Mesh(plane, material); 
      quad.position.z = 0; 
      var scene = new THREE.Scene(); 
      scene.add(camera); 
      scene.add(quad); 

      this.textureWidth = textureWidth; 
      this.textureHeight = textureHeight; 
      this.scene = scene; 
      this.camera = camera; 
      this.renderer = renderer; 
      this.material = material; 
     } 

     UtilityFuncs.prototype.createRenderTarget = function(width, height) { 
      var rtTexture = new THREE.WebGLRenderTarget(width, height, 
              { 
               wrapS:THREE.RepeatWrapping, 
               wrapT:THREE.RepeatWrapping, 
               minFilter: THREE.NearestFilter, 
               magFilter: THREE.NearestFilter, 
               format: THREE.RGBAFormat, 
               type:THREE.FloatType, 
               // renderbuffer defaults to RGB4 
               // if stencil & depth false! 
               // three.js, setupRenderBuffer::24848 
               stencilBuffer: false, 
               depthBuffer: true 
              }); 
      rtTexture.generateMipmaps = false; 
      return rtTexture; 
     } 

     UtilityFuncs.prototype.createFloatTextureFromData = function(width, height, data) { 
      var texture = new THREE.DataTexture(
       data, 
       width, 
       height, 
       THREE.RGBAFormat, 
       THREE.FloatType, 
       null, 
       THREE.RepeatWrapping, 
       THREE.RepeatWrapping, 
       THREE.NearestFilter, 
       THREE.NearestFilter 
      ); 

      texture.generateMipmaps = false; 
      texture.needsUpdate = true; 

      return texture; 
     }; 

     UtilityFuncs.prototype.readFramebuffer = function(renderer, framebuffer, width, height) { 
       var gl = renderer.getContext(); 
       gl.flush(); 
       if (framebuffer != null) 
        gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); 
       var rdData = new Uint8Array(width*height*4); 
       gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, rdData); 
       return rdData; 
     } 

     UtilityFuncs.prototype.readFloatFramebuffer = function(renderer, framebuffer, width, height) { 
       var gl = renderer.getContext(); 
       gl.flush(); 
       if (framebuffer != null) 
        gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); 
       var rdData = new Float32Array(width*height*4); 
       gl.readPixels(0, 0, width, height, gl.RGBA, gl.FLOAT, rdData); 
       return rdData; 
     } 

     UtilityFuncs.prototype.renderToTexture = function(texture, renderToTexture) { 
      this.material.uniforms.tPositions.value = texture; 
      this.renderer.render(this.scene, this.camera, renderToTexture, false); 
     }; 

     UtilityFuncs.prototype.render = function(texture) { 
      this.material.uniforms.tPositions.value = texture; 
      this.renderer.render(this.scene, this.camera); 
     }; 

     // 
     // start of main routines 
     // 
     var WIDTH = window.innerWidth, 
      HEIGHT = window.innerHeight; 
     var texWidth = 4, 
      texHeight = 4; 
     var container, renderer; 
     var start = Date.now(); 
     var rtTexture, rtTexture2; 
     var utilities; 
     var rdData, rdData2, ardData, ardData2; 

     function launch() { 

      container = document.getElementById("container"); 
      renderer = new THREE.WebGLRenderer({antialias:true}); 
      renderer.setSize(WIDTH, HEIGHT); 
      container.appendChild(renderer.domElement); 

      utilities = new UtilityFuncs(); 

      utilities.createScene(texWidth, texHeight, renderer); 

      rtTexture = utilities.createRenderTarget(texWidth, texHeight); 
      rtTexture2 = utilities.createRenderTarget(texWidth, texHeight); 


      // Create constant color test textures 
      var mData = new Float32Array(texWidth*texHeight*4); 
      for (var i = 0; i < 8; i++) { 
        mData[4*i] = 1.0; mData[4*i+1] = 0.0; mData[4*i+2] = 1.0; mData[4*i+3] = 1.0; 
      } 
      magentaTexture = utilities.createFloatTextureFromData(texWidth, texHeight, mData) 

      // Create constant color test textures 
      var cData = new Float32Array(texWidth*texHeight*4); 
      for (var i = 0; i < 8; i++) { 
        cData[4*i] = 0.0; cData[4*i+1] = 1.0; cData[4*i+2] = 1.0; cData[4*i+3] = 1.0; 
      } 
      cyanTexture = utilities.createFloatTextureFromData(texWidth, texHeight, cData) 

      utilities.renderToTexture(cyanTexture, rtTexture); 
      rdData = utilities.readFramebuffer(renderer, rtTexture.__webglFramebuffer, 
               texWidth, texHeight); 

      utilities.renderToTexture(magentaTexture, rtTexture2); 
      rdData2 = utilities.readFramebuffer(renderer, rtTexture2.__webglFramebuffer, 
               texWidth, texHeight); 

      if (rdData[0] != 0 || rdData[1] != 255 || rdData[2] != 255 || rdData[3] != 255) 
       console.log("rtTexture load fail\n"); 

      if (rdData2[0] != 255 || rdData2[1] != 0 || rdData2[2] != 255 || rdData2[3] != 255) 
       console.log("rtTexture2 load fail\n"); 

      animate(); 
     } 

     var timer = 0; 

     function animate() { 
      requestAnimationFrame(animate); 
      render(); 
     } 

     function render() { 
      // 
      // copy rtTexture and rtTexture2 between each other 
      // 

      utilities.renderToTexture(rtTexture, rtTexture2); 
      ardData2 = utilities.readFramebuffer(renderer, rtTexture2.__webglFramebuffer, 
               texWidth, texHeight); 

      utilities.renderToTexture(rtTexture2, rtTexture); 
      ardData = utilities.readFramebuffer(renderer, rtTexture.__webglFramebuffer, 
                texWidth, texHeight); 

      if (timer & 1) 
       utilities.render(rtTexture2); 
      else 
       utilities.render(rtTexture); 

      if (ardData[0] != 0 || ardData[1] != 255 || ardData[2] != 255 || ardData[3] != 255) 
       console.log("rtTexture fail\n"); 
      if (ardData2[0] != 0 || ardData2[1] != 255 || ardData2[2] != 255 || ardData2[3] != 255) 
       console.log("rtTexture2 fail\n"); 
      timer++; 
     } 

     //launch(); 

     </script> 
     <button id="renderButton" onClick="launch()">Render</button> 
     <br/> 
    </body> 
</html> 

回答

0

那麼,如果你改變你的循環,你從補的紋理閃爍將停止:

for (var i = 0; i < 8; i++) ==>> for (var i = 0; i < texWidth*texHeight*4; i++) 

,但我不斷收到「rtTexture2失敗」無論在Chrome和Firefox。

我發現另一個錯誤。線;

if (ardData2[0] != 0 || ardData2[1] != 255 || ardData2[2] != 255 || ardData2[3] != 255) 

應該是:

if (ardData2[0] != 255 || ardData2[1] != 0 || ardData2[2] != 255 || ardData2[3] != 255) 

,但我仍然無法擺脫上述錯誤的。