重用 WebGLRenderTarget 作为材质,它会归零并变黑

问题描述 投票:0回答:1

我是着色器新手。我目前正在将 Three.js 与 ShaderMaterial 一起使用。我想问以下问题。 我的问题是我使用 FBO 创建材质并将材质作为制服传输到片段着色器。本来一切正常,可以得到随机分布的颜色材料。 但是当我使用 this.fbo.texture 作为我自己的制服参数值时,材质将变得完全黑色。 程序代码如下

    setupFBO(){
        this.size = 128;
        this.fbo = this.getRenderTarget();

        this.fboScene = new THREE.Scene();
        this.fboCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, -1, 1);
        this.fboCamera.position.set(0, 0, 0.5);

        let geometry = new THREE.PlaneGeometry(2, 2);

 
        this.data = new Float32Array(this.size * this.size * 4);


        for(let i = 0; i < this.size; i++){
            for(let j = 0; j < this.size; j++){

                let index = (i + j * this.size) * 4;
                let theta = Math.random() * Math.PI * 2; 
                let r = 0.5 + 0.5 * Math.random(); 


                this.data[index + 0] = r * Math.cos(theta);
                this.data[index + 1] = r * Math.sin(theta);
                this.data[index + 2] = 1.0;
                this.data[index + 3] = 1.0;
            }
        }

        this.fboTexture = new THREE.DataTexture(this.data, this.size, this.size, THREE.RGBAFormat, THREE.FloatType);
        this.fboTexture.magFilter = THREE.NearestFilter;
        this.fboTexture.minFilter = THREE.NearestFilter;
        this.fboTexture.needsUpdate = true;


        this.fboMaterial = new THREE.ShaderMaterial({
            uniforms: {
                uPositions: {value: this.fboTexture},
                time: {value: 0}
            },
            vertexShader: simVertex,
            fragmentShader: simFragment
        })
       
        let FBOmesh = new THREE.Mesh(geometry, this.fboMaterial);
        
       

        this.fboScene.add(FBOmesh);
        this.renderer.setRenderTarget(null);
        this.renderer.setRenderTarget(this.fbo);
        this.renderer.render(this.fboScene, this.fboCamera);
        this.renderer.setRenderTarget(null);
        
      ////here is the problem
      //this.fboMaterial.uniforms.uPositions.value = this.fbo.texture;  //here is the problem

      //this.renderer.setRenderTarget(null);
      //this.renderer.setRenderTarget(this.fbo);
      //this.renderer.render(this.fboScene, this.fboCamera);

      //this.renderer.setRenderTarget(null);
      //this.renderer.render(this.fboScene, this.fboCamera);




    }



    getRenderTarget(){
        const renderTarget = new THREE.WebGLRenderTarget(this.canvas.width, this.canvas.height, {
            minFilter: THREE.NearestFilter,
            magFilter: THREE.NearestFilter,  
            format: THREE.RGBAFormat,
            type: THREE.FloatType,
            stencilBuffer: false
        });
        return renderTarget;
    }
//simVertex.glsl
uniform float time;
varying vec2 vUv;
varying vec3 vPosition;
float PI = 3.141592653589793238;


void main(){
    vUv = uv;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
//simFragment.glsl
uniform float time;
uniform float progress;
uniform sampler2D uPositions;  
varying vec2 vUv;
varying vec3 vPosition;


void main(){
    vec4 pos = texture2D(uPositions, vUv);
    gl_FragColor = vec4(pos.xyz, 1);
}

如果我将位置更改为渲染后,它工作正常,但我的意思是它不应该是相同的结果吗? 毕竟,结果首先存储在 this.fbo 中,然后我再次 setRenderTarget。 为什么结果全黑?

this.fboMaterial.uniforms.uPositions.value = this.fbo.texture;

this.renderer.setRenderTarget(null);
this.renderer.setRenderTarget(this.fbo);
this.renderer.render(this.fboScene, this.fboCamera);

this.renderer.setRenderTarget(null);
this.renderer.render(this.fboScene, this.fboCamera);

但是当我使用新的fbo1作为载体时,它不会受到影响,所以我认为是因为render改变了它的值

three.js fragment-shader
1个回答
0
投票

感谢另一个社区的 Mugen 的帮助。造成这个问题的原因是一个称为反馈循环的问题。 解决方案是使用乒乓球。

© www.soinside.com 2019 - 2024. All rights reserved.