2013-02-25 3 views
4

저는 three.js를 처음 사용하며 훌륭하다고 생각합니다. 텍스쳐 데이터를 쉐이더로 옮겨 놓는 것이 더 좋습니다. GPU를 주로 사용할 수 있습니다. Doob의 마술 먼지 예제를 기반으로 프로그램을 만들었지 만 텍스처로 저장된 모델보다는 오히려 입자를 사용하고 있습니다. 현재 내가 깜박 거리는 문제가 있습니다. 아래의 코드는 깜박임의 대략적인 예이며 내가하고있는 것에 대해 어느 정도 친숙합니다. 누구나 내가 잘못하고있는 부분이나 깜박 거리는 부분을 이해하는 데 도움이 될 수 있다면 ... 텍스처 매핑과 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 실패"점점 계속.

다른 오류가 발견되었습니다. 선;

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

하지만, 난 여전히 위의 오류를 제거 얻을 수 없습니다

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

이 있어야한다.

관련 문제