完整代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>正方体贴图</title>
<style>
.body{
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
</body>
<script src="js/three.js"></script>
<script>
var scene=new THREE.Scene();
/*相机设置*/
var width=window.innerWidth;
var height=window.innerHeight;
var k=width/height;
var s=100;
var camera=new THREE.OrthographicCamera(-k*s,k*s,s,-s,1,1000);
camera.position.set(200,300,200);
camera.lookAt(scene.position);
// /*光源*/
// //点光源
var pointLight=new THREE.PointLight(0x0000FF);
pointLight.position.set(300,400,300);
scene.add(pointLight);
// //环境光
var envLight=new THREE.AmbientLight(0xFAFAD2)
scene.add(envLight);
/*几何体*/
var texture = new THREE.TextureLoader().load( 'crate.jpg' );
var box_show = new THREE.CubeGeometry(10,10,10,1,1,1);
var box_metal = new THREE.MeshPhongMaterial({
map: texture
});
var mesh = new THREE.Mesh(box_show, box_metal);
scene.add(mesh);
/*渲染*/
var renderer=new THREE.WebGLRenderer();
renderer.setSize(width,height);
renderer.setClearColor(0xb9d3ff,1);
document.body.appendChild(renderer.domElement);
render();
function render(){
window.requestAnimationFrame(this.render.bind(this))
renderer.render(scene,camera);
mesh.rotateX(0.1);
}
</script>
</html>
效果:
注意代码中一定要加:window.requestAnimateFrame(this.render.bind(this))这句话,因为前面的加载纹理是异步加载,即所有都加载完之后加载。
问题:出现贴图之后,是黑色纹理
可能是两个原因:
(1)没有服务器,需要运行在服务器上,可以用node.js(一定要在开启本地服务器的环境下运行,不要直接打开文件调试),这个问题和加载3维模型一样,参考上篇https://blog.csdn.net/chengmo123/article/details/108247020(three.js(4):加载外部3维模型)
(2)网上的代码大多有问题,没有加window.requestAnimateFrame(this.render.bind(this))这句,new THREE.TextureLoader().load()方法是异步,即所有代码执行完成后再执行里面的代码(参考:https://blog.csdn.net/qq_32339477/article/details/106670757和three.js加载纹理为黑色)
https://blog.csdn.net/qq_32339477/article/details/106670757代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>创建纹理贴图</title>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
<script src="js/three.js"></script>
</head>
<body>
<script>
/*==========================================创建一个场景==============================================================*/
var scene = new THREE.Scene(); // 创建一个场景
// 纹理贴图映射到一个矩形平面上
var geometry = new THREE.BoxGeometry(200,200,200); //矩形平面
// TextureLoader创建一个纹理加载器对象,可以加载图片作为几何体纹理
var textureLoader = new THREE.TextureLoader();
// 执行load方法,加载纹理贴图成功后,返回一个纹理对象Texture
textureLoader.load('crate.jpg', function(texture) {
var material = new THREE.MeshLambertMaterial({
// color: 0x0000ff,
// 设置颜色纹理贴图:Texture对象作为材质map属性的属性值
map: texture,//设置颜色贴图属性值
});
var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
scene.add(mesh); //网格模型添加到场景中
//点光源
var point = new THREE.PointLight(0xffffff);
point.position.set(400, 200, 300); //点光源位置
scene.add(point); //点光源添加到场景中
var width = window.innerWidth; //窗口宽度
var height = window.innerHeight; //窗口高度
var k = width / height; //窗口宽高比
var s = 300; //三维场景显示范围控制系数,系数越大,显示的范围越大
//创建相机对象
var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
camera.position.set(200, 300, 100); //设置相机位置
camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
var renderer = new THREE.WebGLRenderer(); // 创建渲染器
renderer.setSize( window.innerWidth, window.innerHeight ); // 应用程序里设置一个渲染器的尺寸
renderer.setClearColor(0xb9d3ff, 1);
document.body.appendChild( renderer.domElement ); // 将renderer(渲染器)的dom元素(renderer.domElement)添加到我们的HTML文档中
renderer.render(scene,camera)
})
</script>
</body>
</html>
效果: