Threejs:WebGL 3D文本到three.js海洋场景

时间:2016-09-02 21:38:10

标签: javascript canvas 3d three.js

我正在使用three.js ocean scene 3D canvas text。 3D文本假设替换球的位置,但文本不会出现。  当我检查元素时,我只注意到背景渲染的画布。两幅画布 - 背景和3D文字 - 如何出现?如何在另一个画布上叠加画布? 在不使用画布或canvasrenderer.js用于3D文本的情况下,在水上创建3D文本的另一种方法是什么?

Canvas 3D Text的原始代码:https://github.com/mrdoob/three.js/blob/master/examples/canvas_geometry_text.html

JavaScript组合两个元素:

var container, stats;
        var camera, scene, renderer;

        var parameters = {
            width: 2000,
            height: 2000,
            widthSegments: 250,
            heightSegments: 250,
            depth: 1500,
            param: 4,
            filterparam: 1
        };
        var waterNormals;
        var group;

        var targetRotation = 0;
        var targetRotationOnMouseDown = 0;

        var loader = new THREE.FontLoader();
        loader.load( 'fonts/helvetiker_regular.typeface.json', function ( font ) {

        } );
        init();
        animate();
        function init( font ) {

            container = document.createElement( 'div' );
            document.body.appendChild( container );



            camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
            camera.position.set( 0, 150, 500 );

            scene = new THREE.Scene();

            // Get text from hash

            var theText = "three.js";

            var hash = document.location.hash.substr( 1 );

            if ( hash.length !== 0 ) {

                theText = hash;

            }

            var geometry0 = new THREE.TextGeometry( theText, {

                font: font,
                size: 80,
                height: 20,
                curveSegments: 2

            });

            geometry.computeBoundingBox();

            var centerOffset = -0.5 * ( geometry.boundingBox.max.x - geometry.boundingBox.min.x );

            var material0 = new THREE.MultiMaterial( [
                new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, overdraw: 0.5 } ),
                new THREE.MeshBasicMaterial( { color: 0x000000, overdraw: 0.5 } )
            ] );

            var mesh = new THREE.Mesh( geometry0, material0 );

            mesh.position.x = centerOffset;
            mesh.position.y = 100;
            mesh.position.z = 50;



            group = new THREE.Group();
            group.add( mesh );

            scene.add( group );

            renderer = new THREE.CanvasRenderer();
            renderer.setClearColor( 0xf0f0f0 );
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize( window.innerWidth, window.innerHeight );
            container.appendChild( renderer.domElement );

            stats = new Stats();
            container.appendChild( stats.dom );

            //

            window.addEventListener( 'resize', onWindowResize, false );

        }
        function onWindowResize() {

            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();

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

        }
        function init() {
            container = document.createElement( 'div' );
            document.body.appendChild( container );
            renderer = new THREE.WebGLRenderer();
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize( window.innerWidth, window.innerHeight );
            container.appendChild( renderer.domElement );
            scene = new THREE.Scene();
            camera = new THREE.PerspectiveCamera( 55, window.innerWidth / window.innerHeight, 0.5, 3000000 );
            camera.position.set( 2000, 750, 2000 );
            controls = new THREE.OrbitControls( camera, renderer.domElement );
            controls.enablePan = false;
            controls.minDistance = 1000.0;
            controls.maxDistance = 5000.0;
            controls.maxPolarAngle = Math.PI * 0.495;
            controls.target.set( 0, 500, 0 );
            scene.add( new THREE.AmbientLight( 0x444444 ) );
            var light = new THREE.DirectionalLight( 0xffffbb, 1 );
            light.position.set( - 1, 1, - 1 );
            scene.add( light );
            waterNormals = new THREE.TextureLoader().load( 'textures/waternormals.jpg' );
            waterNormals.wrapS = waterNormals.wrapT = THREE.RepeatWrapping;
            water = new THREE.Water( renderer, camera, scene, {
                textureWidth: 512,
                textureHeight: 512,
                waterNormals: waterNormals,
                alpha:  1.0,
                sunDirection: light.position.clone().normalize(),
                sunColor: 0xffffff,
                waterColor: 0x001e0f,
                distortionScale: 50.0,
            } );
            mirrorMesh = new THREE.Mesh(
                new THREE.PlaneBufferGeometry( parameters.width * 500, parameters.height * 500 ),
                water.material
            );
            mirrorMesh.add( water );
            mirrorMesh.rotation.x = - Math.PI * 0.5;
            scene.add( mirrorMesh );
            // load skybox
            var cubeMap = new THREE.CubeTexture( [] );
            cubeMap.format = THREE.RGBFormat;
            var loader = new THREE.ImageLoader();
            loader.load( 'textures/skyboxsun25degtest.png', function ( image ) {
                var getSide = function ( x, y ) {
                    var size = 1024;
                    var canvas = document.createElement( 'canvas' );
                    canvas.width = size;
                    canvas.height = size;
                    var context = canvas.getContext( '2d' );
                    context.drawImage( image, - x * size, - y * size );
                    return canvas;
                };
                cubeMap.images[ 0 ] = getSide( 2, 1 ); // px
                cubeMap.images[ 1 ] = getSide( 0, 1 ); // nx
                cubeMap.images[ 2 ] = getSide( 1, 0 ); // py
                cubeMap.images[ 3 ] = getSide( 1, 2 ); // ny
                cubeMap.images[ 4 ] = getSide( 1, 1 ); // pz
                cubeMap.images[ 5 ] = getSide( 3, 1 ); // nz
                cubeMap.needsUpdate = true;
            } );
            var cubeShader = THREE.ShaderLib[ 'cube' ];
            cubeShader.uniforms[ 'tCube' ].value = cubeMap;
            var skyBoxMaterial = new THREE.ShaderMaterial( {
                fragmentShader: cubeShader.fragmentShader,
                vertexShader: cubeShader.vertexShader,
                uniforms: cubeShader.uniforms,
                depthWrite: false,
                side: THREE.BackSide
            } );
            var skyBox = new THREE.Mesh(
                new THREE.BoxGeometry( 1000000, 1000000, 1000000 ),
                skyBoxMaterial
            );
            scene.add( skyBox );
            var geometry = new THREE.IcosahedronGeometry( 400, 4 );
            for ( var i = 0, j = geometry.faces.length; i < j; i ++ ) {
                geometry.faces[ i ].color.setHex( Math.random() * 0xffffff );
            }
            var material = new THREE.MeshPhongMaterial( {
                vertexColors: THREE.FaceColors,
                shininess: 100,
                envMap: cubeMap
            } );

        }
        //
        function animate() {
            requestAnimationFrame( animate );
            render();
        }
        function render() {


            water.material.uniforms.time.value += 1.0 / 60.0;
            controls.update();
            water.render();
            renderer.render( scene, camera );
        }

1 个答案:

答案 0 :(得分:1)

我注意到的第一件事是你正在调用init();动画();在加载器有机会加载字体之前的函数(因为你没有将字体传递给init函数,如canvas_geometry_text示例)。

我已经粘贴了下面的海洋示例中的代码(注释我如何修改它以使用canvas_geometry_text示例中的代码)。我已经对此进行了测试,并且可以正常运行

        var container, stats;
        var camera, scene, renderer;
        var sphere;

        var parameters = {
            width: 2000,
            height: 2000,
            widthSegments: 250,
            heightSegments: 250,
            depth: 1500,
            param: 4,
            filterparam: 1
        };

        var waterNormals;

        // 1. 
        // copy+paste this code from the canvas_geometry_text file
        var loader = new THREE.FontLoader();
        loader.load( 'fonts/helvetiker_regular.typeface.json', function ( font ) {

            init( font );
            animate();

        } );

        // 2. 
        // comment out these calls to init() and animate() 
        // these will be called in the loader's callback above instead
        // init();
        // animate();

        // add 'font' parameter to init
        function init( font ) {

            container = document.createElement( 'div' );
            document.body.appendChild( container );

            renderer = new THREE.WebGLRenderer();
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize( window.innerWidth, window.innerHeight );
            container.appendChild( renderer.domElement );

            scene = new THREE.Scene();

            camera = new THREE.PerspectiveCamera( 55, window.innerWidth / window.innerHeight, 0.5, 3000000 );
            camera.position.set( 2000, 750, 2000 );

            controls = new THREE.OrbitControls( camera, renderer.domElement );
            controls.enablePan = false;
            controls.minDistance = 1000.0;
            controls.maxDistance = 5000.0;
            controls.maxPolarAngle = Math.PI * 0.495;
            controls.target.set( 0, 500, 0 );

            scene.add( new THREE.AmbientLight( 0x444444 ) );

            var light = new THREE.DirectionalLight( 0xffffbb, 1 );
            light.position.set( - 1, 1, - 1 );
            scene.add( light );


            waterNormals = new THREE.TextureLoader().load( 'textures/waternormals.jpg' );
            waterNormals.wrapS = waterNormals.wrapT = THREE.RepeatWrapping;

            water = new THREE.Water( renderer, camera, scene, {
                textureWidth: 512,
                textureHeight: 512,
                waterNormals: waterNormals,
                alpha:  1.0,
                sunDirection: light.position.clone().normalize(),
                sunColor: 0xffffff,
                waterColor: 0x001e0f,
                distortionScale: 50.0,
            } );


            mirrorMesh = new THREE.Mesh(
                new THREE.PlaneBufferGeometry( parameters.width * 500, parameters.height * 500 ),
                water.material
            );

            mirrorMesh.add( water );
            mirrorMesh.rotation.x = - Math.PI * 0.5;
            scene.add( mirrorMesh );


            // load skybox

            var cubeMap = new THREE.CubeTexture( [] );
            cubeMap.format = THREE.RGBFormat;

            var loader = new THREE.ImageLoader();
            loader.load( 'textures/skyboxsun25degtest.png', function ( image ) {

                var getSide = function ( x, y ) {

                    var size = 1024;

                    var canvas = document.createElement( 'canvas' );
                    canvas.width = size;
                    canvas.height = size;

                    var context = canvas.getContext( '2d' );
                    context.drawImage( image, - x * size, - y * size );

                    return canvas;

                };

                cubeMap.images[ 0 ] = getSide( 2, 1 ); // px
                cubeMap.images[ 1 ] = getSide( 0, 1 ); // nx
                cubeMap.images[ 2 ] = getSide( 1, 0 ); // py
                cubeMap.images[ 3 ] = getSide( 1, 2 ); // ny
                cubeMap.images[ 4 ] = getSide( 1, 1 ); // pz
                cubeMap.images[ 5 ] = getSide( 3, 1 ); // nz
                cubeMap.needsUpdate = true;

            } );

            var cubeShader = THREE.ShaderLib[ 'cube' ];
            cubeShader.uniforms[ 'tCube' ].value = cubeMap;

            var skyBoxMaterial = new THREE.ShaderMaterial( {
                fragmentShader: cubeShader.fragmentShader,
                vertexShader: cubeShader.vertexShader,
                uniforms: cubeShader.uniforms,
                depthWrite: false,
                side: THREE.BackSide
            } );

            var skyBox = new THREE.Mesh(
                new THREE.BoxGeometry( 1000000, 1000000, 1000000 ),
                skyBoxMaterial
            );

            scene.add( skyBox );

            // 3.
            // comment out all the sphere mesh code

            // var geometry = new THREE.IcosahedronGeometry( 400, 4 );

            // for ( var i = 0, j = geometry.faces.length; i < j; i ++ ) {

            //  geometry.faces[ i ].color.setHex( Math.random() * 0xffffff );

            // }

            // var material = new THREE.MeshPhongMaterial( {
            //  vertexColors: THREE.FaceColors,
            //  shininess: 100,
            //  envMap: cubeMap
            // } );

            // sphere = new THREE.Mesh( geometry, material );
            // scene.add( sphere );

            // 4.
            // copy+paste the text mesh code from canvas_geometry_text

            var theText = "Hello three.js! :)";

            var hash = document.location.hash.substr( 1 );

            if ( hash.length !== 0 ) {

                theText = hash;

            }

            var geometry = new THREE.TextGeometry( theText, {

                font: font,
                size: 80,
                height: 20,
                curveSegments: 2

            });

            geometry.computeBoundingBox();

            var centerOffset = -0.5 * ( geometry.boundingBox.max.x - geometry.boundingBox.min.x );

            var material = new THREE.MultiMaterial( [
                new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, overdraw: 0.5 } ),
                new THREE.MeshBasicMaterial( { color: 0x000000, overdraw: 0.5 } )
            ] );

            var mesh = new THREE.Mesh( geometry, material );

            mesh.position.x = centerOffset;
            mesh.position.y = 100;
            mesh.position.z = 0;

            mesh.rotation.x = 0;
            mesh.rotation.y = Math.PI * 2;

            group = new THREE.Group();
            group.add( mesh );

            scene.add( group );
        }

        //

        function animate() {

            requestAnimationFrame( animate );
            render();

        }

        function render() {

            var time = performance.now() * 0.001;

            // 6.
            // comment out the sphere animation code

            // sphere.position.y = Math.sin( time ) * 500 + 250;
            // sphere.rotation.x = time * 0.5;
            // sphere.rotation.z = time * 0.51;

            // 7.
            // copy+paste the sphere animation code above
            // but replace 'sphere' with 'group'

            group.position.y = Math.sin( time ) * 500 + 250;
            group.rotation.x = time * 0.5;
            group.rotation.z = time * 0.51;

            water.material.uniforms.time.value += 1.0 / 60.0;
            controls.update();
            water.render();
            renderer.render( scene, camera );

        }