• Threejs 3D模型入门项目


    先看效果:

    threejs还不熟悉的小伙伴可以先这篇文章:Threejs入门教程_程序猿青石的博客-CSDN博客

    1.基本设置

    1.初始化场景,相机

    1. import * as THREE from "three";
    2. // 初始化场景
    3. const scene = new THREE.Scene();
    4. // 初始化相机
    5. const camera = new THREE.PerspectiveCamera(
    6. 75,
    7. window.innerWidth / window.innerHeight,
    8. 0.1,
    9. 2000
    10. );
    11. // // 设置相机位置
    12. camera.position.set(-50, 50, 130);
    13. scene.add(camera);

    2.初始化渲染器

    1. // 初始化渲染器
    2. const renderer = new THREE.WebGLRenderer();
    3. // 设置渲染器宽高
    4. renderer.setSize(window.innerWidth, window.innerHeight);
    5. // 将渲染器添加到页面
    6. document.body.appendChild(renderer.domElement);
    7. // 实例化控制器
    8. const controls = new OrbitControls(camera, renderer.domElement);

    3.添加轨道控制器并循环渲染图画

    1. // 导入控制器
    2. import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
    3. // 实例化控制器
    4. const controls = new OrbitControls(camera, renderer.domElement);
    5. function render() {
    6. // 渲染场景
    7. renderer.render(scene, camera);
    8. // 引擎自动更新渲染器
    9. requestAnimationFrame(render);
    10. }
    11. render();

    4.监听窗口并实现画布自适应

    1. // 监听屏幕的大小改变,修改渲染器的宽高,相机的比例
    2. window.addEventListener("resize", () => {
    3. camera.aspect = window.innerWidth / window.innerHeight;
    4. // 修改属性后需要刷新来使改变生效
    5. camera.updateProjectionMatrix();
    6. renderer.setSize(window.innerWidth, window.innerHeight);
    7. });

    2.要点步骤

    1.为场景添加平行光

    平行光是沿着特定方向发射的光。这种光的表现像是无限远,从它发出的光线都是平行的。常常用平行光来模拟太阳光 的效果; 太阳足够远,因此我们可以认为太阳的位置是无限远,所以我们认为从太阳发出的光线也都是平行的。

    构造函数:

    DirectionalLight( color : Integer, intensity : Float )

    color - (可选参数) 16进制表示光的颜色。 缺省值为 0xffffff (白色)。
    intensity - (可选参数) 光照的强度。缺省值为1。

    1. const light = new THREE.DirectionalLight(0xffffff, 1);
    2. light.position.set(-100, 100, 10);
    3. scene.add(light);

    2.为背景添加天空球体 

    TextureLoader

    加载texture的一个类。 内部使用ImageLoader来加载文件。

    .load ( url : String, onLoad : Function, onProgress : Function, onError : Function ) : Texture

    url — 文件的URL或者路径,也可以为 Data URI.
    onLoad — 加载完成时将调用。回调参数为将要加载的texture.
    onProgress — 将在加载过程中进行调用。参数为XMLHttpRequest实例,实例包含total和loaded字节。
    onError — 在加载错误时被调用。

    注意:此处的url的默认目录当前目录是项目打包生成的dist文件夹,所有资源文件均需放置到此文件夹下方可访问

    .map : Texture

    颜色贴图。可以选择包括一个alpha通道,通常与.transparent 或.alphaTest。默认为null。

    .scale ( x : Float, y : Float, z : Float ) : this

    缩放几何体。该操作一般在一次处理中完成,不会循环处理。典型的用法是通过调用 Object3D.scale 实时旋转几何体。

    1. // 创建一个巨大的天空球体
    2. let texture = new THREE.TextureLoader().load("./textures/water/sky.jpg");
    3. const skyGeometry = new THREE.SphereGeometry(1000, 60, 60);
    4. const skyMaterial = new THREE.MeshBasicMaterial({
    5. map: texture,
    6. });
    7. skyGeometry.scale(1, 1, -1);
    8. const sky = new THREE.Mesh(skyGeometry, skyMaterial);
    9. scene.add(sky);

    3.添加视频纹理

    VideoTexture

    创建一个使用视频来作为贴图的纹理对象。
    它和其基类Texture几乎是相同的,除了它总是将needsUpdate设置为true,以便使得贴图能够在视频播放时进行更新。自动创建mipmaps也会被禁用。

    1. // 视频纹理
    2. const video = document.createElement("video");
    3. video.src = "./textures/sky.mp4";
    4. video.loop = true;
    5. window.addEventListener("click", (e) => {
    6. // 当鼠标移动的时候播放视频
    7. // 判断视频是否处于播放状态
    8. if (video.paused) {
    9. video.play();
    10. let texture = new THREE.VideoTexture(video);
    11. skyMaterial.map = texture;
    12. skyMaterial.map.needsUpdate = true;
    13. }
    14. });

    4.创建水面

    CircleGeometry是欧式几何的一个简单形状,它由围绕着一个中心点的三角分段的数量所构造,由给定的半径来延展。 同时它也可以用于创建规则多边形,其分段数量取决于该规则多边形的边数。

    CircleGeometry(radius : Float, segments : Integer, thetaStart : Float, thetaLength : Float)

    radius — 圆形的半径,默认值为1
    segments — 分段(三角面)的数量,最小值为3,默认值为8。
    thetaStart — 第一个分段的起始角度,默认为0。(three o'clock position)
    thetaLength — 圆形扇区的中心角,通常被称为“θ”(西塔)。默认值是2*Pi,这使其成为一个完整的圆。

    1. // 导入水面
    2. import { Water } from "three/examples/jsm/objects/Water2";
    3. // 创建水面
    4. const waterGeometry = new THREE.CircleBufferGeometry(300, 64);
    5. const water = new Water(waterGeometry);
    6. water.position.y = -80;
    7. // 水面旋转至水平
    8. water.rotation.x = -Math.PI / 2;
    9. scene.add(water);

    5.导入实例模型

    draco

    draco是谷歌出的一款模型压缩工具,可将gltf格式的模型进行进一步压缩提高页面加载速的一种方法 

    github官网:https://github.com/google/draco

    下载后将javascript文件夹复制到本项目dist目录下

    sketchfab(3d模型网站)

    Explore 3D Models - Sketchfab

    同样下载的模型也需要放置到dist目录下,我的模型在model文件夹下

    1. // 导入gltf载入库
    2. import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
    3. import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
    4. // 添加小狗模型
    5. // 实例化gltf载入库
    6. const loader = new GLTFLoader();
    7. // 实例化draco载入库
    8. const dracoLoader = new DRACOLoader();
    9. // 添加draco载入库
    10. dracoLoader.setDecoderPath("./javascript/");
    11. // 添加draco载入库
    12. loader.setDRACOLoader(dracoLoader);
    13. loader.load("./model/shiba.glb", (gltf) => {
    14. gltf.scene.scale.set(100,100,100)
    15. scene.add(gltf.scene);
    16. });

    package.json

    1. {
    2. "name": "ch02",
    3. "version": "1.0.0",
    4. "description": "",
    5. "main": "index.js",
    6. "scripts": {
    7. "dev": "parcel src/index.html",
    8. "build": "parcel build src/index.html"
    9. },
    10. "author": "",
    11. "license": "ISC",
    12. "devDependencies": {
    13. "parcel": "^2.4.1"
    14. },
    15. "dependencies": {
    16. "dat.gui": "^0.7.9",
    17. "gsap": "^3.10.3",
    18. "three": "^0.139.2"
    19. }
    20. }

    参考视频:手把手教你用three.js开发水天一色小岛_哔哩哔哩_bilibili

  • 相关阅读:
    Redis——》实现分布式锁
    云原生K8S------K8S管理工具kubectl详解(一)
    自动驾驶---Perception之视觉点云&雷达点云
    Linux -- 面试考点要点,笔试不多
    聊聊spring的UnexpectedRollbackException
    如何找到并快速上手一个开源项目
    docker 网络简介
    picGo图床搭建gitee和smms(建议使用)
    RHCE-day1
    一文整明白Researcher ID与ORCID
  • 原文地址:https://blog.csdn.net/m0_63748493/article/details/127603376