天天看点

three.js(5):纹理贴图和遇到的问题

完整代码:

<!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>
           

效果:

three.js(5):纹理贴图和遇到的问题

注意代码中一定要加:window.requestAnimateFrame(this.render.bind(this))这句话,因为前面的加载纹理是异步加载,即所有都加载完之后加载。

问题:出现贴图之后,是黑色纹理

three.js(5):纹理贴图和遇到的问题

可能是两个原因:

(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>

           

效果:

three.js(5):纹理贴图和遇到的问题

继续阅读