Threejs问题:TextureLoader 与<img>标签,图片跨域的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Threejs问题:TextureLoader 与<img>标签,图片跨域的问题相关的知识,希望对你有一定的参考价值。

参考技术A 项目中遇到一个问题,同一个图片在 dom 节点中使用了 <img> 标签来加载,同时由于项目使用了 ThreeJS 3D 渲染引擎,在加载纹理时使用了 TextureLoader 来加载了同一张图片,而由于图片是在阿里云服务器上的,所以最后报出了跨域问题。

https://www.jianshu.com/p/8fa0fb53c183

ThreeJS——创建纹理贴图

这次小猿来给大家介绍一下三维模型纹理贴图,在实际的三维场景中,三维模型都是贴图显示的,比如一些大型的三维场景的游戏,场景的树,草地,房屋等等,其模型表面显示的材质效果都是可以通过贴图来实现。



这里实现贴图可以通过两种方法实现,一是通过TextureLoader创建一个纹理加载器对象,可以加载图片作为几何体纹理;二是通过图片加载器ImageLoader加载一张图片。



TextureLoader创建一个纹理加载器对象

// TextureLoader创建一个纹理加载器对象,可以加载图片作为几何体纹理let textureLoader = new THREE.TextureLoader();// 执行load方法,加载纹理贴图成功后,返回一个纹理对象TexturetextureLoader.load('./../img/earth.jpg', texture => { let material = new THREE.MeshLambertMaterial({ // color: 0x0000ff, // 设置颜色纹理贴图:Texture对象作为材质map属性的属性值 side: THREE.DoubleSide, map: texture,// 设置颜色贴图属性值 }); // 材质对象Material mesh = new THREE.Mesh(geometry, material); // 网格模型对象Mesh scene.add(mesh); // 网格模型添加到场景中})

ImageLoader加载一张图片

// 图片加载器let ImageLoader = new THREE.ImageLoader();// load方法回调函数,按照路径加载图片,返回一个html的元素img对象ImageLoader.load('./../img/earth.jpg', img => { // image对象作为参数,创建一个纹理对象Texture let texture = new THREE.Texture(img); // 下次使用纹理时触发更新 texture.needsUpdate = true; let material = new THREE.MeshLambertMaterial({ side: THREE.DoubleSide, map: texture, //设置纹理贴图 }); mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh scene.add(mesh); //网格模型添加到场景中})

纹理图片


完整代码

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title></title><style> body{ margin: 0; overflow: hidden; }</style></head><body><script src="./../js/three.js"></script><script src="./../js/OrbitControls.js"></script><script>/** 创建场景对象Scene* */let scene = new THREE.Scene();let mesh = null
// 纹理贴图映射到一个矩形平面上// let geometry = new THREE.PlaneGeometry(250, 250); // 矩形平面// let geometry = new THREE.BoxGeometry(100, 100, 100); //立方体let geometry = new THREE.SphereGeometry(100, 40, 40); //球体
/*// TextureLoader创建一个纹理加载器对象,可以加载图片作为几何体纹理let textureLoader = new THREE.TextureLoader();// 执行load方法,加载纹理贴图成功后,返回一个纹理对象TexturetextureLoader.load('./../img/earth.jpg', texture => { let material = new THREE.MeshLambertMaterial({ // color: 0x0000ff, // 设置颜色纹理贴图:Texture对象作为材质map属性的属性值 side: THREE.DoubleSide, map: texture,// 设置颜色贴图属性值 }); // 材质对象Material mesh = new THREE.Mesh(geometry, material); // 网格模型对象Mesh scene.add(mesh); // 网格模型添加到场景中})*/
/*----------------------------------------------*/// 图片加载器let ImageLoader = new THREE.ImageLoader();// load方法回调函数,按照路径加载图片,返回一个html的元素img对象ImageLoader.load('./../img/earth.jpg', img => { // image对象作为参数,创建一个纹理对象Texture let texture = new THREE.Texture(img); // 下次使用纹理时触发更新 texture.needsUpdate = true; let material = new THREE.MeshLambertMaterial({ side: THREE.DoubleSide, map: texture, //设置纹理贴图 }); mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh scene.add(mesh); //网格模型添加到场景中});

/** * 光源设置 *///点光源let point = new THREE.PointLight(0xffffff);point.position.set(400, 200, 300);scene.add(point);//环境光let ambient = new THREE.AmbientLight(0x444444);scene.add(ambient);
/** * 相机设置 */let width = window.innerWidth; //窗口宽度let height = window.innerHeight;let k = width / height; //窗口宽高比let s = 200;// 创建相机对象let camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);camera.position.set(200, 300, 200); //设置相机位置camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
/** * 创建渲染器对象 */let renderer = new THREE.WebGLRenderer();renderer.setSize(width, height);//设置渲染区域尺寸renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色document.body.appendChild(renderer.domElement); // body元素中插入canvas对象//执行渲染操作 指定场景、相机作为参数
let T0 = new Date()function renderModle() { let T1 = new Date() let t = T1 - T0 T0 = T1 requestAnimationFrame(renderModle) renderer.render(scene, camera) mesh.rotateY(0.0001 * t)}renderModle ()</script></body></html>

显示效果

ThreeJS——创建纹理贴图


以上是关于Threejs问题:TextureLoader 与<img>标签,图片跨域的问题的主要内容,如果未能解决你的问题,请参考以下文章

ThreeJS——创建纹理贴图

threejs4模型发光加GUI

threejs7 实现背景图和360全景图的加载

尝试使用 TextureLoader 从 Rails 应用程序连接到 S3 时出现 CORS 错误

如何通过一张图片给BoxBufferGeometry的6个面贴图

Threejs:与热点交互的全景图