ThreeJS-3D教学五-材质

这篇具有很好参考价值的文章主要介绍了ThreeJS-3D教学五-材质。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

我们在ThreeJS-3D教学二:基础形状展示中有简单介绍过一些常用的材质,这次我们举例来具体看下效果:
ThreeJS-3D教学五-材质,three,3d,材质,javascript,前端
代码是这样的:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    body {
      width: 100%;
      height: 100%;
    }
    * {
      margin: 0;
      padding: 0;
    }
    .label {
      font-size: 20px;
      color: #000;
      font-weight: 700;
    }
  </style>
</head>
<body>
<div id="container"></div>
<script type="importmap">
  {
    "imports": {
      "three": "../three-155/build/three.module.js",
      "three/addons/": "../three-155/examples/jsm/"
    }
  }
</script>
<script type="module">
import * as THREE from 'three';
import Stats from 'three/addons/libs/stats.module.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { GPUStatsPanel } from 'three/addons/utils/GPUStatsPanel.js';
import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
let stats, labelRenderer, gpuPanel, spotLight;
let camera, scene, renderer, controls, earth;
const group = new THREE.Group();
let widthImg = 200;
let heightImg = 200;
let time = 0;
init();
initHelp();
initLight();
axesHelperWord();
animate();
// 添加平面
addPlane();
addBox();

function addBox() {
  /**
   * 凹凸贴图可以使纹理也有厚度,看起来更立体。凹凸贴图一般使用一张灰度图,设置成材料的bumpMap属性
   * */
  const loader = new THREE.TextureLoader();
  loader.load("../materials/line_images/stone.jpg", texture => {
    loader.load("../materials/line_images/stone-bump.jpg",bumpTexture => {
      const boxGeo = new THREE.BoxGeometry(60, 60, 2);
      const material = new THREE.MeshStandardMaterial({
        map: texture,
        bumpMap: bumpTexture,
        bumpScale: 1
      });
      const box = new THREE.Mesh(boxGeo,material);
      box.position.set(-45, 10, 0);
      box.castShadow = true;
      scene.add(box);
    });
  });
  /**
   * 法向贴图使用一张法向图来表示纹理图片某个点的法向量。即用一张图片保存另一张图片的法向量信息,
   * 然后再在threejs中将这两个图片的信息合在一起,就形成了一个细节丰富的立体纹理
   * 设置材质的 normalMap 属性
   * */
  loader.load("../materials/line_images/normal2.jpg", texture => {
    loader.load("../materials/line_images/normal1.jpg", bumpTexture => {
      const boxGeo = new THREE.BoxGeometry(60, 60, 2);
      const material = new THREE.MeshStandardMaterial({
        map: texture,
        normalMap: bumpTexture
      });
      // material.normalScale.set(1, 1)
      const box = new THREE.Mesh(boxGeo,material);
      box.position.set(45, 10, 0);
      box.castShadow = true;
      scene.add(box);
    });
  });

  // 高光贴图
  loader.load("../materials/line_images/earth.jpg",textureNormal => {
    loader.load("../materials/line_images/earthSpec.png", textureSpec => {
      const meterial = new THREE.MeshPhongMaterial({
        shininess: 5, //高光部分的亮度,默认30
        map: textureNormal, // 普通纹理贴图
        specularMap: textureSpec, // 高光贴图
        specular: '#fff' // 高光部分的颜色
      });
      /**
       SphereGeometry(radius:浮点,widthSegments:整数,heightSegments:整数)
          radius——球体半径。默认值为1。
          widthSegments—水平线段的数量。最小值为3,默认值为32。
          heightSegments—垂直线段的数量。最小值为2,默认值为16。
       */
      const earthGeo = new THREE.SphereGeometry(15, 50, 50);
      earth = new THREE.Mesh(earthGeo, meterial);
      earth.position.set(0, 15, 70);
      earth.castShadow = true;
      scene.add(earth);
    });
  });
}

function addPlane() {
  // 创建一个平面 PlaneGeometry(width, height, widthSegments, heightSegments)
  const planeGeometry = new THREE.PlaneGeometry(widthImg, heightImg, 1, 1);
  // 创建 Lambert 材质:会对场景中的光源作出反应,但表现为暗淡,而不光亮。
  const planeMaterial = new THREE.MeshPhongMaterial({
    color: 0xb2d3e6,
    side: THREE.DoubleSide
  });
  const plane = new THREE.Mesh(planeGeometry, planeMaterial);
  // 以自身中心为旋转轴,绕 x 轴顺时针旋转 45 度
  plane.rotation.x = -0.5 * Math.PI;
  plane.position.set(0, -4, 0);
  plane.castShadow = true;
  plane.receiveShadow = true;
  scene.add(plane);
}

function init() {

  camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 10, 1000 );
  camera.up.set(0, 1, 0);
  camera.position.set(60, 40, 60);
  camera.lookAt(0, 0, 0);

  scene = new THREE.Scene();
  scene.background = new THREE.Color( '#ccc' );

  renderer = new THREE.WebGLRenderer( { antialias: true } );
  renderer.setPixelRatio( window.devicePixelRatio );
  renderer.setSize( window.innerWidth, window.innerHeight );

  renderer.shadowMap.enabled = true;
  renderer.shadowMap.type = THREE.PCFSoftShadowMap;
  renderer.toneMapping = THREE.ACESFilmicToneMapping;
  // 色调映射的曝光级别
  renderer.toneMappingExposure = 1;

  document.body.appendChild( renderer.domElement );

  labelRenderer = new CSS2DRenderer();
  labelRenderer.setSize( window.innerWidth, window.innerHeight );
  labelRenderer.domElement.style.position = 'absolute';
  labelRenderer.domElement.style.top = '0px';
  labelRenderer.domElement.style.pointerEvents = 'none';
  document.getElementById( 'container' ).appendChild( labelRenderer.domElement );

  controls = new OrbitControls( camera, renderer.domElement );

  // 设置最大最小视距
  controls.minDistance = 20;
  controls.maxDistance = 1000;

  window.addEventListener( 'resize', onWindowResize );

  stats = new Stats();
  stats.setMode(1); // 0: fps, 1: ms
  document.body.appendChild( stats.dom );

  gpuPanel = new GPUStatsPanel( renderer.getContext() );
  stats.addPanel( gpuPanel );
  stats.showPanel( 0 );

  scene.add( group );
}

function initLight() {

  const targetObject = new THREE.Object3D();
  targetObject.position.set(0, 0, 0);
  scene.add(targetObject);

  spotLight = new THREE.SpotLight(0xffffff);
  spotLight.position.set(0, 80, 150);
  spotLight.target = targetObject;
  spotLight.angle = Math.PI / 4;
  spotLight.intensity = 500;
  spotLight.penumbra = 1;
  spotLight.decay = 1;
  spotLight.distance = 300;
  // spotLight.map = textures['uv_grid_opengl.jpg'];

  spotLight.castShadow = true;
  spotLight.shadow.mapSize.width = 1024;
  spotLight.shadow.mapSize.height = 1024;
  spotLight.shadow.camera.near = 1;
  spotLight.shadow.camera.far = 200;
  spotLight.shadow.focus = 1;
  scene.add(spotLight);
  const lightHelper = new THREE.SpotLightHelper(spotLight);
  scene.add(lightHelper);

  const AmbientLight = new THREE.AmbientLight(new THREE.Color('rgb(255, 255, 255)'));
  scene.add( AmbientLight );
}

function initHelp() {
  // const size = 100;
  // const divisions = 5;
  // const gridHelper = new THREE.GridHelper( size, divisions );
  // scene.add( gridHelper );

  // The X axis is red. The Y axis is green. The Z axis is blue.
  const axesHelper = new THREE.AxesHelper( 100 );
  scene.add( axesHelper );
}

function axesHelperWord() {
  let xP = addWord('X轴');
  let yP = addWord('Y轴');
  let zP = addWord('Z轴');
  xP.position.set(50, 0, 0);
  yP.position.set(0, 50, 0);
  zP.position.set(0, 0, 50);
}

function addWord(word) {
  let name = `<span>${word}</span>`;
  let moonDiv = document.createElement( 'div' );
  moonDiv.className = 'label';
  // moonDiv.textContent = 'Moon';
  // moonDiv.style.marginTop = '-1em';
  moonDiv.innerHTML = name;
  const label = new CSS2DObject( moonDiv );
  group.add( label );
  return label;
}

function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize( window.innerWidth, window.innerHeight );
}

function animate() {
  requestAnimationFrame( animate );

  if (earth) {
    time += 0.00005;
    earth.rotateY(time);
  }

  stats.update();
  controls.update();
  labelRenderer.render( scene, camera );
  renderer.render( scene, camera );
}
</script>
</body>
</html>

图片我依次放进来,方便大家本地看效果

stone.jpg

ThreeJS-3D教学五-材质,three,3d,材质,javascript,前端

stone-bump.jpg

ThreeJS-3D教学五-材质,three,3d,材质,javascript,前端

normal2.jpg

ThreeJS-3D教学五-材质,three,3d,材质,javascript,前端

normal1.jpg

ThreeJS-3D教学五-材质,three,3d,材质,javascript,前端

earth.jpg

ThreeJS-3D教学五-材质,three,3d,材质,javascript,前端

earthSpec.png

ThreeJS-3D教学五-材质,three,3d,材质,javascript,前端
具体的注释也都放代码里了!感觉不错的点个赞,光白嫖可还行!文章来源地址https://www.toymoban.com/news/detail-733753.html

到了这里,关于ThreeJS-3D教学五-材质的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ThreeJS-3D教学十-有宽度的line

    webgl中线是没有宽度的,现实的应用中一般做法都是将线拓宽成面来绘制。默认threejs的线宽是无法调节的,需要用有厚度的线 THREE.Line2。 先看效果图: 看下代码:

    2024年02月07日
    浏览(39)
  • ThreeJS-3D教学八-OBJLoader模型加载+动画

    先看效果图: 本篇给大家介绍下模型加载的知识,用到了OBJLoader对应的模型,为了增加趣味性,花了些时间,利用new THREE.Points获取到模型上的点,做了一个动画效果,其实就是操作 Y轴上的点,先降低上0,然后再还原,代码如下: 如果有同学从我第一篇文章开始学到现在,

    2024年04月24日
    浏览(40)
  • ThreeJS-3D教学三:平移缩放+物体沿轨迹运动

    我们在项目中会有一些这样的需求,我们可视化一个场景,需要俯视、平移、缩放,方便观察场景中的数据或者模型,之所以把这个案例拿出来 1、这是个很实用的需求,我相信很多人会用到 2、我自己认为在实际案例中我们可以学习相关知识点更易吸收些 为了丰富本篇文章

    2024年02月03日
    浏览(47)
  • 【js&threeJS】入门three,并实现3D汽车展示厅,附带全码

    首先放个最终效果图:   三维(3D)概念: 三维(3D)是一个描述物体在三个空间坐标轴上的位置和形态的概念。相比于二维(2D)只有长度和宽度的平面,三维增加了高度或深度这一维度 在三维空间中,我们使用三个独立的坐标轴来描述物体的位置。通常使用笛卡尔坐标系

    2024年02月11日
    浏览(111)
  • ThreeJS-3D教学十一:屏幕坐标和世界坐标转换

    直接复制上面的代码,将three资源路径修改后,启动即可看到效果 上面是代码实现,以下我们看下一些理论知识点: 坐标系之间的转换关系大致为: 因此坐标转换过程就变成了: 原本世界坐标转换到观察空间坐标需要乘上视图矩阵 CameraMatrixWorldInverse(ViewMatrix) 随后,观察空

    2024年01月17日
    浏览(46)
  • Three.JS教程5 threejs中的材质

    Three.js中的材质(Material)是实现引人注目的3D效果的关键组件之一。本篇博客中,我们将深入探讨Three.js中的材质类型、属性和用法。 在Three.js中,材质是应用于几何体(Geometry)的外观和纹理的规则。它们决定了对象在场景中如何反射光线、显示颜色、反射环境等。 Three.j

    2024年02月21日
    浏览(54)
  • 前端前沿web 3d可视化技术 ThreeJS学习全记录

    完整案例与项目代码: gitee开源项目地址 https://gitee.com/jumping-world-line/01_threeJS_basic 随着浏览器性能和网络带宽的提升 使得3D技术不再是桌面的专利 打破传统平面展示模式 前端方向主要流向的3D图形库包括Three.js和WebGL WebGL灵活高性能,但代码量大,难度大,需要掌握很多底层

    2024年02月01日
    浏览(58)
  • 除了three.js,还有许多其他前端开发语言和库可以用于创建3D可视化大屏

    hello老铁们...本人熟悉html5,vue对bootsrap,uniapp,layui,element,vite,antd,echarts,jq响应式尤其擅长,ui设计等技能,如果ui前端工作中有遇到烦恼可私信关注评论我们共同交流进步!谢谢       随着前端技术的飞速发展,3D可视化已经成为许多应用场景中不可或缺的一部分。在

    2024年03月15日
    浏览(68)
  • 19个Web前端交互式3D JavaScript框架和库

    JavaScript (JS) 是一种轻量级的解释(或即时编译)编程语言,是世界上最流行的编程语言。JavaScript 是一种基于原型的多范式、单线程的动态语言,支持面向对象、命令式和声明式(例如函数式编程)风格。JavaScript 几乎可以做任何事情,更可以在包括物联网在内的多个平台

    2024年02月22日
    浏览(45)
  • Threejs开发3D展馆 | 大帅老猿threejs特训

    本文将介绍如果使用Threejs开发制作一个3D展馆,效果如图:  首先,我们需要一个展馆模型。我是通过Blender做出来的,在Blender中将模型导出为glb格式。 接下来,我们通过代码将模型加载到网页中。 在3D图形开发中,最基本的概念就是场景、相机和光源。这三个是构成3D世界

    2024年02月11日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包