在FragmentShader中的gl_FragColor上更新u_time不起作用

时间:2019-09-18 17:08:12

标签: reactjs three.js glsl shader

请参阅codepen:https://codepen.io/nvandijk_dev/pen/YzKOXaN

我是Three.js的新手,所以也许有人可以帮助我!

我正在尝试渲染一个将网格添加到包含THREE.PlaneGeometryTHREE.ShaderMaterial的场景的组件。在Component的状态下,我初始化了几个统一的制服,例如u_time,还初始化了着色器,例如片段着色器,它提供了以下方法:

void main() {
    gl_FragColor = vec4(cos(u_time),0., 0. ,1.);
}

除了我做的所有其他事情外,我还有一个animate()函数和一个renderScene()函数。

animate = () => {
    this.delta = this.clock.getDelta();
    this.hasControlsUpdated = this.controls.update(this.delta);
    this.state.uniforms.u_time.value = this.clock.elapsedTime;
    this.renderScene();
    this.frameId = window.requestAnimationFrame(this.animate);
};

renderScene = () => {
    this.renderer.render(this.scene, this.camera);
};

在这里您看到u_time的值一直在更新,console.log也确认了这一点,但是gl_FragColor仅在我的飞机上返回了一个红色着色器,其颜色没有任何改变。

有人可以帮我吗?我的代码中可能遗漏了一些东西,但似乎无法弄清楚!

在下面您会看到我的组件的构造函数

class Scene extends Component {
   constructor(props) {
    super(props);
    this.state = {
      // Shader Uniforms
      uniforms: {
        u_time: {
          type: "f",
          value: 1.0
        },
        u_resolution: {
          type: "v2",
          value: new THREE.Vector2()
        },
        u_mouse: {
          type: "v2",
          value: new THREE.Vector2()
        }
      },

      vertexShader: `
        void main() {
          vec2 vUv = uv;
          gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.);
        }
      `,
      fragmentShader: `
        uniform vec2 u_resolution;
        uniform float u_time;

        void main() {
          gl_FragColor = vec4(cos(u_time),0., 0. ,1.);
        }
      `
    };

1 个答案:

答案 0 :(得分:0)

  

[...]仅在我的飞机上返回一个红色着色器,该着色器的颜色不变[...]

原因是,统一u_time的值完全没有变化。

.elapsedTimeTHREE.Clock属性不会自动更新
该属性会在例如.getElapsedTime().getDelta ()被调用。由于您从不会在代码中调用此函数之一,因此.elapsedTime的值保持为0。
建议不要调用.elapsedTime,而要获取.getElapsedTime()的值。该函数返回自时钟启动以来经过的秒数:

this.state.uniforms.u_time.value = this.clock.getElapsedTime();

当然,以下内容也可以工作:

this.clock.getElapsedTime();
this.state.uniforms.u_time.value = this.clock.elapsedTime;

请注意,由于调用了this.clock.getElapsedTime(),因此属性this.clock.elapsedTime被更新并且可以检索。