【问题标题】:THREE.JS | GLSL Using canvas as shader uniform texture三.JS | GLSL 使用画布作为着色器统一纹理
【发布时间】:2020-12-03 15:17:06
【问题描述】:

我正在尝试使用画布作为统一纹理:

uniforms = {
    
    canvasTexture: { type: "t", value: new THREE.Texture(canvas) }
        
};

也试过了:

uniforms = {
    
    canvasTexture: { type: "t", value: new THREE.CanvasTexture(canvas) }
        
};

但是除了黑屏我什么都看不到。

我也尝试在 animate() 更新制服:

mesh.material.uniforms.canvasTexture.needsUpdate = true;

没有任何成功。有什么建议吗?

 
var renderer, scene, camera, canvas, ctx, mesh, canvasTexture;
    
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
document.body.appendChild( renderer.domElement );
renderer.setSize( window.innerWidth, window.innerHeight );
    
camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );

scene = new THREE.Scene();

var canvas = document.createElement("canvas");
canvas.height = window.innerHeight;
canvas.width = window.innerWidth;
ctx = canvas.getContext("2d");

var geometry = new THREE.PlaneBufferGeometry( 2, 2 );
    
uniforms = {
    
    canvasTexture: { type: "t", value: new THREE.Texture(canvas) }
        
};

var material = new THREE.ShaderMaterial( {

    uniforms: uniforms,
    vertexShader: document.getElementById( "vs-canvasTest" ).textContent,
    fragmentShader: document.getElementById( "fs-canvasTest" ).textContent,

} );

mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
    
window.addEventListener("resize", onWindowResize, false);

animate();
    
function onWindowResize() { 
    
    renderer.setSize( window.innerWidth, window.innerHeight );
    
    canvas.height = window.innerHeight;
    canvas.width = window.innerWidth;
        
}
    
function animate() {
    
    requestAnimationFrame( animate );
    renderer.render( scene, camera );
    
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = "#FF0000";
    ctx.fill();
    
    mesh.material.uniforms.canvasTexture.needsUpdate = true;

}
body { margin: 0; }
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Test</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">

    <script src="https://unpkg.com/three@0.106.0/build/three.min.js"></script>

</head>
<body>
    
<script id="vs-canvasTest" type="x-shader/x-vertex">

    varying vec2 vUv;

    void main() {

        vUv = uv;
        gl_Position = vec4( position, 1.0 );

    }

</script>

<script id="fs-canvasTest" type="x-shader/x-fragment">

    varying vec2 vUv;
    uniform sampler2D canvasTexture;

    void main() {

        gl_FragColor = texture2D(canvasTexture, vUv);

    }


</script>

</body>  
</html>

【问题讨论】:

    标签: canvas three.js glsl textures


    【解决方案1】:

    这是一个小错误,我也经常犯。这是你现在拥有的:

    mesh.material.uniforms.canvasTexture.needsUpdate = true;

    这是你需要的:

    mesh.material.uniforms.canvasTexture.value.needsUpdate = true;

    您只需要在.needsUpdate 之前使用.value,因此您的目标是纹理而不是包含纹理的制服。

    var renderer, scene, camera, canvas, ctx, mesh, tex;
        
    renderer = new THREE.WebGLRenderer();
    renderer.setPixelRatio( window.devicePixelRatio );
    document.body.appendChild( renderer.domElement );
    renderer.setSize( window.innerWidth, window.innerHeight );
        
    camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
    
    scene = new THREE.Scene();
    
    var canvas = document.createElement("canvas");
    canvas.height = window.innerHeight;
    canvas.width = window.innerWidth;
    ctx = canvas.getContext("2d");
    
    var geometry = new THREE.PlaneBufferGeometry( 2, 2 );
    
    uniforms = {
        
        canvasTexture: { value: new THREE.Texture(canvas) }
            
    };
    
    var material = new THREE.ShaderMaterial( {
    
        uniforms: uniforms,
        vertexShader: document.getElementById( "vs-canvasTest" ).textContent,
        fragmentShader: document.getElementById( "fs-canvasTest" ).textContent,
    
    } );
    
    mesh = new THREE.Mesh( geometry, material );
    scene.add( mesh );
        
    window.addEventListener("resize", onWindowResize, false);
    
    animate();
        
    function onWindowResize() { 
        
        renderer.setSize( window.innerWidth, window.innerHeight );
        
        canvas.height = window.innerHeight;
        canvas.width = window.innerWidth;
            
    }
        
    function animate() {
        
        requestAnimationFrame( animate );
        renderer.render( scene, camera );
        
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.fillStyle = "#FF0000";
        ctx.fill();
        
        mesh.material.uniforms.canvasTexture.value.needsUpdate = true;
    
    }
    body { margin: 0; }
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <title>Test</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    
        <script src="https://unpkg.com/three@0.106.0/build/three.min.js"></script>
    
    </head>
    <body>
        
    <script id="vs-canvasTest" type="x-shader/x-vertex">
    
        varying vec2 vUv;
    
        void main() {
    
            vUv = uv;
            gl_Position = vec4( position, 1.0 );
    
        }
    
    </script>
    
    <script id="fs-canvasTest" type="x-shader/x-fragment">
    
        varying vec2 vUv;
        uniform sampler2D canvasTexture;
    
        void main() {
    
            gl_FragColor = texture2D(canvasTexture, vUv);
    
        }
    
    
    </script>
    
    </body>  
    </html>

    【讨论】:

    • 愚蠢的错误。干杯。
    猜你喜欢
    • 2017-03-28
    • 2019-03-09
    • 2010-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多