首页 > 其他分享 >three.js基础之动画、相机、材质、灯光

three.js基础之动画、相机、材质、灯光

时间:2024-04-05 17:13:26浏览次数:14  
标签:scene 动画 const THREE three add camera new js

动画

<body>
  <canvas id="mainCanvas" width="400px" height="300px"></canvas>
</body>
<script type="importmap">
  {
    "imports": {
      "three": "./js/build/three.module.js",
      "three/jsm/": "./js/jsm/"
    }
  }
</script>
<script type="module">
  import * as THREE from "three";
  import Stats from "three/jsm/libs/stats.module.js";

  const renderer = new THREE.WebGLRenderer({
    canvas: document.getElementById("mainCanvas"),
  });
  renderer.setClearColor(0x000000);

  const scene = new THREE.Scene();

  const box = new THREE.Mesh(
    new THREE.BoxGeometry(100, 60, 20),
    new THREE.MeshBasicMaterial({
      color: 0x0000ff, //设置材质颜色
      transparent: true, //开启透明
      opacity: 0.5, //设置透明度
    })
  );
  box.position.set(10, 0, 0);
  scene.add(box);

  const camera = new THREE.PerspectiveCamera(30, 400 / 300, 1, 3000); //透视投影相机参数设置
  camera.position.set(200, 200, 200);
  camera.lookAt(0, 0, 0);
  scene.add(camera);

  const axesHelper = new THREE.AxesHelper(150);
  scene.add(axesHelper);

  renderer.render(scene, camera);

  // 渲染循环
  const clock = new THREE.Clock();
  function render() {
    const spt = clock.getDelta() * 1000; //毫秒
    console.log("两帧渲染时间间隔(毫秒)", spt);
    console.log("帧率FPS", 1000 / spt);
    renderer.render(scene, camera); //执行渲染操作
    box.rotateY(0.01); //每次绕y轴旋转0.01弧度
    requestAnimationFrame(render); //请求再次执行渲染函数render,渲染下一帧
  }
  render();
</script>

相机

<body>
  <canvas id="OrthographicCamera" width="300px" height="200px"></canvas>
  <canvas id="PerspectiveCamera" width="300px" height="200px"></canvas>
  <canvas id="OrbitControls" width="300px" height="200px"></canvas>
</body>
<script type="importmap">
  {
    "imports": {
      "three": "./js/build/three.module.js",
      "three/jsm/": "./js/jsm/"
    }
  }
</script>
<script type="module">
  import * as THREE from "three";
  import { OrbitControls } from "three/jsm/controls/OrbitControls.js";

  const pointsArr = [new THREE.Vector2(0, 0), new THREE.Vector2(100, 0), new THREE.Vector2(100, 100), new THREE.Vector2(0, 100)];
  const shape = new THREE.Shape(pointsArr);
  const geometry = new THREE.ExtrudeGeometry(shape, { depth: 100 });
  const material = new THREE.MeshBasicMaterial({
    color: 0xffffff,
    side: THREE.DoubleSide, //双面显示看到管道内壁
  });
  const mesh = new THREE.Mesh(geometry, material);

  let resize_Orthographic;
  let resize_Perspective;

  {
    const renderer = new THREE.WebGLRenderer({
      canvas: document.getElementById("OrthographicCamera"),
      antialias: true,
    });
    renderer.setClearColor(0x000000);

    const scene = new THREE.Scene();
    scene.add(mesh);

    // 正投影相机
    const width = 300; //canvas画布宽度
    const height = 200; //canvas画布高度
    const k = width / height; //canvas画布宽高比
    const s = 200; //控制left, right, top, bottom范围大小
    const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 8000);
    camera.position.set(700, 500, 500);
    camera.lookAt(0, 0, 0);
    scene.add(camera);

    const axesHelper = new THREE.AxesHelper(150);
    scene.add(axesHelper);

    renderer.render(scene, camera);

    resize_Orthographic = function () {
      const width = 400;
      const height = 200;
      renderer.setSize(width, height); //更新Canvas画布尺寸

      const k = width / height;
      camera.left = -s * k;
      camera.right = s * k;
      camera.updateProjectionMatrix(); //相机参数更新
    };
  }

  {
    const renderer = new THREE.WebGLRenderer({
      canvas: document.getElementById("PerspectiveCamera"),
      antialias: true,
    });
    renderer.setClearColor(0x000000);

    const scene = new THREE.Scene();
    scene.add(mesh);

    const width = 300; //canvas画布宽度
    const height = 200; //canvas画布高度
    const k = width / height; //canvas画布宽高比
    const camera = new THREE.PerspectiveCamera(30, k, 1, 3000); //透视投影相机参数设置
    camera.position.set(700, 500, 500); //设置相机位置
    camera.lookAt(0, 0, 0);
    scene.add(camera); //添加到场景中。

    const axesHelper = new THREE.AxesHelper(150);
    scene.add(axesHelper);

    renderer.render(scene, camera);

    resize_Perspective = function () {
      const width = 400;
      const height = 200;
      renderer.setSize(width, height); //更新Canvas画布尺寸

      camera.aspect = width / height;
      camera.updateProjectionMatrix(); //相机参数更新
    };
  }

  {
    const renderer = new THREE.WebGLRenderer({
      canvas: document.getElementById("OrbitControls"),
      antialias: true,
    });
    renderer.setClearColor(0x000000);

    const scene = new THREE.Scene();

    const pointsArr = [new THREE.Vector2(0, 0), new THREE.Vector2(30, 0), new THREE.Vector2(30, 30), new THREE.Vector2(0, 30)];
    const shape = new THREE.Shape(pointsArr);
    const geometry = new THREE.ExtrudeGeometry(shape, { depth: 30 });
    const material = new THREE.MeshBasicMaterial({
      color: 0xffff00,
      side: THREE.DoubleSide,
    });
    const mesh = new THREE.Mesh(geometry, material);
    scene.add(mesh);

    const box = new THREE.Mesh(new THREE.BoxGeometry(30, 30, 20), material);
    box.position.set(0, 50, 0);
    scene.add(box);

    // 包围盒计算模型对象的大小和位置
    const box3 = new THREE.Box3();
    box3.expandByObject(mesh); // 计算模型包围盒
    console.log("查看包围盒", box3);
    const size = new THREE.Vector3();
    box3.getSize(size); // 计算包围盒尺寸
    console.log("模型包围盒尺寸", size);
    const center = new THREE.Vector3();
    box3.getCenter(center); // 计算包围盒中心坐标
    console.log("模型中心坐标", center);

    const width = 400; //canvas画布宽度
    const height = 300; //canvas画布高度
    const k = width / height;
    const s = 200; //控制left, right, top, bottom范围大小
    const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 8000); 
    camera.position.set(center.x, center.y, 500);
    camera.lookAt(center.x, center.y, center.z);
    scene.add(camera);

    const axesHelper = new THREE.AxesHelper(150);
    scene.add(axesHelper);

    //相机控件
    const controls = new OrbitControls(camera, renderer.domElement);
    controls.enablePan = true; //允许右键拖拽,默认值true
    controls.enableZoom = true; //允许缩放,默认值true
    controls.enableRotate = true; //允许旋转,默认值true
    controls.minDistance = 200; //相机位置与观察目标点距离
    controls.maxDistance = 500;
    controls.minZoom = 0.5; //正投影缩放范围
    controls.maxZoom = 2;
    controls.minPolarAngle = 0; //上下旋转范围 默认值0
    controls.maxPolarAngle = Math.PI; //默认值Math.PI
    controls.minAzimuthAngle = -Math.PI / 2; // 左右旋转范围
    controls.maxAzimuthAngle = Math.PI / 2;
    const dis = controls.getDistance(); //相机位置与目标观察点距离
    console.log("dis", dis);
    controls.target.set(0, 0, 0);

    controls.update(); //update()函数内会执行camera.lookAt(x, y, z)

    controls.addEventListener("change", function () {
      renderer.render(scene, camera); //执行渲染操作
    }); //监听鼠标、键盘事件

    renderer.render(scene, camera);

    // 渲染循环
    let angle = 0; //用于圆周运动计算的角度值
    const R = 100; //相机圆周运动的半径
    function render() {
      angle += 0.01;
      // 相机y坐标不变,在XOZ平面上做圆周运动
      camera.position.x = R * Math.cos(angle);
      camera.position.z = R * Math.sin(angle);
      camera.lookAt(0, 0, 0);
      renderer.render(scene, camera);
      requestAnimationFrame(render);

      // 查看相机位置变化
      console.log("camera.position", camera.position);
    }
    render();
  }

  window.addEventListener("resize", resize_Orthographic);
  window.addEventListener("resize", resize_Perspective);
</script>

单个物体,两种相机的显示效果感觉差别不大

灯光

<body>
  <canvas id="canvas-ambient-light" width="300px" height="200px"></canvas>
  <canvas id="canvas-directional-light" width="300px" height="200px"></canvas>
  <canvas id="canvas-point-light" width="300px" height="200px"></canvas>
  <canvas id="canvas-spot-light" width="300px" height="200px"></canvas>
</body>
<script type="importmap">
  {
    "imports": {
      "three": "./js/build/three.module.js",
      "three/jsm/": "./js/jsm/"
    }
  }
</script>
<script type="module">
  import * as THREE from "three";

  const mesh = new THREE.Mesh(
    new THREE.BoxGeometry(50, 30, 20),
    new THREE.MeshLambertMaterial({
      color: 0xffffff, //设置材质颜色
      side: THREE.DoubleSide, //两面可见
    })
  );

  {
    const renderer = new THREE.WebGLRenderer({
      canvas: document.getElementById("canvas-ambient-light"),
    });
    renderer.setClearColor(0x000000);

    const scene = new THREE.Scene();

    mesh.position.set(10, 0, 0);
    scene.add(mesh);

    //环境光:没有特定方向,整体改变场景的光照明暗
    const ambient = new THREE.AmbientLight(0xffffff, 0.4);
    scene.add(ambient);

    const camera = new THREE.PerspectiveCamera(30, 300 / 200, 1, 3000); //透视投影相机参数设置
    camera.position.set(200, 200, 200); //设置相机位置
    camera.lookAt(0, 0, 0);
    scene.add(camera); //添加到场景中。

    const axesHelper = new THREE.AxesHelper(150);
    scene.add(axesHelper);

    renderer.render(scene, camera);
  }

  {
    const renderer = new THREE.WebGLRenderer({
      canvas: document.getElementById("canvas-directional-light"),
    });
    renderer.setClearColor(0x000000);
    renderer.shadowMap.enabled = true; // 设置渲染器,允许光源阴影渲染

    const scene = new THREE.Scene();

    mesh.position.set(10, 0, 0);
    mesh.castShadow = true; // 设置产生投影的网格模型
    scene.add(mesh);

    const geometry = new THREE.PlaneGeometry(20, 30);
    const mesh2 = new THREE.Mesh(
      geometry,
      new THREE.MeshLambertMaterial({
        color: 0xffffff,
        side: THREE.DoubleSide,
      })
    );
    mesh2.position.set(0, 0, 50);
    mesh2.rotateY(Math.PI / 2);
    scene.add(mesh2);

    // 平行光:两个参数分别表示光源颜色和光照强度
    const directionalLight = new THREE.DirectionalLight(0xffffff, 5);
    directionalLight.position.set(100, 50, 50);
    directionalLight.target = mesh; // 方向光指向对象,可以不设置,默认的位置是0,0,0
    directionalLight.castShadow = true; // 平行光设置产生阴影的光源对象,开启光源阴影的计算功能
    // 设置三维场景计算阴影的范围
    directionalLight.shadow.camera.left = -200;
    directionalLight.shadow.camera.right = 200;
    directionalLight.shadow.camera.top = 200;
    directionalLight.shadow.camera.bottom = -200;
    directionalLight.shadow.camera.near = 0.5;
    directionalLight.shadow.camera.far = 300;
    console.log("阴影默认像素", directionalLight.shadow.mapSize); // mapSize属性默认512x512
    console.log("shadow.radius", directionalLight.shadow.radius); // 模糊弱化阴影边缘
    scene.add(directionalLight);

    const camera = new THREE.PerspectiveCamera(30, 300 / 200, 1, 3000); //透视投影相机参数设置
    camera.position.set(300, 300, 300);
    camera.lookAt(0, 0, 0);
    scene.add(camera);

    const axesHelper = new THREE.AxesHelper(150);
    scene.add(axesHelper);

    // DirectionalLightHelper:可视化平行光
    const dirLightHelper = new THREE.DirectionalLightHelper(directionalLight, 5, 0xff0000);
    scene.add(dirLightHelper);

    // 可视化平行光阴影对应的正投影相机对象
    const cameraHelper = new THREE.CameraHelper(directionalLight.shadow.camera);
    // scene.add(cameraHelper);

    renderer.render(scene, camera);
  }

  {
    const renderer = new THREE.WebGLRenderer({
      canvas: document.getElementById("canvas-point-light"),
    });
    renderer.setClearColor(0x000000);

    const scene = new THREE.Scene();

    mesh.position.set(10, 0, 0);
    scene.add(mesh);

    //点光源:两个参数分别表示光源颜色和光照强度
    const pointLight = new THREE.PointLight(0xffffff, 10000.0);
    pointLight.position.set(100, 50, 50);
    scene.add(pointLight); //点光源添加到场景中

    const camera = new THREE.PerspectiveCamera(30, 300 / 200, 1, 3000); //透视投影相机参数设置
    camera.position.set(200, 200, 200);
    camera.lookAt(0, 0, 0);
    scene.add(camera);

    const axesHelper = new THREE.AxesHelper(150);
    scene.add(axesHelper);

    // 光源辅助观察
    const pointLightHelper = new THREE.PointLightHelper(pointLight, 10);
    scene.add(pointLightHelper);

    renderer.render(scene, camera);
  }

  {
    const renderer = new THREE.WebGLRenderer({
      canvas: document.getElementById("canvas-spot-light"),
    });
    renderer.setClearColor(0x000000);

    const scene = new THREE.Scene();

    mesh.position.set(0, 0, 0);
    scene.add(mesh);

    // 聚光源:两个参数分别表示光源颜色和光照强度
    const spotLight = new THREE.SpotLight(0xffffff, 10000.0);
    spotLight.angle = Math.PI / 2; // 设置聚光光源发散角度
    // spotLight.decay = 0.0; //设置光源不随距离衰减
    spotLight.position.set(100, 50, 50); // 设置聚光光源位置
    scene.add(spotLight); //光源添加到场景中
    spotLight.target.position.set(0, 0, 0);

    const camera = new THREE.PerspectiveCamera(30, 300 / 200, 1, 3000); //透视投影相机参数设置
    camera.position.set(200, 200, 200);
    camera.lookAt(0, 0, 0);
    scene.add(camera);

    const axesHelper = new THREE.AxesHelper(150);
    scene.add(axesHelper);

    // 聚光源辅助对象,可视化聚光源
    const spotLightHelper = new THREE.SpotLightHelper(spotLight, 0xffffff);
    scene.add(spotLightHelper);

    renderer.render(scene, camera);
  }
</script>

材质

<body>
  <canvas id="MeshBasicMaterial" width="300px" height="200px"></canvas>
  <canvas id="MeshLambertMaterial" width="300px" height="200px"></canvas>
  <canvas id="MeshPhongMaterial" width="300px" height="200px"></canvas>
</body>
<script type="importmap">
  {
    "imports": {
      "three": "./js/build/three.module.js",
      "three/jsm/": "./js/jsm/"
    }
  }
</script>
<script type="module">
  import * as THREE from "three";

  {
    const renderer = new THREE.WebGLRenderer({
      canvas: document.getElementById("MeshBasicMaterial"),
      antialias: true,
    });
    renderer.setClearColor(0x000000);

    const scene = new THREE.Scene();

    const geometry = new THREE.BoxGeometry(60, 40, 20);
    const material = new THREE.MeshBasicMaterial({
      color: 0xff0000,
    });
    const mesh = new THREE.Mesh(geometry, material);
    scene.add(mesh);

    //环境光:没有特定方向,整体改变场景的光照明暗
    const ambient = new THREE.AmbientLight(0xffffff, 3);
    scene.add(ambient);

    const camera = new THREE.PerspectiveCamera(30, 300 / 200, 1, 3000); //透视投影相机参数设置
    camera.position.set(300, 300, 300);
    camera.lookAt(0, 0, 0);
    scene.add(camera);

    const axesHelper = new THREE.AxesHelper(150);
    scene.add(axesHelper);

    renderer.render(scene, camera);
  }

  {
    const renderer = new THREE.WebGLRenderer({
      canvas: document.getElementById("MeshLambertMaterial"),
      antialias: true,
    });
    renderer.setClearColor(0x000000);

    const scene = new THREE.Scene();

    const geometry = new THREE.BoxGeometry(60, 40, 20);
    // 高光网格材质
    const material = new THREE.MeshLambertMaterial({
      color: 0xff0000,
    });
    const mesh = new THREE.Mesh(geometry, material);
    scene.add(mesh);

    // 聚光源:两个参数分别表示光源颜色和光照强度
    const spotLight = new THREE.SpotLight(0xffffff, 3.0);
    spotLight.angle = Math.PI / 2; // 设置聚光光源发散角度
    spotLight.decay = 0.0; //设置光源不随距离衰减
    spotLight.position.set(100, 50, 50); // 设置聚光光源位置
    scene.add(spotLight); //光源添加到场景中
    spotLight.target.position.set(0, 0, 0);

    const camera = new THREE.PerspectiveCamera(30, 300 / 200, 1, 3000); //透视投影相机参数设置
    camera.position.set(300, 300, 300);
    camera.lookAt(0, 0, 0);
    scene.add(camera);

    const axesHelper = new THREE.AxesHelper(150);
    scene.add(axesHelper);

    renderer.render(scene, camera);
  }

  {
    const renderer = new THREE.WebGLRenderer({
      canvas: document.getElementById("MeshPhongMaterial"),
      antialias: true,
    });
    renderer.setClearColor(0x000000);

    const scene = new THREE.Scene();

    const geometry = new THREE.BoxGeometry(60, 40, 20);
    // 高光网格材质
    const material = new THREE.MeshPhongMaterial({
      color: 0xff0000,
      shininess: 20, //高光部分的亮度,默认30
      specular: 0x444444, //高光部分的颜色
    });
    const mesh = new THREE.Mesh(geometry, material);
    scene.add(mesh);

    // 聚光源:两个参数分别表示光源颜色和光照强度
    const spotLight = new THREE.SpotLight(0xffffff, 3.0);
    spotLight.angle = Math.PI / 2; // 设置聚光光源发散角度
    spotLight.decay = 0.0; //设置光源不随距离衰减
    spotLight.position.set(100, 50, 50); // 设置聚光光源位置
    scene.add(spotLight); //光源添加到场景中
    spotLight.target.position.set(0, 0, 0);

    const camera = new THREE.PerspectiveCamera(30, 300 / 200, 1, 3000); //透视投影相机参数设置
    camera.position.set(300, 300, 300);
    camera.lookAt(0, 0, 0);
    scene.add(camera);

    const axesHelper = new THREE.AxesHelper(150);
    scene.add(axesHelper);

    renderer.render(scene, camera);
  }
</script>

 

标签:scene,动画,const,THREE,three,add,camera,new,js
From: https://www.cnblogs.com/caroline2016/p/18115914

相关文章

  • three.js基础之几何体Curve、Geometry
    CurveEllipseCurve<canvasid="EllipseCurve"width="300px"height="200px"></canvas><canvasid="ArcCurve"width="300px"height="200px"></canvas><canvasid="Curv......
  • js基本数据类型——Symbol
    一、介绍Symbol是ES6中新加的基本数据类型。可以用于解决对象属性名称冲突的问题,以及提供一种唯一的标识符。还是不清楚?别急,先看看下面的场景:现在我要用一个User类来表示用户对象,每个用户对象都有一个唯一的userId,并且我希望能够将这个对象的一些属性标记为私有属性,例如密......
  • three.js基础
    记录下three.js的学习历程。three.js基本概念包括画布Canvas、渲染器Renderer、场景Scene、相机Camera、光源Light、几何体Geometry、材质Material、颜色纹理、点模型、线模型、网格模型、阴影、外部三维模型、动画等 基础<canvasid="basic"></canvas><scripttype="impo......
  • 二叉树计算【华为OD机试JAVA&Python&C++&JS题解】
    一.题目-二叉树计算给出一个二叉树如下图所示:6/79\/-26请由该二叉树生成一个新的二叉树,它满足其树中的每个节点将包含原始树中的左子树和右子树的和。20(7-2+9+6)/\-26\/......
  • 学生重新排队【华为OD机试JAVA&Python&C++&JS题解】
    一.题目-学生重新排队n个学生排成一排,学生编号分别是1到n,n为3的整倍数。老师随机抽签决定将所有学生分成m个3人的小组,n=3*m为了便于同组学生交流,老师决定将小组成员安排到一起,也就是同组成员彼此相连,同组任意两个成员输入描述:之间无其它组的成员。因此老师决定调整队伍,......
  • `.gitattributes` 文件中的 *.js linguist-language=ts *.tsx linguist-language=ts
    .jslinguist-language=ts和.tsxlinguist-language=ts是针对特定文件类型的元数据标记,它们的作用是在特定的上下文中指示这些文件的实际编程语言类型,而非其扩展名所暗示的语言。具体来说:.jslinguist-language=ts表示尽管文件以.js扩展名结尾,但实际上它应该被视为TypeScr......
  • HTB-Three
    HTB-Three1.TASK1输入命令:nmap-sS-sV10.129.247.144-sC使用默认脚本扫描-sV探测服务/版本信息答案:22.TASK2问题:网站“联系人”部分提供的电子邮件地址的域是什么?答案:thetoppers.htb3.TASK3问题:在没有DNS服务器的情况下,我们可以使用哪个Linux文件将主机名......
  • 万户ezOFFICE-wf_printnum.jsp存在SQL注入漏洞
    声明:本文仅用于技术交流,请勿用于非法用途由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。简介万户EZOFFICE是一款办公软件,由中国万户网络科技有限公司开发和提供。该软件提供了一系列办公管理工具,包括......
  • Node.js毕业设计基于WEB的学生成绩查询系统(Express+附源码)
    本系统(程序+源码)带文档lw万字以上  文末可获取本课题的源码和程序系统程序文件列表系统的选题背景和意义选题背景:随着信息技术的飞速发展,互联网已经深入到我们生活的每一个角落。教育领域也不例外,越来越多的学校开始利用网络技术进行教学管理。其中,学生成绩查询系统是一......
  • Node.js毕业设计基于Web的选课系统(Express+附源码)
    本系统(程序+源码)带文档lw万字以上  文末可获取本课题的源码和程序系统程序文件列表系统的选题背景和意义选题背景:在当今信息化社会,教育行业也在不断地进行数字化改革。其中,选课系统作为学校教学管理的重要组成部分,其效率和准确性直接影响到学生的学习体验和教学质量。传......