【问题标题】:ThreeJS - How can I apply an environment map to an imported obj model?ThreeJS - 如何将环境贴图应用于导入的 obj 模型?
【发布时间】:2015-12-17 16:04:49
【问题描述】:

编辑:我在这篇文章中遇到了一个解决方案——How to assign a material to ColladaLoader or OBJLoader。我使用以下代码实现了允许我在导入的 .obj 上使用 envMaterial 立方体贴图的效果 -

    var loader = new THREE.OBJLoader();

    loader.load( 'models/refTestblend.obj', function ( object ) {

      object.traverse( function ( child ) {

          if ( child instanceof THREE.Mesh ) {

              child.material = envMaterial;

          }

      } );

      scene.add( object );

    } );

不幸的是,我不得不牺牲 .mtl 文件,因此我的任务的下一步将是尝试恢复导出的 .mtl 纹理,并以某种方式混合立方体贴图材质。 (我将此标记为已回答,显然欢迎任何进一步的输入..)

编辑:混合原始纹理和 envmap cmets 问题的解决方案见下文。希望这个有用!

操作: 我有一个从搅拌机导出的环境立方体贴图 - 我可以将 envmap 应用到生成的几何体上,但是如何将它应用到我导入的 .obj 模型中?

我相信我能在这个演示中找到最接近的例子 - http://mrdoob.github.io/three.js/examples/webgl_materials_cubemap.html

loader = new THREE.BinaryLoader();
loader.load( "obj/walt/WaltHead_bin.js", function( geometry ) { createScene( geometry, cubeMaterial1, cubeMaterial2, cubeMaterial3 ) } );

但是它运行了 BinaryLoader,我不相信我可以将它用于搅拌机导出 - (我可能错了吗?)

这就是我的加载器、envmap/skybox 和工作生成的立方体的样子..

    var urls = [
        'models/cubemap/right.png',
        'models/cubemap/left.png',
        'models/cubemap/top.png',
        'models/cubemap/bottom.png',
        'models/cubemap/front.png',
        'models/cubemap/back.png'
    ];


    // create the cubemap
    var cubemap = THREE.ImageUtils.loadTextureCube(urls);
    cubemap.format = THREE.RGBFormat;

    // create a custom shader
    var shader = THREE.ShaderLib["cube"];
    shader.uniforms["tCube"].value = cubemap;

    var material = new THREE.ShaderMaterial({

        fragmentShader: shader.fragmentShader,
        vertexShader: shader.vertexShader,
        uniforms: shader.uniforms,
        depthWrite: false,
        side: THREE.DoubleSide

    });

    // create the skybox
    var skybox = new THREE.Mesh(new THREE.BoxGeometry(10000, 10000, 10000), material);
    scene.add(skybox);

    var envMaterial = new THREE.MeshBasicMaterial({envMap:cubemap});

    var cubeGeometry = new THREE.BoxGeometry(5, 5, 5);

    var cube = new THREE.Mesh(cubeGeometry, envMaterial);
    cube.name = 'cube';
    scene.add(cube);
    cube.position.set(-10, 0, 0);

    var loader = new THREE.OBJMTLLoader();
    loader.load("models/refTestblend.obj",
    "models/refTestblend.mtl",
    function(obj) {
    obj.translateY(-3);
    scene.add(obj);
    });

非常感谢!

【问题讨论】:

  • THREE.OBJMTLLoader 返回什么?如果它是一个网格,你应该能够在加载到你的 envMaterial 后切换材质。
  • 如果没有,您可以使用 Three 插件从 Blender 导出并使用 jsonloader 自行加载几何图形,然后应用 envMaterial
  • objmtl loader 很好地引入了模型,我相信作为一个网格,我不知道一旦它进入了如何手动应用 envMaterial?我可以调整 .mtl 文件中加载的纹理,但就应用立方体贴图而言,我迷路了。最终,我还希望将 .mtl 文件中使用的纹理与 envmap 结合使用。

标签: 3d three.js blender


【解决方案1】:

您可以使用如下模式将环境贴图添加到 OBJ 模型的现有材质:

    var loader = new THREE.OBJLoader();

    loader.load( 'myModel.obj', function ( object ) {

      object.traverse( function ( child ) {

          if ( child instanceof THREE.Mesh ) {

              child.material.envMap = myEnvironmentMap;
              // add any other properties you want here. check the docs.

          }

      } );

      scene.add( object );

    } );

【讨论】:

  • 您好,感谢您的参与。我正在使用 OBJMTLLoader,因为我无法找到一个像样的示例,分别从相应的 .mtl 文件加载多个纹理。所以加载器看起来像 loader.load('myModel.obj','myModel.mtl'。当我使用 child.material.envMap 时,它只会使场景中的有纹理的对象变黑?再次感谢您的帮助。
  • 好吧,我阅读了尽可能多的文档,并尝试了一堆示例,但我仍然无法理解,我正在阅读 three.js 食谱,所以希望它也会脱落一些光。我想出了一个解决方案,即加载模型两次,稍微增加一个模型的大小,然后应用 envmap 并降低透明度。这使它具有我所追求的确切效果,但是涉及加载两个相当重的模型,这实际上是不可行的。
  • 提供您认为应该可以工作的代码的实时链接。提供您希望呈现效果的图像。
  • 嗨,这是代表成功结果的图像 - 这是通过叠加两个模型来实现的纹理。 chriscarruthers.co.uk/dev/demo/result.jpg。这是示例代码chriscarruthers.co.uk/dev/demo/example.html cmets 是内联的,它显示了原始的工作版本,然后是我尝试在使用 traverse 时混合环境映射的版本,它出现了错误。此处未显示,但我尝试向材料添加参数以混合/组合它,但没有成功。
  • child.material.envMap 应该分配一个立方体贴图纹理,而不是一个材质。还要检查您的控制台错误/警告。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-07
  • 2019-04-16
  • 2017-09-10
  • 2018-09-22
  • 1970-01-01
  • 2019-03-16
相关资源
最近更新 更多