我有一个由单独域上的服务器动态生成的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中遇到以下错误:
Uncaught SecurityError:无法在'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&amp; timtest = 115可能无法加载。
现在在检查我的网络监视器后,我意识到Jpg图像已成功下载,并且正确的CORS标头都已到位。但是webgl / three.js仍然会出错并且不会显示我的模型。
所以这看起来像一个WEBGL错误。但我在所有浏览器中都获得了安全错误。 我在我的localhost和我的服务器上测试了这个。同样的问题。
任何解决方案?
更新 这是我如何使用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);
这就是我所做的一切。材料和纹理由装载器正确表达。 我没有必要设置任何材料。
答案 0 :(得分:4)
我只是想把这个放在其他人身上。 当我试图从静态谷歌地图图像加载图像时,我有一个非常类似的问题。 所以这就是我所做的
THREE.ImageUtils.crossOrigin = "anonymous";
在加载实际纹理之前。 现在这让它工作了,我可以毫无问题地加载图像。
答案 1 :(得分: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);
如果上述代码中不清楚,您唯一需要做的就是在声明loader.crossOrigin = '';
后添加行OBJMTLLoader.
我希望这有助于将来的某个人!
答案 2 :(得分:1)
您需要为图像显式设置crossorigin属性。从我自己的一个例子中复制:
images [id] .image = new Image();
images [id] .image.crossOrigin =“anonymous”;
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”
我加载了您上面提到的图片,它在浏览器中作为纹理正常使用。
答案 3 :(得分:0)
我经常开玩笑说我的项目因为忘了分号而爆炸了。好吧,这次不是开玩笑。有人在最新版本的ThreeJS中忘记了分号。我挖到了MTLLoader.js(由OBJMTLLoader.js引用)并发现这一行(靠近MTLLoader原型构造函数的底部)有一个分号丢失:
materialCreator.crossOrigin = this.crossOrigin
这会杀死所有材料的任何跨站点共享。我把分号添加回......
materialCreator.crossOrigin = this.crossOrigin;
......再次与世界相处得很好。