首页 > 其他分享 >three.js基础

three.js基础

时间:2024-04-05 14:47:31浏览次数:23  
标签:scene const 30 基础 THREE three mesh new js

记录下three.js的学习历程。

three.js基本概念包括画布Canvas、渲染器Renderer、场景Scene、相机Camera、光源Light、几何体Geometry、材质Material、颜色纹理、点模型、线模型、网格模型、阴影、外部三维模型、动画等 

基础

<canvas id="basic"></canvas>

<script type="importmap">
  {
    "imports": {
      "three": "./js/build/three.module.js",
      "three/jsm/": "./js/jsm/"
    }
  }
</script>
<script type="module">
  import * as THREE from "three";

  {
    //渲染器
    const domId = document.getElementById("basic");
    const width = 300;
    const height = 200;
    const renderer = new THREE.WebGLRenderer({
      canvas: document.getElementById("basic"),
      antialias: true, //抗锯齿,平滑
    });
    renderer.setSize(width, height); //设置渲染区域的尺寸(像素px)
    renderer.setClearColor(0x000000, 1); //设置背景颜色
    renderer.setPixelRatio(window.devicePixelRatio); //设置设备像素比,以免渲染模糊问题

    //场景
    const scene = new THREE.Scene();

    //几何体
    const geometry = new THREE.BufferGeometry(); //空的几何体
    //顶点数据
    const vertices = new Float32Array([0, 0, 0, 30, 0, 0, 30, 30, 0, 0, 30, 0]);
    // 设置几何体的顶点位置,3个数据为1组,表示定点的xyz坐标
    geometry.attributes.position = new THREE.BufferAttribute(vertices, 3);
    // 点材质
    const pointMaterial = new THREE.PointsMaterial({
      color: 0xffff00,
      size: 10.0, //点对象像素尺寸
    });
    //点模型对象
    const points = new THREE.Points(geometry, pointMaterial);
    points.position.set(10, 10, 0);
    scene.add(points);

    // 线材质对象
    const lineMaterial = new THREE.LineBasicMaterial({
      color: 0xff0000, //线条颜色
    });
    // 创建线模型对象
    const line = new THREE.LineLoop(geometry, lineMaterial);
    line.position.set(50, 10, 0);
    scene.add(line);

    //网格材质:默认正面可见,反面不可见。
    const meshMaterial = new THREE.MeshBasicMaterial({
      color: 0xffffff,
      // side: THREE.FrontSide, //默认只有正面可见
      side: THREE.DoubleSide, //两面可见
      // side: THREE.BackSide,  //设置只有反面可见
    });
    const geometry1 = new THREE.BufferGeometry();
    const vertices1 = new Float32Array([0, 0, 0, 30, 0, 0, 30, 30, 0, 0, 0, 0, 30, 30, 0, 0, 30, 0]);
    geometry1.attributes.position = new THREE.BufferAttribute(vertices1, 3);
    //网格模型:由多个三角形的面拼接构成。正反面区分:依相机观察方向的三个点顺序逆时针为正面,顺时针为反面
    const mesh = new THREE.Mesh(geometry1, meshMaterial);
    mesh.position.set(90, 10, 0);
    mesh.rotateX(Math.PI); // 网格模型绕着x轴旋转
    mesh.translateY(30); //网格模型沿着y轴正方向平移
    mesh.scale.set(2, 2, 2); //网格模型缩放
    console.log("模型位置", mesh.position);
    scene.add(mesh);

    //网格材质:默认正面可见,反面不可见。
    const meshMaterial2 = new THREE.MeshBasicMaterial({
      color: 0xffffff,
      side: THREE.DoubleSide,
      wireframe: true, //线条模式渲染
    });
    const geometry2 = new THREE.BufferGeometry();
    const vertices2 = new Float32Array([0, 0, 0, 30, 0, 0, 30, 30, 0, 0, 0, 0, 30, 30, 0, 0, 30, 0]);
    geometry2.attributes.position = new THREE.BufferAttribute(vertices2, 3);
    geometry2.scale(1, 2, 2); // 几何体缩放
    geometry2.translate(30, 30, 0); // 几何体平移
    geometry2.rotateX(Math.PI); // 几何体绕着x轴旋转
    console.log("顶点位置数据", geometry2.attributes.position);
    const mesh2 = new THREE.Mesh(geometry2, meshMaterial2);
    mesh2.position.set(140, 10, 0);
    scene.add(mesh2);

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

    //坐标轴辅助
    const axesHelper = new THREE.AxesHelper(150);
    scene.add(axesHelper);

    console.log("scene的子对象", scene.children);
    renderer.render(scene, camera);

    window.onresize = function () {
      const width = 400; //若需全屏使用window.innerWidth
      const height = 300; //若需全屏使用window.innerHeight
      // 重置渲染器输出画布canvas尺寸
      renderer.setSize(width, height);

      //画布宽高比变化后更新透视投影相机PerspectiveCamera的aspect属性
      camera.aspect = width / height;
      camera.updateProjectionMatrix();
    };
  }

</script>

Group

<canvas id="group"></canvas>
<script type="importmap">
  {
    "imports": {
      "three": "./js/build/three.module.js",
      "three/jsm/": "./js/jsm/"
    }
  }
</script>
<script type="module">
  import * as THREE from "three";

  {
    const domId = document.getElementById("group");
    const width = 300;
    const height = 200;
    const renderer = new THREE.WebGLRenderer({
      canvas: document.getElementById("group"),
      antialias: true, //抗锯齿,平滑
    });
    renderer.setSize(width, height);
    renderer.setClearColor(0x000000, 1);
    renderer.setPixelRatio(window.devicePixelRatio);

    const scene = new THREE.Scene();

    const material = new THREE.MeshBasicMaterial({
      color: 0xffffff,
      side: THREE.DoubleSide, //两面可见
    });
    const geometry = new THREE.BufferGeometry();
    const vertices = new Float32Array([0, 0, 0, 30, 0, 0, 30, 30, 0, 0, 0, 0, 30, 30, 0, 0, 30, 0]);
    geometry.attributes.position = new THREE.BufferAttribute(vertices, 3);
    const mesh = new THREE.Mesh(geometry, material);
    mesh.position.set(10, 10, 0);
    const axis = new THREE.Vector3(1, 0, 0); //向量axis
    mesh.translateOnAxis(axis, 20); //沿着axis轴表示方向平移
    mesh.rotateOnAxis(axis, Math.PI / 2); //绕axis轴旋转
    mesh.scale.set(0.5, 0.5, 0.5);

    scene.add(mesh);

    //对象clone
    const mesh1 = mesh.clone();
    //材质clone
    mesh1.material = mesh.material.clone();
    mesh1.material.color.set(0x00ff00);
    mesh1.position.set(0, 50, 0);
    // 模型命名
    mesh1.name = "test";

    const mesh2 = mesh.clone();
    mesh2.material = mesh.material.clone();
    mesh2.material.color.set(0x00ffff);
    mesh2.position.set(50, 50, 0);

    //组
    const group = new THREE.Group();
    group.add(mesh1, mesh2);
    group.position.set(0, 90, 0);
    group.rotateX(Math.PI / 2);
    // 递归遍历group包含所有的对象
    group.traverse(function (obj) {
      // obj.isMesh:判断模型对象obj是不是网格模型'Mesh',等同于obj.type === 'Mesh'
      if (obj.isMesh) {
        obj.material.color.set(0xffff00);
        obj.material.visible = true;
        obj.visible = true;
      }
    });
    console.log("group的子对象", group.children);
    scene.add(group);

    // 对象移除
    // group.remove(mesh1);
    // scene.remove(mesh);

    // 根据name查找对象节点
    const nameNode = scene.getObjectByName("test");
    nameNode.material.color.set(0xff0000);
    const worldPosition = new THREE.Vector3();
    nameNode.getWorldPosition(worldPosition);
    //世界坐标-子对象的坐标叠加所有父对象的坐标
    console.log("世界坐标", worldPosition);
    //本地坐标-子对象相对于父对象的坐标
    console.log("本地坐标", nameNode.position);
    //可视化mesh的局部坐标系
    const meshAxesHelper = new THREE.AxesHelper(50);
    nameNode.add(meshAxesHelper);

    const camera = new THREE.PerspectiveCamera(30, width / height, 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,30,基础,THREE,three,mesh,new,js
From: https://www.cnblogs.com/caroline2016/p/18115739

相关文章

  • 二叉树计算【华为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为了便于同组学生交流,老师决定将小组成员安排到一起,也就是同组成员彼此相连,同组任意两个成员输入描述:之间无其它组的成员。因此老师决定调整队伍,......
  • MATLAB | 基础知识
    专题一:MATLAB数值数据1.数值数据类型的分类(1)整型: 无符号整数:无符号8位整数,无符号16位整数,无符号32位整数,无符号64位整数 带符号整数:带符号8位整数,带符号16位整数,带符号32位整数,带符号64位整数无符号8位整数数据范围:00000000~11111111(0~2^8-1)带符号8位整数数据范......
  • 代码随想录算法训练营第二十四天 二十五 | 回溯的理论基础,77. 组合 216. 组合总和 II
    77.组合https://leetcode.cn/problems/combinations/description/List<List<Integer>>res=newArrayList<>();List<Integer>path=newArrayList<>();publicList<List<Integer>>combine(intn,intk){......
  • `.gitattributes` 文件中的 *.js linguist-language=ts *.tsx linguist-language=ts
    .jslinguist-language=ts和.tsxlinguist-language=ts是针对特定文件类型的元数据标记,它们的作用是在特定的上下文中指示这些文件的实际编程语言类型,而非其扩展名所暗示的语言。具体来说:.jslinguist-language=ts表示尽管文件以.js扩展名结尾,但实际上它应该被视为TypeScr......
  • Python企业面试题2 —— 基础篇
    1.re的match和search区别?re.match尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。re.search扫描整个字符串并返回第一个匹配成功的值。2.什么是正则的贪婪匹配?匹配一个字符串没有节制,能匹配多少就去匹配多少,直到没有匹配的为止。......
  • 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是一款办公软件,由中国万户网络科技有限公司开发和提供。该软件提供了一系列办公管理工具,包括......
  • Java基础_运算符和分支结构
    今天的内容1.运算符2.分支结构if-else1.运算符1.算术运算符2.关系运算符3.逻辑运算符1.1算术运算符自增和自减​目的:让变量自身加一或者减一语法格式:变量++;先执行当前的操作,然后自身再加1++变量;变量--;--变量;packagecom.qf.a_test;public......
  • Linux基础
    1.请写出配置网卡信息的命令(2个) nmtui[root@yq~]#vi/etc/sysconfig/network-scripts/ifcfg-ens33 2./boot分区:存放系统启动文件500M~1024Mswap分区:虚拟内存分区真实内存的1-2倍,封顶8G/分区:存储系统和用户数据剩下的都给/ 3.请在虚拟机中创建一个名字为oldbo......