【问题标题】:Changing Color of Threejs Cars Example on Runtime在运行时更改 Threejs 汽车的颜色示例
【发布时间】:2019-04-07 04:49:27
【问题描述】:

我最近开始在以下 URL 中使用 Threejs 汽车示例: https://threejs.org/examples/webgl_loader_ctm_materials.html

用于测试真实物体的绝妙作品。我想在运行时更改这辆车的材质,但由于网格被添加到场景中的方式,我被阻止了。我会很感激有人可以保释我并发布小提琴或分享代码。

以下是将网格添加到场景中的方式:

var loader = new THREE.CTMLoader();
                loader.loadParts( "catalog/view/javascript/models/ctm/camaro/camaro.js", function( geometries, materials ) {
                    hackMaterials( materials );
                    for ( var i = 0; i < geometries.length; i ++ ) {
                        var mesh = new THREE.Mesh( geometries[ i ], materials[ i ] );
                        mesh.position.copy( position );
                        mesh.scale.copy( scale );
                        scene.add( mesh );
                    }

这里是 hackMaterials(materials) 函数。

function hackMaterials( materials ) {
                for ( var i = 0; i < materials.length; i ++ ) {
                    var m = materials[ i ];
                    if ( m.name.indexOf( "Body" ) !== -1 ) {
                        var mm = new THREE.MeshStandardMaterial( );

                       mm.color.setHex( 0x56cc5b );   //
                        mm.lightMap = m.map;
                        //mm.envMap = textureCube;
                        mm.metalness = 0.5;
                        mm.roughness = 0.3;
                        materials[ i ] = mm;
                    } 
                    else if ( m.name.indexOf( "tire_car" ) !== -1 ) {
                        var mm = new THREE.MeshStandardMaterial();
                        mm.color.setHex( 0x000000 );
                        mm.lightMap = m.map;
                        mm.metalness = 0.1;
                        mm.roughness = 0.9;
                        materials[ i ] = mm;
                    }
                     else if ( m.name.indexOf( "mirror" ) !== -1 ) {
                        var mm = new THREE.MeshStandardMaterial();
                        mm.color.setHex( 0x808080 );
                        mm.lightMap = m.map;
                        mm.envMap = textureCube;
                        mm.metalness = 0.9;
                        mm.roughness = 0.5;
                        materials[ i ] = mm;
                    } 
                    else if ( m.name.indexOf( "glass" ) !== -1 ) {
                        var mm = new THREE.MeshStandardMaterial();
                        mm.color.copy( m.color );
//                      mm.lightMap = m.map;
                        mm.envMap = textureCube;
                        mm.metalness = 1;
                        mm.roughtness = 0.1;
                        mm.opacity = m.opacity;
                        mm.transparent = true;
                        materials[ i ] = mm;
                    } 
                    else if ( m.name.indexOf( "Material.001" ) !== -1 ) {
                        var mm = new THREE.MeshPhongMaterial( { map: m.map } );
                        mm.specularMap = m.map;
                        mm.shininess = 30;
                        mm.color.setHex( 0xffffff );
                        mm.metal = true;
                        materials[ i ] = mm;
                   }
                    materials[ i ].side = THREE.DoubleSide;
                }
            }

不用指出,函数 hackMaterials 循环遍历数组中的材质名称,然后根据名称为材质分配不同的值。

我一直在尝试使用 dat.gui.js,但到目前为止我唯一能做的就是通过此代码创建颜色控件并通过以下代码生成控制台输出:

var color = 0xffffff;

                     var params = {
                        modelcolor: "#ffffff"
                        };
                    var gui = new dat.GUI();
                    var folder = gui.addFolder('Model Colour');
                    folder.addColor(params, 'modelcolor')
                        .name('Model Color')
                        .onChange(function() {

                    //var mm = new THREE.MeshStandardMaterial( {color: params.modelcolor});
                    //alert(params.modelcolor)
                    color = params.modelcolor.replace("#", "0x");

                    //mm.color.setHex(0xdd5353);
                    console.log(color);
                    for ( var i = 0; i < geometries.length; i ++ ) {
                        //console.log(materials[i].name);
                        if (materials[i].name.indexOf("Plane") !== -1) {
                            materials[i].color.setHex(0x56cc5b);
                            console.log("color should be changed for " + materials[i].name);
                        }
                    }

它在控制台中输出所需的颜色代码,但不会将其应用于汽车。 如果有人可以发布一个带有下拉换色器的基本工作示例,那将有很大帮助。

提前致谢

【问题讨论】:

  • 我觉得你需要设置materials[i].needsUpdate = true;
  • 尝试了这个建议。它画了所有东西,但我只需要车身就能获得新颜色
  • 你到底想在这里匹配什么? if (materials[i].name.indexOf("Plane") == true)(请注意,在 JavaScript 中,只有 1 == true,而任何其他数字 != true。)
  • 正确!将我的代码编辑为 - (materials[i].name.indexOf("Plane") !== -1)
  • 我正在尝试获取名为 Plane 的材质,以便我可以将其绘制为测试。

标签: javascript three.js


【解决方案1】:

在 THREE.js 中,每当您更新材质并希望在整个场景中更新效果时,您都需要在材质上设置以下标志:

material.needsUpdate = true;

这解决了您的问题还是有其他问题?

【讨论】:

    猜你喜欢
    • 2023-02-17
    • 2019-02-18
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-13
    • 1970-01-01
    相关资源
    最近更新 更多