three.js正确地混合css3d和webgl [英] three.js properly blending css3d and webgl

查看:240
本文介绍了three.js正确地混合css3d和webgl的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图结合webgl和css3d场景,以便两个场景中的对象正确地混合在一起。我遵循这里

I am trying to combine webgl and css3d scenes so that the objects in the two scenes properly blend together. I am following the pattern described here:

,并通过修改three.js示例css3d_sandbox.html创建了一个简单的示例。

and have created a simple example by modifying the three.js example css3d_sandbox.html.

在我的版本中,我已经添加了一个多维数据集到webGl场景,并期望它适当地与现有飞机混合,无论多维数据集是在这些对象的前面还是后面。

In my version I have added a cube to the webGl scene and expect it to properly blend with the existing planes whether the cube is in front of or behind those objects.

我注意到两个异常。第一个是,一旦添加了多维数据集,飞机在平移时会在意外位置消失,就好像远近平面的值没有被正确赋值,或者对象被错误地确定为在其他事物之后。

I notice two anomalies. The first is that once the cube is added the planes disappear in unexpected positions as you pan around as if the far and near plane values are not being honored correctly or the objects are being incorrectly determined to be behind something else.

第二个问题是,css3d对象在针对three.js r67运行时根本不会渲染,但是当对r61运行时它们会渲染。我尝试用r61替换r37版本的CSS3DRenderer.js,但仍然看不到任何css3d对象。

The second issue is that the css3d objects do not render at all when running against three.js r67, but they do render when running against r61. I tried replacing the r67 version of CSS3DRenderer.js with r61, but still do not see any css3d objects.

在r67中,当将webGl dom添加为子的css3d dom被注释掉了,css3d对象确实出现了。

In r67 when the line to add the webGl dom as a child of the css3d dom is commented out, the css3d objects do appear.

我会感谢任何关于如何解决这些问题的建议。示例代码如下,可以通过放入任何版本的three.js示例文件夹(例如r61或r67)来运行。

I would appreciate any suggestions on how to resolve these issues. Sample code is below and may be run by dropping into any version of the three.js examples folder (e.g. r61 or r67).

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <style>
            body {
                background-color: #ffffff;
                margin: 0;
                overflow: hidden;
            }
            #info {
                position: absolute;
                top: 0px;
                width: 100%;
                color: #000000;
                padding: 5px;
                font-family: Monospace;
                font-size: 13px;
                text-align: center;
                z-index: 1;
            }

            a {
                color: #000000;
            }

        </style>
    </head>
    <body>
        <div id="info"><a href="http://threejs.org" target="_blank">three.js</a> - css3d sandbox</div>

        <script src="../build/three.min.js"></script>

        <script src="js/controls/TrackballControls.js"></script>

        <!--<script src="js/renderers/CSS3DRenderer-r61.js"></script>-->
        <script src="js/renderers/CSS3DRenderer.js"></script>

        <script>

            var camera, sceneGl, rendererGl;

            var sceneCss, rendererCss;

            var controls;

            init();
            animate();

            function init() {

                camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
                camera.position.set( 200, 200, 200 );

                controls = new THREE.TrackballControls( camera );

                sceneGl = new THREE.Scene();
                sceneCss = new THREE.Scene();

                var material = new THREE.MeshBasicMaterial( { color: 0x000000, opacity : 0.0 } );
                material.blending  = THREE.NoBlending;

                //
                var xpos = [50, -10, 30, 70, 110];
                var ypos = [60, -40, 0, 40, 80];
                var zpos = [-30, -50, 0, 50, 100];

                for ( var i = 0; i < 5; i ++ ) {

                    var element = document.createElement( 'div' );
                    element.style.width = '100px';
                    element.style.height = '100px';
                    element.style.opacity = 1.0;
                    element.style.background = new THREE.Color( Math.random() * 0xffffff ).getStyle();

                    var object = new THREE.CSS3DObject( element );
                    object.position.x = xpos[i];
                    object.position.y = ypos[i];
                    object.position.z = zpos[i];
                    object.rotation.x = Math.PI/(i + 5);
                    object.rotation.y = Math.PI/(21 - 2 * i);
                    object.rotation.z = Math.PI/(3 * i + 25);
                    object.scale.x = i/12 + 0.5;
                    object.scale.y =  1/ (12 - i) + 0.5;
                    sceneCss.add( object );


                    var geometry = new THREE.PlaneGeometry( 100, 100 );
                    var mesh = new THREE.Mesh( geometry, material );
                    mesh.position.copy( object.position );
                    mesh.rotation.copy( object.rotation );
                    mesh.scale.copy( object.scale );
                    sceneGl.add( mesh );

                }


                //
                var boxGeom = new THREE.CubeGeometry( 60, 60, 60 );

                var cubeMaterial = new THREE.MeshBasicMaterial( 
                    { color: 0x05009A, shading : THREE.FlatShading, side: THREE.FrontSide } );

                var cube = new THREE.Mesh( boxGeom, cubeMaterial );
                cube.position.copy(  new THREE.Vector3(100, 75, 50) );
                cube.rotation.copy( Math.PI/ 6 );

                sceneGl.add( cube );


                rendererCss = new THREE.CSS3DRenderer();
                rendererCss.setSize( window.innerWidth, window.innerHeight );
                rendererCss.domElement.style.position = 'absolute';
                rendererCss.domElement.style.top = 0;

                rendererGl = new THREE.WebGLRenderer();
                rendererGl.setClearColor( 0xf0f0f0 );

                rendererGl.setSize( window.innerWidth, window.innerHeight );

                rendererGl.domElement.style.position    = 'absolute';
                rendererGl.domElement.style.zIndex = 1;
                rendererGl.domElement.style.top = 0;
                rendererCss.domElement.appendChild( rendererGl.domElement );

                document.body.appendChild( rendererCss.domElement );

            }

            function animate() {

                requestAnimationFrame( animate );

                controls.update();

                rendererGl.render( sceneGl, camera );
                rendererCss.render( sceneCss, camera );

            }

        </script>
    </body>
</html>

这里是

Here is a fiddle with the code.

推荐答案

注释中的链接很有帮助。正如该解决方案提到的,将alpha设置为true解决了使用r67获取css3d对象的问题。使webGl背景透明解决了当平移时css3d对象消失的问题。

The link in the comment was helpful. As that solution mentions, setting alpha to true solves the issue of getting the css3d objects to render using r67. Making the webGl background transparent solves the problem of the css3d objects disappearing when panning around.

链接中提到的解决方案增加了webgl和css3d dom作为子元素文档。这种方法在我的情况下没有工作。我发现有必要仍然有webgl dom作为css3d dom的孩子的立方体正确地混合飞机,当它是在这些对象的前面和后面。

The solution mentioned in the link however adds both the webgl and css3d dom as child elements of the document. This approach did not work in my case. I find it necessary to still have the webgl dom as a child of the css3d dom for the cube to blend correctly with the planes when it is both in front of and behind those objects.

以下工作代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <style>
            body {
                background-color: #ffffff;
                margin: 0;
                overflow: hidden;
            }

        </style>
    </head>
    <body>

        <script src="../build/three.min.js"></script>

        <script src="js/controls/TrackballControls.js"></script>

        <script src="js/renderers/CSS3DRenderer.js"></script>

        <script>

        var camera, sceneGl, rendererGl;
var sceneCss, rendererCss;
var controls;

init();
animate();

function init() {

    camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
    camera.position.set(200, 200, 200);

    controls = new THREE.TrackballControls(camera);

    sceneGl = new THREE.Scene();
    sceneCss = new THREE.Scene();

    var material = new THREE.MeshBasicMaterial({
        color: 0x000000,
        opacity: 0.0,
        side: THREE.DoubleSide
    });

    var xpos = [50, -10, 30, 70, 110];
    var ypos = [60, -40, 0, 40, 80];
    var zpos = [-30, -50, 0, 50, 100];

    for (var i = 0; i < 5; i++) {

        var element = document.createElement('div');
        element.style.width = '100px';
        element.style.height = '100px';
        element.style.opacity = 1.0;
        element.style.background = new THREE.Color(Math.random() * 0xff0000).getStyle();

        var object = new THREE.CSS3DObject(element);
        object.position.x = xpos[i];
        object.position.y = ypos[i];
        object.position.z = zpos[i];
        object.rotation.x = Math.PI / (i + 5);
        object.rotation.y = Math.PI / (21 - 2 * i);
        object.rotation.z = Math.PI / (3 * i + 25);
        object.scale.x = i / 12 + 0.5;
        object.scale.y = 1 / (12 - i) + 0.5;
        sceneCss.add(object);


        var geometry = new THREE.PlaneGeometry(100, 100);
        var mesh = new THREE.Mesh(geometry, material);
        mesh.position.copy(object.position);
        mesh.rotation.copy(object.rotation);
        mesh.scale.copy(object.scale);
        sceneGl.add(mesh);

    }


    var boxGeom = new THREE.CubeGeometry(60, 60, 60);

    var cubeMaterial = new THREE.MeshBasicMaterial({
        color: 0x05009A,
        shading: THREE.FlatShading,
        side: THREE.DoubleSide
    });

    var cube = new THREE.Mesh(boxGeom, cubeMaterial);
    cube.position.copy(new THREE.Vector3(100, 75, 50));
    cube.rotation.copy(Math.PI / 6);

    sceneGl.add(cube);


    rendererCss = new THREE.CSS3DRenderer();
    rendererCss.setSize(window.innerWidth, window.innerHeight);
    rendererCss.domElement.style.position = 'absolute';
    rendererCss.domElement.style.top = 0;

    rendererGl = new THREE.WebGLRenderer({alpha:true});
    rendererGl.setClearColor(0x00ff00, 0.0);

    rendererGl.setSize(window.innerWidth, window.innerHeight);

    rendererGl.domElement.style.position = 'absolute';
    rendererGl.domElement.style.zIndex = 1;
    rendererGl.domElement.style.top = 0;
    rendererCss.domElement.appendChild(rendererGl.domElement);

    document.body.appendChild(rendererCss.domElement);

}

function animate() {

    requestAnimationFrame(animate);

    controls.update();

    rendererGl.render(sceneGl, camera);
    rendererCss.render(sceneCss, camera);

}
        </script>
    </body>
</html>

这篇关于three.js正确地混合css3d和webgl的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆