【问题标题】:How do you update a uniform In Three.js?如何在 Three.js 中更新制服?
【发布时间】:2015-07-07 20:49:30
【问题描述】:

我不得不重写我的问题,因为我之前问错了问题。

我是想问,怎么更新three.js中的制服?

【问题讨论】:

  • 你似乎有它倒退。每一帧都会更新制服。
  • 哦,哎呀,你是对的,我用错了术语。我想我的问题真的是,如何在不使用 Vector2 或 Vector3 的情况下更新浮动制服?而且我认为无论如何你这样做会更好。
  • 我想我找到了。是吗:yourMesh.material.uniforms.yourUniform.value = 不管; ?我需要注意哪些性能问题?
  • 所有制服都有一个类型和一个值。更新.value
  • 我觉得你在这里发帖太快了。

标签: javascript three.js shader


【解决方案1】:

这似乎有效:

yourMesh.material.uniforms.yourUniform.value = whatever;

【讨论】:

    【解决方案2】:

    有两种方式:

    • 您可以在Shader Material 本身中更新uniform

    • 您可以使用mesh.material 访问ShaderMaterial,然后更新uniform

      两种情况的示例:

         var  delta = 0
         var customUniforms = {
          delta: { value: 0 },
          u_time: { value: Date.now() }
         };
      
          // shader material with custom Uniform
          shaderMaterial = new THREE.ShaderMaterial({
            uniforms: customUniforms,
            vertexShader: document.getElementById("vertexShader2").textContent,
            fragmentShader: document.getElementById("fragmentShader2").textContent
          });
      
          // test Mesh object for shader
          var geometry = new THREE.BoxBufferGeometry(10, 10, 10, 10, 10, 10);
          shaderMesh = new THREE.Mesh(geometry, shaderMaterial);
          this.scene.add(shaderMesh);
      

      在动画循环中

        animate = () => {
          delta += 0.1; 
      
                // Update uniform in Shader Material
                shaderMaterial.uniforms.delta.value = 0.5 + Math.sin(delta) * 0.0005;
      
                // Update uniform from Mesh itself
           shaderMesh.material.uniforms.u_time.value = delta;
      
      }
      

    https://codesandbox.io/s/autumn-http-e9wk5

    完整示例

    <body>
        <div id="container"></div>
        <script src="js/three.min.js"></script>
        <script id="vertexShader" type="x-shader/x-vertex">
            void main() {
                gl_Position = vec4( position, 1.0 );
            }
        </script>
        <script id="fragmentShader" type="x-shader/x-fragment">
            uniform vec2 u_resolution;
            uniform float u_time;
    
            void main() {
                vec2 st = gl_FragCoord.xy/u_resolution.xy;
                gl_FragColor=vec4(st.x,st.y,0.0,1.0);
            }
        </script>
        <script>
            var container;
            var camera, scene, renderer;
            var uniforms;
    
            init();
            animate();
    
            function init() {
                container = document.getElementById( 'container' );
    
                camera = new THREE.Camera();
                camera.position.z = 1;
    
                scene = new THREE.Scene();
    
                var geometry = new THREE.PlaneBufferGeometry( 2, 2 );
    
                uniforms = {
                    u_time: { type: "f", value: 1.0 },
                    u_resolution: { type: "v2", value: new THREE.Vector2() },
                    u_mouse: { type: "v2", value: new THREE.Vector2() }
                };
    
                var material = new THREE.ShaderMaterial( {
                    uniforms: uniforms,
                    vertexShader: document.getElementById( 'vertexShader' ).textContent,
                    fragmentShader: document.getElementById( 'fragmentShader' ).textContent
                } );
    
                var mesh = new THREE.Mesh( geometry, material );
                scene.add( mesh );
    
                renderer = new THREE.WebGLRenderer();
                renderer.setPixelRatio( window.devicePixelRatio );
    
                container.appendChild( renderer.domElement );
    
                onWindowResize();
                window.addEventListener( 'resize', onWindowResize, false );
    
                document.onmousemove = function(e){
                  uniforms.u_mouse.value.x = e.pageX
                  uniforms.u_mouse.value.y = e.pageY
                }
            }
    
            function onWindowResize( event ) {
                renderer.setSize( window.innerWidth, window.innerHeight );
                uniforms.u_resolution.value.x = renderer.domElement.width;
                uniforms.u_resolution.value.y = renderer.domElement.height;
            }
    
            function animate() {
                requestAnimationFrame( animate );
                render();
            }
    
            function render() {
                uniforms.u_time.value += 0.05;
                renderer.render( scene, camera );
            }
        </script>
    </body>
    

    【讨论】:

      【解决方案3】:

      更新着色器制服的小例子。

      /* Vertex Shader */
      <script type="x-shader/x-fragment" id="myShader">
          uniform float myuniform;
          uniform sampler2D myTexture;
          varying vec2 vUV;
          varying vec2 ver;
      
          ver = uv *vec2( myuniform,  myuniform); // this will be updated on mouse move        
      
          gl_Position = projectionMatrix *modelViewMatrix * vec4(position,1.0);
      </script>
      
      /* Set uniform */
      var myUniform;
      var myTexture = new THREE.ImageUtils.loadTexture( './data/textures/theTexture.jpg'  );
          _uniforms = {
          myUniform:  { type: "f", value: myUniform },        
          myTexture:  { type: "t", value: myTexture },
      };
      
      customMaterial = new THREE.ShaderMaterial( 
      {
          uniforms: _uniforms,
          vertexShader: document.getElementById( 'myShader' ).textContent,
          fragmentShader: document.getElementById( 'fragmentShader' ).textContent,
          wireframe: false,
          side: THREE.FrontSide 
      
      }   );
      
      document.addEventListener( 'mousemove', onDocumentMouseMove, false );
      
      function onDocumentMouseMove(ev) {
         uniforms.myUniform.value += 0.01; // Updates this new value
         uniforms.myUniform.needsUpdate = true;
      }
      
      ...
      

      【讨论】:

        【解决方案4】:

        对于我的用例来说,这似乎是一个很好的方法:

        const mat = new THREE.ShaderMaterial({
            uniforms: {
                customVec3Uniform: { value: new THREE.Vector3(1,1,1) }
            },
            vertexShader: document.getElementById('vertexShader').textContent,
            fragmentShader: document.getElementById('fragmentShader').textContent,
        });
        

        关于运行时更新(citation):

        mat.uniforms.customVec3Uniform.value = new THREE.Vector3(2,2,2);
        // mat.needsUpdate = true; // my example works without 'needsUpdate'
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-09-28
          • 1970-01-01
          • 2013-12-16
          • 2012-08-30
          • 2014-06-22
          • 2013-12-14
          • 2020-07-03
          • 2015-08-28
          相关资源
          最近更新 更多