【问题标题】:Three.js and HTML5 Canvas toDataURLThree.js 和 HTML5 Canvas toDataURL
【发布时间】:2013-09-19 15:29:07
【问题描述】:

我正在尝试使用 Three.js 库将 WebGL 图像渲染到画布,然后在渲染后在该画布上使用 toDataURL() 方法。 当我检查来自 toDataURL 的字符串时,我得到的只是一个小球体,它是我场景中的光源,渲染的 3D 模型不会出现。 代码主要取自 Three.js 网站上的一个示例。 有没有办法在整个渲染实际完成后使用 toDataURL?

    <script type="text/javascript">
            var canvas = document.getElementById("drawing");
            var hash;

            var SCREEN_WIDTH = canvas.width;
            var SCREEN_HEIGHT = canvas.height;

            var container, stats;

            var camera, scene, canvasRenderer, webglRenderer;

            var loader;

            var mesh, zmesh, lightMesh;

            var directionalLight, pointLight;

            var render_canvas = 1, render_gl = 1;
            var has_gl = 0;

            render_canvas = !has_gl;

            function addMesh(geometry, scale, x, y, z, rx, ry, rz, material) {
                    mesh = new THREE.Mesh(geometry, material);

                    mesh.scale.set(scale, scale, scale);
                    mesh.position.set(x, y, z);
                    mesh.rotation.set(rx, ry, rz);

                    scene.add(mesh);
            }

            function init() {
                    camera = new THREE.PerspectiveCamera(50, SCREEN_WIDTH
                                    / SCREEN_HEIGHT, 1, 100000);
                    camera.position.z = 1500;

                    scene = new THREE.Scene();

                    // LIGHTS

                    var ambient = new THREE.AmbientLight(0x101010);
                    scene.add(ambient);

                    directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
                    directionalLight.position.set(1, 1, 2).normalize();
                    scene.add(directionalLight);

                    pointLight = new THREE.PointLight(0xffaa00);
                    pointLight.position.set(0, 0, 0);
                    scene.add(pointLight);

                    // light representation

                    sphere = new THREE.SphereGeometry(100, 16, 8, 1);
                    lightMesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({
                            color : 0xffaa00
                    }));
                    lightMesh.scale.set(0.05, 0.05, 0.05);
                    lightMesh.position = pointLight.position;
                    scene.add(lightMesh);

                    if (render_gl) {
                            try {
                                    webglRenderer = new THREE.WebGLRenderer({
                                            canvas : canvas,
                                            antialias : true,
                                            alpha : true
                                    });
                                    webglRenderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
                                    has_gl = 1;

                            } catch (e) {
                                    alert("browser Doesn't support webGL");
                                    return;
                            }
                    }

                    loader = new THREE.BinaryLoader(true);

                    loader.load('/static/lucy/Lucy100k_bin.js', function(geometry,
                                    materials) {

                            addMesh(geometry, 0.75, 900, 0, 0, 0, 0, 0,
                                            new THREE.MeshPhongMaterial({
                                                    ambient : 0x030303,
                                                    color : 0x030303,
                                                    specular : 0x990000,
                                                    shininess : 30
                                            }));
                            addMesh(geometry, 0.75, 300, 0, 0, 0, 0, 0,
                                            new THREE.MeshFaceMaterial(materials));
                            addMesh(geometry, 0.75, -300, 0, 0, 0, 0, 0,
                                            new THREE.MeshPhongMaterial({
                                                    ambient : 0x030303,
                                                    color : 0x111111,
                                                    specular : 0xffaa00,
                                                    shininess : 10
                                            }));
                            addMesh(geometry, 0.75, -900, 0, 0, 0, 0, 0,
                                            new THREE.MeshPhongMaterial({
                                                    ambient : 0x030303,
                                                    color : 0x555555,
                                                    specular : 0x666666,
                                                    shininess : 10
                                            }));

                    });

            }

            function animate() {
                    requestAnimationFrame(animate);
                    webglRenderer.render(scene, camera);
            }

            init();
            animate();

            var dataurl = canvas.toDataURL();
    </script>

【问题讨论】:

    标签: canvas three.js webgl


    【解决方案1】:

    嗯,我认为将 toDataURL() 放在 renderer.render(scene,cam); 之后工作正常,但是您可以在渲染器参数中设置 preserverDrawingBuffer: true 并且它可以完美地工作,尽管 preserverDrawingBuffer 不能对资源或性能产生负面影响。 见这里:http://learningthreejs.com/blog/2011/09/03/screenshot-in-javascript/

    【讨论】:

    • 仍然不工作:/...我只是得到球体,没有别的
    • 我的回答是正确的。只是您的网格一开始就没有加载。否则,使用 dataURL 的正确答案只是设置 preserverDrawingbuffer 或在渲染发生后和新帧开始之前直接放置。这可以通过一个简单的按钮来完成,但当然不是像您的示例中那样“开始”;)
    【解决方案2】:

    好的,我明白了。我需要添加“preserveDrawingBuffer : true”,将我的截图代码放在加载器回调函数的末尾。

    【讨论】:

    • 是的,网格是异步加载的,并在加载完成后弹出到视图中,因此您的前几帧不会出现网格。将屏幕截图代码移动到加载器回调的末尾将等到不再有问题为止(尽管您可能希望先再渲染一次场景,否则您可能会在加载的网格绘制之前拍摄)。
    【解决方案3】:

    使用 preserveDrawingBuffer 选项创建 WebGL 上下文。

    var gl = canvas.getContext("experimental-webgl", {preserveDrawingBuffer: true});
    var pixelData = new Uint8Array(width * height * 4);
    gl.readPixels(left, top, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixelData);
    console.log(pixelData);
    

    this question

    【讨论】:

      猜你喜欢
      • 2014-11-26
      • 1970-01-01
      • 2015-09-20
      • 1970-01-01
      • 2012-08-13
      • 2015-09-25
      • 2015-11-16
      • 1970-01-01
      相关资源
      最近更新 更多