在保留单独材质颜色的同时合并Three.js中的文本几何

时间:2017-02-06 06:09:32

标签: javascript three.js

我正在尝试合并Three.js中的文本几何(r84)。我需要使用multiMaterial并为每个文本对象保留单独的颜色。这是一个现场演示。 https://jsfiddle.net/5oydk6nL/

感谢。

var $win = $( window ) ,
    $container = $( '#webGL-container' ) ,

    scene , camera , cameraTarget , renderer ,
    pointLight , hex ,
    stats , rendererStats ,

    typeface = 'https://cdn.rawgit.com/redwavedesign/ca97268140e8a51633595cd34bb77f16/raw/46ae61687ac8e7e3af01ee2c983580f2b0b0809f/bebas_regular.json';



/* text objects */

var a = {
    text: 'a' ,
    color: 'red' ,
    x: -90
}

var b = {
    text: 'b' ,
    color: 'blue' ,
    x: -60
}

var c = {
    text: 'c' ,
    color: 'green' ,
    x: -30
}

var d = {
    text: 'd' ,
    color: 'yellow' ,
    x: 0
}

var e = {
    text: 'e' ,
    color: 'purple' ,
    x: 30
}

var f = {
    text: 'f' ,
    color: 'orange' ,
    x: 60
}

var g = {
    text: 'g' ,
    color: 'aqua' ,
    x: 90
}




// array with all text objects
var letters = [ a , b , c , d , e , f , g ];




function decimalToHex( d ) {

    var hex = Number( d ).toString( 16 );
    hex = "000000".substr( 0, 6 - hex.length ) + hex;
    return hex.toUpperCase();

}




function init() {


    /* create scene, camera and renderer */
    scene = new THREE.Scene();
    camera =  new THREE.PerspectiveCamera( 40 , window.innerWidth / window.innerHeight , .1 , 1500 );
    renderer = new THREE.WebGLRenderer({ antialias: true });

    /* setup renderer */
    renderer.setClearColor( '#ffffff' );
    renderer.setSize( window.innerWidth , window.innerHeight );
    renderer.shadowMap.enabled = true;
    renderer.shadowMapSoft = true;

    /* setup camera */
    camera.position.x = 0;
    camera.position.y = 0;
    camera.position.z = 500;

    cameraTarget = new THREE.Vector3( 0 , 0 , 0 );

    /* Lights */
    pointLight = new THREE.PointLight( 0xffffff, 2 );
    pointLight.position.set( 20 , -300 , 200 );
    scene.add( pointLight );

    pointLight.color.setStyle( '#EBEBEB' );
    hex = decimalToHex( pointLight.color.getHex() );


    // load each text object from the 'letters' array
    $.each( letters , function( index , letter ) {


        var fontLoader = new THREE.FontLoader();


        // load font
        fontLoader.load( typeface , function ( font ) {


            var geometry = new THREE.TextGeometry( letter.text , {

                    font: font,
                    height: 8 ,
                    size: 28 ,
                    curveSegments: 4 ,
                    bevelThickness: 1,
                    bevelSize: 1.5 ,
                    bevelSegments: 3 ,
                    bevelEnabled: true ,
                    material: 0,
                    extrudeMaterial: 1

            });


            var material = new THREE.MultiMaterial( [
                new THREE.MeshPhongMaterial( { color: letter.color , shading: THREE.FlatShading } ), // front
                new THREE.MeshPhongMaterial( { color: letter.color , shading: THREE.SmoothShading } ) // side
            ] );


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


            mesh.position.set( letter.x , 0 , 0 );


            // add text object to scene
            scene.add( mesh );


        });


    // end of each loop
    });


    // add the rendered element to the page
    $container.append( renderer.domElement );


}




function render() {

    camera.lookAt( cameraTarget );

    renderer.clear();

    renderer.render( scene , camera );

}



function animate() {

    // begin Three.js stats utility
    stats.begin();

    requestAnimationFrame( animate );

    render();

    // update Threex stats plugin
    rendererStats.update( renderer );

    // conclude sample for Three.js stats testing
    stats.end();

}



// performance monitoring

rendererStats = new THREEx.RendererStats();
rendererStats.domElement.style.position = 'absolute'
rendererStats.domElement.style.left = '0px'
rendererStats.domElement.style.bottom = '0px'
document.body.appendChild( rendererStats.domElement );

stats = new Stats();
    stats.showPanel( 0 );
    document.body.appendChild( stats.domElement );
    document.body.appendChild( stats.dom );



// initialize 
init();

// animate
animate();

1 个答案:

答案 0 :(得分:0)

Here an updated fiddle

需要添加一些内容:

1)创建一个多材料并为每个字母添加材料:

var material = new THREE.MeshPhongMaterial({
    color: letter.color,
    shading: THREE.FlatShading
});

multiMaterial.materials.push(material);

2)将材质索引添加到每个字母的所有面上:

for (var i = 0, il = geometry.faces.length; i < il; i++) {
    geometry.faces[i].materialIndex = index
}

3)使用转换矩阵将几何x转换为右侧:

geometry.applyMatrix(
    matrix.makeTranslation(letter.x, 0, 0)
);

4)将每个字母几何体合并为一个几何体:

mergedGeometry.merge(geometry);

现在你有一个合并的几何体:

enter image description here

注意:下次尝试防止在你的小提琴中使用jQuery,这个额外的库对你的例子来说不是必需的。另请阅读here in these guidelines for more information