9
votes

Changer de texture et de couleur sur trois.js objet collada

J'ai récemment reçu trois.js exemple du site officiel travaillant avec mes objets Collada (.Dae) à l'aide du colladaloader.js code>. Maintenant, ma question est, comment puis-je modifier l'attribut de couleur d'objet Collada chargé et ajouter une texture personnalisée ?? J'ai essayé d'ajouter la texture sans chance.

Voici mon code (légèrement changé de l'exemple original): P>

function load_model(el) {

            if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

            var container, stats;

            var camera, scene, renderer, objects;
            var particleLight, pointLight;
            var dae, skin;

            var loader = new THREE.ColladaLoader();
            loader.options.convertUpAxis = true;
            loader.load( '/site_media/models/model.dae', function ( collada ) {
                dae = collada.scene;
                skin = collada.skins[ 0 ];

                dae.scale.x = dae.scale.y = dae.scale.z = 0.90;
                dae.updateMatrix();

                init(el);
                animate();

            } );

            function init(el) {

                container = document.createElement( 'div' );
                el.append( container );

                camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
                camera.position.set( 2, 2, 3 );

                scene = new THREE.Scene();


                scene.add( dae );

                particleLight = new THREE.Mesh( new THREE.SphereGeometry( 4, 8, 8 ), new THREE.MeshBasicMaterial( { color: 0xffffff } ) );
                scene.add( particleLight );

                // Lights

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

                var directionalLight = new THREE.DirectionalLight(/*Math.random() * 0xffffff*/0xeeeeee );
                directionalLight.position.x = Math.random() - 0.5;
                directionalLight.position.y = Math.random() - 0.5;
                directionalLight.position.z = Math.random() - 0.5;
                directionalLight.position.normalize();
                scene.add( directionalLight );

                // pointLight = new THREE.PointLight( 0xffffff, 4 );
                // pointLight.position = particleLight.position;
                // scene.add( pointLight );

                renderer = new THREE.WebGLRenderer();
                renderer.setSize( window.innerWidth/2, window.innerHeight/2 );


                container.appendChild( renderer.domElement );

                stats = new Stats();
                stats.domElement.style.position = 'absolute';
                stats.domElement.style.top = '0px';
                container.appendChild( stats.domElement );

                //

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

            }

            function onWindowResize() {

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

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

            }

            //

            var t = 0;
            var clock = new THREE.Clock();

            function animate() {

                var delta = clock.getDelta();

                requestAnimationFrame( animate );

                if ( t > 1 ) t = 0;

                if ( skin ) {

                    // guess this can be done smarter...

                    // (Indeed, there are way more frames than needed and interpolation is not used at all
                    //  could be something like - one morph per each skinning pose keyframe, or even less,
                    //  animation could be resampled, morphing interpolation handles sparse keyframes quite well.
                    //  Simple animation cycles like this look ok with 10-15 frames instead of 100 ;)

                    for ( var i = 0; i < skin.morphTargetInfluences.length; i++ ) {

                        skin.morphTargetInfluences[ i ] = 0;

                    }

                    skin.morphTargetInfluences[ Math.floor( t * 30 ) ] = 1;

                    t += delta;

                }

                render();
                stats.update();

            }

            function render() {

                var timer = Date.now() * 0.0005;

                camera.position.x = Math.cos( timer ) * 10;
                camera.position.y = 2;
                camera.position.z = Math.sin( timer ) * 10;

                camera.lookAt( scene.position );

                particleLight.position.x = Math.sin( timer * 4 ) * 3009;
                particleLight.position.y = Math.cos( timer * 5 ) * 4000;
                particleLight.position.z = Math.cos( timer * 4 ) * 3009;

                renderer.render( scene, camera );

            }


}


4 Réponses :


1
votes

Une chose que vous pouvez faire est de modifier votre modèle de collada (fichier dae) localiser la référence de texture et le changer à votre goût.


1 commentaires

Un peu besoin d'une solution dynamique



12
votes

Vous pouvez remplacer vos matériaux de scène de collada récursivement avec ce type de fonction. Cela traverse toute la hiérarchie et attribue un matériau. xxx

l'utiliser comme setmaterial (dae, neuf trois.meshbasicmaterial ({couleur: 0xFF0000}));

Vous pouvez probablement adapter que Pour modifier les propriétés du matériau existantes au lieu d'attribuer un nouveau, si nécessaire.


5 commentaires

Vous devez appeler la fonction à l'intérieur de votre rappel Loader.load, de sorte que vous attribuez de nouveaux matériaux après chargement de la collada. En fait, vous pouvez le faire à tout moment après avoir chargé la collada, si vous devez modifier de manière dynamique des matériaux. Et la fonction elle-même peut aller n'importe où.


Oui ça marche pour la couleur. Cela peut-il aussi fonctionner pour la texture? Si oui, comment?


Il existe de nombreux exemples comment créer des matériaux avec une carte de texture. webgl_materials.html dans l'exemple du dossier est un bon point de départ.


Je reçois un "Webgl: invalid_value: teximage2d: image invalide". Je me demande si son objectif mon objet est plutôt complexe et j'espérais que la texture se déplace automatiquement ou si je dois le faire manuellement


J'ai trouvé que je dois ajouter une scène au chargeur. Exemple de code. loader.load (// url de ressource 'test / objet.dae', // fonction lorsque la ressource est chargée fonction (collada) {setmaterial (collada.scene, neuf trois.deshbasicmaterial ({couleur: 0xFF0000})); scène.add (collada.scene);},



2
votes

Après de nombreux problèmes, nous avons écrit un petit hack à colladaloader.js prenant l'idée de @gaitat La sorcière remplace fondamentalement l'ancien chemin des textures des images en transmettant de nouvelles dans un tableau et utilise des expressions régulières pour analyser le XML pour la balise d'images .png ou .jpg sous les images. Je ne sais pas s'il y a un moyen plus facile, mais car le soutien était limité, nous avons dû proposer une solution d'une manière utile xxx


0 commentaires

0
votes
if ( url !== undefined ) {
    var parts = url.split( '/' );
    parts.pop();
    baseUrl = ( parts.length < 1 ? '.' : parts.join( '/' ) ) + '/';

}

parseAsset();
setUpConversion();
images = parseLib( "//dae:library_images/dae:image", _Image, "image" );

for(var i in imageReplace) {
    var iR = imageReplace[i];

    for(var i in images) {
        var image = images[i];

        var patt=new RegExp('[a-zA-Z0-9\-\_]*\/'+iR.name,'g');

        //if(image.id==iR.id)
        if(patt.test(image.init_from))
            image.init_from = iR.new_image; 
    }//for
}

0 commentaires