在three.js中如何在WebGL渲染器和画布渲染器之间切换

时间:2020-02-21 23:34:31

标签: javascript html three.js

我想在three.js(版本69)中使用WebGL渲染器或画布渲染器渲染场景。

这是我的代码:

<!DOCTYPE html>

<html>

<head>
    <script src="./libs/three.js"></script>
    <script src="./libs/CanvasRenderer.js"></script>
    <script src="./libs/Projector.js"></script>

    <script src="./libs/dat.gui.js"></script>
</head>

<body>
    <div id="renderer-output"></div>

    <script type="text/javascript">
        // global variables
        var scene, camera, renderer;

        var gui;

        var config = {
            rendererType: 'WebGL',
            perspectiveCameraFOV: 45,
            perspectiveCameraNear: 0.1,
            perspectiveCameraFar: 1000,
            cameraPosition_x: -30,
            cameraPosition_y: 40,
            cameraPosition_z: 30,
        };

        function init() {
            // create the scene
            scene = new THREE.Scene();

            // create the camera
            camera = new THREE.PerspectiveCamera(
                config.perspectiveCameraFOV,
                window.innerWidth / window.innerHeight,
                config.perspectiveCameraNear,
                config.perspectiveCameraFar
            );
            // set the position
            camera.position.set(
                config.cameraPosition_x,
                config.cameraPosition_y,
                config.cameraPosition_z
            );
            // set the look at
            camera.lookAt(scene.position);

            // create the renderer
            if (config.rendererType == 'WebGL') {
                renderer = new THREE.WebGLRenderer();
            } else if (config.rendererType == 'canvas') {
                renderer = new THREE.CanvasRenderer();
            }
            // set the size
            renderer.setSize(window.innerWidth, window.innerHeight);
            // add the output to the html element
            document.getElementById("renderer-output").appendChild(renderer.domElement);

            var boxGeometry = new THREE.BoxGeometry(4, 4, 4);
            var boxMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });

            var box = new THREE.Mesh(boxGeometry, boxMaterial);

            scene.add(box);

            // create the dat gui
            gui = new dat.GUI({
                preset: config // preset default config
            });

            // remember config
            gui.remember(config);

            // add a renderer folder
            let rendererFolder = gui.addFolder("Renderer");
            rendererFolder.open();

            // set control rendererType
            let rendererTypeController = rendererFolder.add(
                config,
                "rendererType",
                ['WebGL', 'canvas']
            );
            rendererTypeController.onFinishChange(function (rendererType) {
                // remove the renderer output from the html element
                document.getElementById('renderer-output').removeChild(renderer.domElement);
                // create the renderer
                if (rendererType == 'WebGL') {
                    renderer = new THREE.WebGLRenderer();
                } else {
                    renderer = new THREE.CanvasRenderer();
                }
                // set the size
                renderer.setSize(window.innerWidth, innerHeight);
                // add the output to the html element
                document.getElementById('renderer-output').appendChild(renderer.domElement);
            });

            render();
        }

        function render() {
            // update the scene
            requestAnimationFrame(render);
            renderer.render(scene, camera);
        }

        window.onload = init;
    </script>
</body>

</html>

当我想更改渲染器类型时,执行以下几行:

// remove the renderer output from the html element
document.getElementById('renderer-output').removeChild(renderer.domElement);
// create the renderer
if (rendererType == 'WebGL') {
    renderer = new THREE.WebGLRenderer();
} else {
    renderer = new THREE.CanvasRenderer();
}
// set the size
renderer.setSize(window.innerWidth, innerHeight);
// add the output to the html element
document.getElementById('renderer-output').appendChild(renderer.domElement);

但是当我将渲染器从画布更改为WebGL时,我看不到场景中的对象。当我从WebGL转到画布时,可以看到它。

控制台没有任何错误。

您有什么建议吗?

1 个答案:

答案 0 :(得分:0)

我可以找到一个解决方案,创建两个变量来存储两种不同的渲染器类型,并在更改config.rendererTypes的值时调用它们。

<!DOCTYPE html>

<html>

<head>
    <script src="./libs/three.js"></script>
    <script src="./libs/CanvasRenderer.js"></script>
    <script src="./libs/Projector.js"></script>

    <script src="./libs/dat.gui.js"></script>
</head>

<body>
    <div id="renderer-output"></div>

    <script type="text/javascript">
        // global variables
        var camera, scene;
        var rendererWebGL, rendererCanvas;

        var gui;

        var config = {
            rendererType: 'WebGL'
        };

        function init() {
            // create the scene
            scene = new THREE.Scene();

            // create the camera
            camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
            // set the position
            camera.position.set(-30, 40, 30);
            // set the look at
            camera.lookAt(new THREE.Vector3(0, 0, 0));

            // create the renderer
            rendererWebGL = new THREE.WebGLRenderer();
            rendererCanvas = new THREE.WebGLRenderer();
            // set the sizeWebGLRenderer
            rendererWebGL.setSize(window.innerWidth, window.innerHeight);
            rendererCanvas.setSize(window.innerWidth, window.innerHeight);
            // set the color
            // rendererWebGL.setClearColor(0xEEEEEE);
            // rendererCanvas.setClearColor(0xEEEEEE);            
            // add the output to the html element
            if (config.rendererType == 'WebGL') {
                document.getElementById("renderer-output").appendChild(rendererWebGL.domElement);
            } else if (config.rendererType == 'canvas') {
                document.getElementById("renderer-output").appendChild(rendererCanvas.domElement);
            }

            // add a box to the scene
            var boxGeometry = new THREE.BoxGeometry(4, 4, 4);
            var boxMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
            scene.add(new THREE.Mesh(boxGeometry, boxMaterial));

            // create the dat gui
            gui = new dat.GUI({
                preset: config
            });
            // remember config
            gui.remember(config);
            // add a renderer folder
            let rendererFolder = gui.addFolder("Renderer");
            // set folder open
            rendererFolder.open();
            // add a control rendererType
            let rendererTypeController = rendererFolder.add(config, "rendererType", ['WebGL', 'canvas']);
            // set the onFinishCange
            rendererTypeController.onFinishChange(function (rendererType) {
                // remove the renderer's domElement
                var renderer_output = document.getElementById("renderer-output");
                renderer_output.removeChild(renderer_output.children[0]);

                // add the renderer-output
                if (rendererType == 'WebGL') {
                    renderer_output.appendChild(rendererWebGL.domElement);
                } else {
                    renderer_output.appendChild(rendererWebGL.domElement);
                }
            });

            render();
        }

        function render() {
            // update the scene
            if (config.rendererType == 'WebGL') {
                rendererWebGL.render(scene, camera); 
            } else if (config.rendererType == 'canvas') {
                rendererCanvas.render(scene, camera); 
            }

            requestAnimationFrame(render);
        }

        window.onload = init;
    </script>
</body>

</html>
相关问题