• 老陈打码老陈打码


    均匀旋转

    let T0 = new Date();//上次时间
    function render() {
            let T1 = new Date();//本次时间
            let t = T1-T0;//时间差
            T0 = T1;//把本次时间赋值给上次时间
            requestAnimationFrame(render);
            renderer.render(scene,camera);//执行渲染操作
            mesh.rotateY(0.001*t);//旋转角速度0.001弧度每毫秒
        }
    render();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    光照计算算法

    平行光漫反射简单数学模型:漫反射光的颜色 = 网格模型材质颜色值 x 光线颜色 x 光线入射角余弦值
    漫反射数学模型RGB分量表示:(R2,G2,B2) = (R1,G1,B1) x (R0,G0,B0) x cosθ
    
    • 1
    • 2

    光照阴影(3步)

    • 一个是设置产生投影的模型对象 mesh.castShadow = true;
    • 一个是设置接收投影效果的模型 planeMesh.receiveShadow = true;
    • 最后一个是光源对象本身的设置,光源如何产生投影 directionalLight.castShadow = true;

    几何体本质上就是threejs生成顶点的算法

    曲线和几何体同样本质上都是用来生成顶点的算法,曲线主要是按照一定的规则生成一系列沿着某条轨迹线分布的顶点。
    
    • 1

    外部添加贴图

    
    var geometry = new THREE.PlaneGeometry(204, 102); //矩形平面
    var textureLoader = new THREE.TextureLoader();
    textureLoader.load('Earth.png', function(texture) {
      var material = new THREE.MeshLambertMaterial({
        map: texture,
      }); 
      var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
      scene.add(mesh); //网格模型添加到场景中
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    纹理坐标UV

    纹理UV坐标和顶点位置坐标是一一对应关系,这也就是为什么一张图片可以映射到一个模型的表面,
    只要把图片的每个纹理坐标和模型的顶点位置建立一对一的关系,就可以实现图像到模型的映射。
    
    • 1
    • 2

    纹理贴图

    纹理贴图方法

    阵列、偏移、旋转

    /**
     * 创建一个地面
     */
    var geometry = new THREE.PlaneGeometry(1000, 1000); //矩形平面
    // 加载树纹理贴图
    var texture = new THREE.TextureLoader().load("grass.jpg");
    // 设置阵列
    texture.wrapS = THREE.RepeatWrapping;
    texture.wrapT = THREE.RepeatWrapping;
    // uv两个方向纹理重复数量
    texture.repeat.set(10, 10);
    var material = new THREE.MeshLambertMaterial({
      map: texture,
    });
    var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
    scene.add(mesh); //网格模型添加到场景中
    mesh.rotateX(-Math.PI / 2);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    纹理贴图动画

    在渲染函数中render()一直执行texture.offset.x -= 0.06动态改变纹理对象Texture的偏移属性.offset就可以。
    在这里插入图片描述

    凹凸贴图和法线贴图

    凹凸贴图和法线贴图功能相似,只是没有法线贴图表达的几何体表面信息更丰富。
    凹凸贴图是用图片像素的灰度值表示几何表面的高低深度,如果模型定义了法线贴图,就没有必要在使用凹凸贴图。
    
    • 1
    • 2

    阴影贴图

    一般几何体有两套UV坐标,对于Geometry类型集合体来说、第一套UV坐标用来展示颜色贴图map、法线贴图normalMap等,第二套纹理贴图用于阴影贴图。

    一般通过Threejs几何体API创建的几何体默认只有一组纹理坐标Geometry.faceVertexUvs[0],所以为了设置光照阴影贴图,需要给另一组纹理坐标赋值Geometry.faceVertexUvs[1] = Geometry.faceVertexUvs[0];

    高光贴图 specularMap

    环境贴图 envMap

    高光网格材质MeshPhongMaterial和物理PBR材质MeshStandardMaterial通常会使用环境贴图.envMap来实现更好的渲染效果

    相机对象 Camera

    所谓相机对象Camera本质上就是视图矩阵.matrixWorldInverse和投影矩阵.projectionMatrix,Threejs渲染场景的时候调用相机对象的视图矩阵和投影矩阵值对顶点进行矩阵变换。

    关键帧动画

    比如一个机械的装配过程,一个车门开关的动作,一个物体的移动动画。

    自定义动画

    1. 创建关键帧动画 KeyframeTrack(可以有多个)
    2. 剪辑合并多个关键帧动画 AnimationClip( [ track1, track2 ] )
    3. 把模型和动画混合
    4. 播放

    模型生成动画

    1. 把模型和动画混合
    2. 播放
    // 通过ObjectLoader加载模型文件model.json
    var loader = new THREE.ObjectLoader();
    var mixer = null; //声明一个混合器变量
    // 加载文件返回一个对象obj
    loader.load("model.json", function(obj) {
      obj.scale.set(15, 15, 15);//缩放加载的模型
      scene.add(obj);
      // obj作为混合器的参数,可以播放obj包含的帧动画数据
      mixer = new THREE.AnimationMixer(obj);
      // obj.animations[0]:获得剪辑clip对象
      // // 剪辑clip作为参数,通过混合器clipAction方法返回一个操作对象AnimationAction
      var AnimationAction = mixer.clipAction(obj.animations[0]);
      AnimationAction.play();
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    骨骼动画

    本质上就是模拟人体的骨骼运行机制、

    音频

    非位置音频

    非位置音频THREE.Audio加载一段音频进行进行播放,该音频播放效果不受具体位置影响,一般可以用于一个三维场景的背景音乐

    位置音频

    在实际生活中,听到声音的效果,受音源相对监听者的位置和角度影响。音频源位置发生变化,听到的声音有所变化,比如音量大小

    模型文件加载

    加载器本质上都是解析模型文件的字符串,通过正则表达式提取相关的顶点、材质等信息转化为Threejs自身的类表示的对象

    模型加载完成后的一些常用操作

    // 加载后的一些编辑操作
    obj.children[0].scale.set(20,20,20);//网格模型缩放
    obj.children[0].geometry.center();//网格模型的几何体居中
    obj.children[0].material.color.set(0xff0000);//设置材质颜色
    
    • 1
    • 2
    • 3
    • 4

    STL格式

    .stl格式的三维模型不包含材质Material信息,只包含几何体顶点数据的信息,你可以简单地把stl文件理解为几何体对象Geometry

    obj模型文件

    使用三维软件导出.obj模型文件的时候,会同时导出一个材质文件.mtl, .obj和.stl文件包含的信息一样都是几何体顶点相关数据,材质文件.mtl包含的是模型的材质信息,比如颜色、贴图路径等。

    var OBJLoader = new THREE.OBJLoader();//obj加载器
    var MTLLoader = new THREE.MTLLoader();//材质文件加载器
    MTLLoader.load('./立方体/box.mtl', function(materials) {
      // 返回一个包含材质的对象MaterialCreator
      console.log(materials);
      //obj的模型会和MaterialCreator包含的材质对应起来
      OBJLoader.setMaterials(materials);
      OBJLoader.load('./立方体/box.obj', function(obj) {
        console.log(obj);
        obj.scale.set(10, 10, 10); //放大obj组对象
        scene.add(obj);//返回的组对象插入场景中
      })
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    导出.obj和.mtl的名称、路径问题
    3dmax导出的obj和mtl模型文件有时候需要修改一下个别位置字符,比如.obj中.mtl文件的名称可能是乱码mtllib �����.mtl,.mtl文件中贴图的路径要设置正确,比如导出的是绝对路径还是相对路径,可以打开看下。

    obj文件不包含信息
    .obj文件不包含场景的相机Camera、光源Light等信息,不能导出骨骼动画、变形动画,如果希望导出光照信息、相机信息、骨骼动画信息、变形动画信息,可以选择.fbx、.gltf等格式。

    FBX并解析骨骼动画

    FBX文件比较常用

    GLTF / GLB

    着色器

    着色器本质上就是就是一个函数(接收位置,返回颜色),编译的时候他会运行的非常快。这意味着超快的三角和矩阵运算 - 与电力一样快

  • 相关阅读:
    HarmonyOS NEXT应用开发—Grid和List内拖拽交换子组件位置
    webpack原理篇(五十二):webpack-cli源码阅读
    python库-dotenv包 | .env配置文件
    Makefile入门(三)
    三维模型3DTile格式轻量化压缩处理效率提高的技术方浅析
    [NCTF2019]True XML cookbook
    接口测试中Groovy引擎的接入实现
    jquery之Dom操作
    15:00面试,15:06就出来了,问的问题有点变态。。。
    [动态规划] (十) 路径问题 LeetCode 174.地下城游戏
  • 原文地址:https://blog.csdn.net/Yun__shen/article/details/126489528