【问题标题】:Cross Domain Problems when loading OBJ/MTL Files with textures in THREE.JS在 THREE.JS 中加载带有纹理的 OBJ/MTL 文件时的跨域问题
【发布时间】:2014-03-24 19:36:54
【问题描述】:

我有一个由单独域上的服务器动态生成的 OBJ 文件。它有一些材质和纹理的JPG文件。

我用一个简单的 php 代理 (fileProxy.php) 加载这个 OBJ 文件:

<?php
 header('Access-Control-Allow-Origin: *');
 header("Access-Control-Allow-Credentials: true"); 
 header('Access-Control-Allow-Headers: X-Requested-With');
 header('Access-Control-Allow-Headers: Content-Type');
 header('Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT'); // http://stackoverflow.com/a/7605119/578667
 header('Access-Control-Max-Age: 86400');

//Check if this is an image. if So print coorect header.
if (strpos($_REQUEST['fileToProxy'],'jpg') !== false) {

     header('Content-Type: image/jpeg');

}


$proxyFile = (isset($_REQUEST['fileToProxy'])? $_REQUEST['fileToProxy'] : null);

if ( isset($proxyFile)){
  // the files sent to us aren't properly url encoded
  $proxyFile = str_replace(' ', '+', $proxyFile);

  $content = file_get_contents($proxyFile);

  print($content);
}
else {
  echo "ERROR: no file to proxy";
}



?>

加载 OBJ 文件就像一个魅力

但是,我无法加载嵌入在 MTL 文件中的 JPG 纹理。单色着色器都可以正常工作,但加载图像时出现错误。

我在 chrome 中收到以下错误:

未捕获的安全错误:无法在“WebGLRenderingContext”上执行“texImage2D”:http://ec2-54-201-204-177.us-west-2.compute.amazonaws.com/fileProxy.php?fil…est-2.compute.amazonaws.com/3DModels/435639/DonutFullBread.jpg&timtest=115 的跨域图像可能未加载。

纹理文件的地址被正确输入到我的代理中: http://ec2-54-201-204-177.us-west-2.compute.amazonaws.com/fileProxy.php?fileToProxy=http://ec2-54-201-204-177.us-west-2.compute.amazonaws.com/3DModels/435639/DonutFullBread.jpg&timtest=115

现在检查我的网络监视器后,我意识到 Jpg 图像已成功下载,并且正确的 CORS 标头都已到位。但是 webgl/three.js 仍然吐出错误并且不显示我的模型。

所以这似乎是一个 WEBGL 错误。但是我在所有浏览器中都遇到了安全错误。 我已经在我的本地主机和服务器上对此进行了测试。同样的问题。

有什么解决办法吗?

更新 以下是我如何使用 three.js 加载 OBJ/MTL 文件: (只有跨域纹理失败)

var loader = new THREE.OBJMTLLoader( manager);

///////////////////LOAD MDOEL////////////////////
 loader.load( 'http://ec2-54-201-204-177.us-west-2.compute.amazonaws.com/fileProxy.php?fileToProxy=' + obj.file, 'http://ec2-54-201-204-177.us-west-2.compute.amazonaws.com/fileProxy.php?fileToProxy=' + obj.material, function ( object ) {                                              
//if loaded, do some stuff here.                                                   
}
loadedmodel.add(object);

这就是我所做的一切。加载程序正确地表述了材料和纹理。 我不需要设置任何材料。

【问题讨论】:

    标签: three.js textures webgl cors


    【解决方案1】:

    我只是想把这个放在这里给其他人。 当我尝试从静态谷歌地图图像加载图像时,我遇到了一个非常相似的问题。 所以这就是我所做的

    THREE.ImageUtils.crossOrigin = "anonymous";
    

    就在实际纹理加载之前。 现在这让它工作了,我可以毫无问题地加载图像。

    【讨论】:

      【解决方案2】:

      我知道这已经过时了,但我只是花了几个小时来解决相​​同的问题,所以我想我会在这里为遇到此问题的任何未来用户发布答案。解决方案非常简单,但不幸的是,我能看到的任何地方都没有记录它。我是靠运气才发现的。

      var loader = new THREE.OBJMTLLoader( manager);
      loader.crossOrigin = ''; //  <-- this is all you need to add!
      
      ///////////////////LOAD MDOEL////////////////////
      loader.load( 'http://obj_url.com', 'http://mtl_url.com', function ( object ) {                                              
          //if loaded, do some stuff here.                                                   
      }
      loadedmodel.add(object);
      

      如果上面的代码不清楚,你唯一需要做的就是在声明OBJMTLLoader.之后添加loader.crossOrigin = '';这一行

      我希望这对将来的某人有所帮助!

      【讨论】:

      • 太棒了,谢谢。我在 Apache 上也有跨源设置。这行得通。
      【解决方案3】:

      您需要为图像显式设置 crossorigin 属性。从我自己的一个例子中复制:

      images[id].image = new Image();

      images[id].image.crossOrigin = "匿名";

      images[id].image.onload = function() {/* 此处文件的 WebGL 纹理加载 */}

      images[id].image.src = "http://ec2-54-201-204-177.us-west-2.compute.amazonaws.com/fileProxy.php?fileToProxy=http://ec2-54-201-204-177.us-west-2.compute.amazonaws.com/3DModels/435639/DonutFullBread.jpg&timtest=115"

      我加载了您上面提到的图像,它在浏览器中作为纹理正常工作。

      【讨论】:

      • 原谅我的无知。但是我将如何去做呢?地址总是变化的,因为这些纹理是动态生成的。另外,如果我只是从我的代理中应用带有纹理的标准朗伯材料,它就可以正常工作。当我认为通过 OBJ/MTL 加载器应用纹理时会出现问题。
      • 我指定的代码在客户端运行(客户端浏览器上的Javascript)。无论您在何处使用 Javascript 加载图像,都需要为图像指定此属性。
      • 纹理本身在 MTL 文件中指定。在这种情况下,我如何定义纹理的交叉原点属性?非常感谢您的帮助。
      • 你是如何使用 Three.js 在客户端加载 OBJ 的?
      • 您是否尝试过添加“THREE.ImageUtils.crossOrigin = "";"在three.js调用加载之前?
      【解决方案4】:

      我经常开玩笑说我的项目因为忘记分号而失败。好吧,这次不是开玩笑。实际上有人在 ThreeJS 的最新版本中忘记了分号。我深入研究了 MTLLoader.js(由 OBJMTLLoader.js 引用),发现这一行(靠近 MTLLoader 原型构造函数的底部)缺少分号:

      materialCreator.crossOrigin = this.crossOrigin
      

      这将终止所有材料的任何跨站点共享。我在...中添加了分号。

      materialCreator.crossOrigin = this.crossOrigin;
      

      ...一切都好起来了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-07-16
        • 1970-01-01
        • 2020-07-05
        • 1970-01-01
        • 2017-06-13
        • 2017-10-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多