javascript - three.js 上的延迟着色。使用 gl_fragData

标签 javascript 3d three.js webgl

用three.js,我想延迟着色,但是效果不好。它不接收 gl_fragData 的值。 你要么知道有人解决方案。

一个

着色器代码

//shader1
<script id="vshader1" type="x-shader/x-vertex">

#extension GL_EXT_draw_buffers : require
varying vec2 vUv;

void main(void){
    vUv = uv;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
</script>

<script id="fshader1" type="x-shader/x-fragment">
uniform sampler2D texture;
varying vec2 vUv;
void main(void) {
    vec4 smpColor = texture2D(texture, vUv);
    gl_FragData[0] = smpColor;
    gl_FragData[1] = smpColor;
}
</script>

//shader2
<script id="vshader2" type="x-shader/x-vertex">
varying vec2 vUv;

void main(void){
    vUv = uv;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
</script>

<script id="fshader2" type="x-shader/x-fragment">
uniform sampler2D texture;
varying vec2 vUv;
void main(void) {
    vec4 smpColor = texture2D(texture, vUv);
    gl_FragColor = smpColor;
}
</script>

主程序。 它是three.js和webgl代码的结合。

    function init(){

        var texture = THREE.ImageUtils.loadTexture('img/test.png');
        var mat1 = new THREE.ShaderMaterial({
            vertexShader: document.getElementById('vshader1').textContent,
            fragmentShader: document.getElementById('fshader1').textContent,

            uniforms: {
                texture: {
                    type: 't', value: texture
                }
            },
            transparent: true,
            needsUpdate:true,
        });



        var geometry = new THREE.PlaneGeometry( 100, 100, 10, 10 );
        plane = new THREE.Mesh( geometry, mat1 );
        plane.rotation.x =  220 * ( Math.PI / 180 );
        scene.add( plane );
    }




    var gl;
    var bufs = [];
    var plane;
    var mat;
    var ext;
    var FBO = [];
    var texture1;
    var texture2;

    function initBuffer(){

        gl = renderer.context;
        ext = gl.getExtension("WEBGL_draw_buffers");

        gl.getExtension("OES_texture_float");
        gl.getExtension("OES_texture_float_linear");

        var maxDrawBuffers = gl.getParameter(ext.MAX_DRAW_BUFFERS_WEBGL);


        FBO[0] = gl.createFramebuffer();
        gl.bindFramebuffer(gl.FRAMEBUFFER, FBO[0]);



         var depthRenderBuffer = gl.createRenderbuffer();
        gl.bindRenderbuffer(gl.RENDERBUFFER, depthRenderBuffer);
        gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 1024, 1024);
        gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthRenderBuffer);



        texture1 = createTexture( gl, 1024, 0 );
        texture2 = createTexture( gl, 1024, 1 );

        ext.drawBuffersWEBGL(bufs);

        gl.framebufferTexture2D(gl.FRAMEBUFFER, bufs[0], gl.TEXTURE_2D, texture1.__webglTexture, 0);
        gl.framebufferTexture2D(gl.FRAMEBUFFER, bufs[1], gl.TEXTURE_2D, texture2.__webglTexture, 0);

        var FBOstatus = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
        if(FBOstatus != gl.FRAMEBUFFER_COMPLETE) {
            console.log("GL_FRAMEBUFFER_COMPLETE failed, CANNOT use FBO[0]\n");         
        }

        gl.bindFramebuffer(gl.FRAMEBUFFER, null);
        gl.bindRenderbuffer(gl.RENDERBUFFER, null);
        gl.bindTexture(gl.TEXTURE_2D, null);




        texture1.needsUpdate = true;
        texture2.needsUpdate = true;
        texture1.image = new Image();
        texture2.image = new Image();
        new THREE.ImageLoader().load(
            'img/color0.png',
            function ( image ) {
                texture1.image = image;
                texture2.image = image;
        });

        mat = new THREE.ShaderMaterial({
            vertexShader: document.getElementById('vshader2').textContent,
            fragmentShader: document.getElementById('fshader2').textContent,

            uniforms: {
                texture: {
                    type: 't', value: texture1
                }
            },
            transparent: true,
            needsUpdate:true,
        });



        var geometry = new THREE.PlaneGeometry( 100, 100, 10, 10 );
        plane = new THREE.Mesh( geometry, mat );
        plane.position.x = 100;
        plane.rotation.x =  220 * ( Math.PI / 180 );
        scene.add( plane );


        setInterval(function(){
            renderBuffer();
        }, 500 );

    }




    function createTexture( gl, size, buf ){
        var texture = new THREE.Texture();
        texture.__webglTexture = gl.createTexture();
        gl.bindTexture(gl.TEXTURE_2D, texture.__webglTexture );
        texture.__webglInit = true;
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
        switch( buf ){
            case 0:
                bufs[0] = ext.COLOR_ATTACHMENT0_WEBGL;
                break;
            case 1:
                bufs[1] = ext.COLOR_ATTACHMENT1_WEBGL;
                break;
            case 2:
                bufs[2] = ext.COLOR_ATTACHMENT2_WEBGL;
                break;
            case 3:
                bufs[3] = ext.COLOR_ATTACHMENT3_WEBGL;
                break;
        }
        gl.bindTexture( gl.TEXTURE_2D, null );
        return texture;
    }





    function renderBuffer(){

        //pass1
        gl.bindFramebuffer(gl.FRAMEBUFFER, FBO[0]);
        gl.viewport(0, 0, size, size);

        renderer.render( scene, camera );

        renderer.setSize(window.innerWidth,window.innerHeight);
        gl.bindFramebuffer(gl.FRAMEBUFFER, null);



        //pass2
        mat.uniforms.texture2.value = texture2;
        plane.material = mat;



        renderer.render( scene, camera );

    }

最佳答案

必须启用 WEBGL_draw_buffers 扩展才能使用执行延迟着色所需的多个渲染目标。否则帧缓冲区只能有一种颜色附件。

关于javascript - three.js 上的延迟着色。使用 gl_fragData,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31769959/

相关文章:

javascript - WooCommerce 图像缩放

javascript - 在 Chrome、Firefox 或 IE 上更改 navigator.platform 以测试操作系统检测代码

algorithm - 运动结构 : Implementing Triangulation

JavaFX 如何获取 3D 场景中对象的坐标

OpenCV-Stereo : How to check the validity of a 3D point (x, y,z)?

three.js - 实例形状内的透明度

javascript - AWS S3 getObject 到图像

JavaScript 单纯形/柏林噪声

Three.js 实例化等效

javascript - 三个js-纹理加载-async/await