glTF加载器(glTFLoader)

一个用来加载JSON格式的.gltf资源的加载器,用来快速递交和加载3D内容。加载gltf模型,我们需要引入three.js的GLTFLoader.js

  1. <script src="./js-r100/loaders/GLTFLoader.js"></script>

加载GLTF模型

通过实例化GLTFLoader方法后,调用load函数,传入gltf模型位置就可以在场景中添加模型了.第二个参数为模型添加的回调函数,参数为获取gltf模型对象

  1. var loader = new THREE.GLTFLoader();
  2. loader.load('./models/BanGongLou/BanGongLou.gltf', function (gltf) {
  3. console.log(gltf)
  4. gltf.scene.traverse(function (child) {
  5. if (child.isMesh) {
  6. // child.material.envMap = background;
  7. }
  8. });
  9. scene.add(gltf.scene);
  10. render();
  11. }, undefined, function (e) {
  12. console.error(e);
  13. });

此时场景中样子:
image.png

添加场景贴图

在添加场景贴图前,我们先对CubeTextureLoader做一定的了解,加环境贴图的6张纹理贴图,可以通过CubeTextureLoader类趋势线。
获取CubeTextureLoader实例后,可以通过setPath()设置统一图片路径,在调用load函数时就可以按顺序添加对应的图片名称即可.

  1. var geometry = new THREE.BoxGeometry(100, 100, 100); //立方体
  2. var loader = new THREE.CubeTextureLoader();
  3. // 所有贴图在同一目录下,可以使用该方法设置共用路径
  4. loader.setPath('环境贴图/');
  5. // 立方体纹理加载器返回立方体纹理对象CubeTexture
  6. var CubeTexture = loader.load(['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg']);
  7. //材质对象Material
  8. var material = new THREE.MeshPhongMaterial({
  9. //网格模型设置颜色,网格模型颜色和环境贴图会进行融合计算
  10. // color:0xff0000,
  11. envMap: CubeTexture, //设置环境贴图
  12. // 环境贴图反射率 控制环境贴图对被渲染三维模型影响程度
  13. // reflectivity: 0.1,
  14. });
  15. console.log(CubeTexture.image);
  16. var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
  17. scene.add(mesh); //网格模型添加到场景中

接下来我们接着看导入一个我们自己的gltf模型,首先引入CubeTextureLoader.js

  1. <script type="moduls" src="./js-r100/src/loaders/CubeTextureLoader.js"></script>

创建场景对象后,设置background属性.再结合前面添加的gltf模型

  1. /**
  2. * 创建场景对象Scene
  3. */
  4. var scene = new THREE.Scene();
  5. /**
  6. * 创建网格模型
  7. */
  8. //- 环境贴图
  9. var urls = [
  10. './images/skybox/远山_RT.jpg', // right
  11. './images/skybox/远山_LF.jpg', // left
  12. './images/skybox/远山_UP.jpg', // top
  13. './images/skybox/远山_DN.jpg', // bottom
  14. './images/skybox/远山_BK.jpg', // back
  15. './images/skybox/远山_FR.jpg' // front
  16. ];
  17. var background = new THREE.CubeTextureLoader().load(urls);
  18. scene.background = background;

页面展示效果:
image.png

完整代码:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>模型材质</title>
  6. <style>
  7. body {
  8. margin: 0;
  9. overflow: hidden;
  10. /* 隐藏body窗口区域滚动条 */
  11. }
  12. </style>
  13. <!--引入three.js三维引擎-->
  14. <script src="./js-r100/three.js"></script>
  15. <script src="./js-r100/controls/OrbitControls.js"></script>
  16. <script type="moduls" src="./js-r100/src/loaders/CubeTextureLoader.js"></script>
  17. <script src="./js-r100/loaders/GLTFLoader.js"></script>
  18. </head>
  19. <body>
  20. <script>
  21. /**
  22. * 创建场景对象Scene
  23. */
  24. var scene = new THREE.Scene();
  25. /**
  26. * 创建网格模型
  27. */
  28. //- 环境贴图
  29. var urls = [
  30. './images/skybox/远山_RT.jpg', // right
  31. './images/skybox/远山_LF.jpg', // left
  32. './images/skybox/远山_UP.jpg', // top
  33. './images/skybox/远山_DN.jpg', // bottom
  34. './images/skybox/远山_BK.jpg', // back
  35. './images/skybox/远山_FR.jpg' // front
  36. ];
  37. var background = new THREE.CubeTextureLoader().load(urls);
  38. scene.background = background;
  39. // 外部导入网格模型
  40. var loader = new THREE.GLTFLoader();
  41. loader.load('./models/BanGongLou/BanGongLou.gltf', function (gltf) {
  42. console.log(gltf)
  43. gltf.scene.traverse(function (child) {
  44. if (child.isMesh) {
  45. // child.material.envMap = background;
  46. }
  47. });
  48. scene.add(gltf.scene);
  49. render();
  50. }, undefined, function (e) {
  51. console.error(e);
  52. });
  53. //- 添加半球光源
  54. light = new THREE.HemisphereLight(0xbbbbff, 0x444422);
  55. light.position.set(0, 1, 0);
  56. scene.add(light);
  57. // 辅助坐标系 参数250表示坐标系大小,可以根据场景大小去设置
  58. // var axisHelper = new THREE.AxisHelper(250);
  59. // scene.add(axisHelper);
  60. /**
  61. * 光源设置
  62. */
  63. //点光源
  64. var point = new THREE.PointLight(0xffffff);
  65. point.position.set(400, 200, 300); //点光源位置
  66. scene.add(point); //点光源添加到场景中
  67. //环境光
  68. // var ambient = new THREE.AmbientLight(0x444444);
  69. // scene.add(ambient);
  70. /**
  71. * 相机设置
  72. */
  73. var width = window.innerWidth; //窗口宽度
  74. var height = window.innerHeight; //窗口高度
  75. var k = width / height; //窗口宽高比
  76. var s = 200; //三维场景显示范围控制系数,系数越大,显示的范围越大
  77. //创建相机对象
  78. //- 远景相机 远景投影,也称之为透视投影。这个是我们人眼观察世界的模式,远景投影相机示意图如下:
  79. camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 1000);
  80. // camera.position.set( - 1.8, 0.9, 2.7 );
  81. camera.position.set(0, 2, 8);
  82. // camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
  83. /**
  84. * 创建渲染器对象
  85. */
  86. var renderer = new THREE.WebGLRenderer();
  87. renderer.setSize(width, height);//设置渲染区域尺寸
  88. // renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
  89. document.body.appendChild(renderer.domElement); //body元素中插入canvas对象
  90. //- 渲染函数
  91. function render() {
  92. //执行渲染操作 指定场景、相机作为参数
  93. renderer.render(scene, camera);
  94. // console.log(camera);
  95. }
  96. render();
  97. window.addEventListener('click', function (event) {
  98. let intsersects = getIntersects(event)
  99. if (intsersects.length > 0) {
  100. //- 判断点击的物体的name属性值
  101. if (intsersects[0].object.material.name === 'belinebox') {
  102. console.log(intsersects[0].object);
  103. //- 判断当前对象的x轴缩放是否为2倍
  104. if (intsersects[0].object.scale.x === 2) {
  105. //- 还原物体大小1比1,并设置一个颜色
  106. intsersects[0].object.scale.set(1, 1, 1)
  107. intsersects[0].object.material.color.set(0xff000)
  108. } else {
  109. //- 设置物体大小为2倍,并设置一个颜色
  110. intsersects[0].object.scale.set(2, 2, 2)
  111. intsersects[0].object.material.color.set(0x0000ff)
  112. }
  113. render()
  114. }
  115. }
  116. })
  117. // 获取与射线相交的对象数组
  118. function getIntersects(event) {
  119. event.preventDefault();
  120. // console.log("event.clientX:" + event.clientX)
  121. // console.log("event.clientY:" + event.clientY)
  122. // 声明 raycaster 和 mouse 变量
  123. var raycaster = new THREE.Raycaster();
  124. var mouse = new THREE.Vector2();
  125. // 通过鼠标点击位置,计算出 raycaster 所需点的位置,以屏幕为中心点,范围 -1 到 1
  126. mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  127. mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
  128. //通过鼠标点击的位置(二维坐标)和当前相机的矩阵计算出射线位置
  129. raycaster.setFromCamera(mouse, camera);
  130. // 获取与raycaster射线相交的数组集合,其中的元素按照距离排序,越近的越靠前
  131. var intersects = raycaster.intersectObjects(scene.children);
  132. //返回选中的对象数组
  133. return intersects;
  134. }
  135. //- 添加鼠标对视觉相机的操作
  136. let controls = new THREE.OrbitControls(camera);
  137. //监听鼠标事件,触发渲染函数,更新canvas画布渲染效果
  138. controls.addEventListener('change', render, { passive: true });
  139. </script>
  140. </body>
  141. </html>