• ThreeJS-3D教学二基础形状展示


    请特别注意以下内容:
    自Three r125以来,所有内置几何图形现在都仅从Three.BufferGeometry派生。BufferGeometry是表示网格的一种更有效的方式,因为它将数据存储为类型化数组。经典的THREE.Geometry将其数据存储为THREE.Vector3和THREE.Color对象的数组。经典的THREE.Geometry从人类的角度阅读和编辑更直观,但在Threejs核心的WebGL着色器代码中处理速度较慢。请注意,在Threejs的未来版本中,THREE.BufferGeometry可能会重命名为THREE.Geometry。
    上面的内容很重要,新版本中类似BoxBufferGeometry的写法会直接报错。

    three中提供了22 个基础模型,此案例除了 EdgesGeometry、ExtrudeGeometry、TextGeometry、WireframeGeometry,涵盖 17 个形状。

     Fog  雾化设置,这是scene场景效果
     
     EdgesGeometry , WireframeGeometry 更多地可能作为辅助功能去查看几何体的边和线框
     
     ExtrudeGeometry 则是将一个二维图形沿 z 轴拉伸出一个三维图形
     
     TextGeometry 则需要从外部加载特定格式的字体文件(可在 typeface.js_three 网站上进行转换)进行渲染,其内部依然使用 ExtrudeGeometry 对字体进行拉伸,从而形成三维字体。另外,该类字体的本质是一系列类似SVG 的指令。所以,字体越简单(如直线越多),就越容易被正确渲染。
    
     planeGeometry  底层
      
     BoxGeometry(长方体)
     
     CircleGeometry(圆形)
     
     ConeGeometry(圆锥体)
     
     CylinderGeometry(圆柱体)
     
     DodecahedronGeometry(十二面体)
     
     IcosahedronGeometry(二十面体)
    
     LatheGeometry(让任意曲线绕 y 轴旋转生成一个形状,如花瓶)
     
     OctahedronGeometry(八面体)
    
     ParametricGeometry(根据参数生成形状)
     
     PolyhedronGeometry(多面体)
    
     RingGeometry(环形)
     
     ShapeGeometry(二维形状)
    
     SphereGeometry(球体)
    
     TetrahedronGeometry(四面体)
     
     TorusGeometry(圆环体)
     
     TorusKnotGeometry(换面纽结体)
     
     TubeGeometry(管道)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    我们先看下效果图
    在这里插入图片描述
    看代码

    
    
    
      
      Title
      
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331

    直接复制粘贴到html文件即可看到效果,当然前提是已经提前下载了three的代码库,然后在script type="importmap"标签中改下路径就可以了。
    到这一步,我们开始往场景 scene 中添加模型,也就是mesh,案例中用到了 SceneUtils.js 中的createMultiMaterialObject 创建 mesh,这个在官网中用法是这样的:
    在这里插入图片描述
    我们发现按官网看调用应该是SceneUtils.createMultiMaterialObject,但是这样会报错,我们看three 155版本中发现源码为:
    在这里插入图片描述
    看来新的版本已经更简洁了直接使用createMultiMaterialObject即可
    从这个解错的过程中,我们可以总结一些规律,当我们发现有时官网提供的方法也会报错,解错思路是什么呢?
    1、百度查问题,事实我也是这么做的,但由于这是最新版本,查询的结果大家也是推荐的官网用法,一通折腾没结果,这也是使用最新版本可能出现的一些无法预知的问题
    2、这时大家可以调转思路,为什么不看一眼源码,虽然大部分源码晦涩难懂,多层嵌套,比较难发现问题,本身我也不喜欢读源码,但结果是看完源码几秒钟这个问题就解决了,所以当我们遇到问题,第一步不一定要百度,看一眼源码也是很好的

    因为要写案例,在这个过程中遇到了一些问题,我就把解决问题的思路写下来分享给大家,我想这远比教会大家怎么实现效果更有助于大家成长。

    回到主题我们在讲createMultiMaterialObject做了什么时,先看下一般情况下mesh是怎么做的,在代码中有一个addPlane函数:

      // 创建一个平面  PlaneGeometry(width, height, widthSegments, heightSegments)
      const planeGeometry = new THREE.PlaneGeometry(120, 140, 1, 1);
      // 创建 Lambert 材质:会对场景中的光源作出反应,但表现为暗淡,而不光亮。
      const planeMaterial = new THREE.MeshLambertMaterial({
        color: 0xffffff
      });
      // 这里new THREE.Mesh 大部分情况我们都是这样做的
      const plane = new THREE.Mesh(planeGeometry, planeMaterial);
      // 以自身中心为旋转轴,绕 x 轴顺时针旋转 45 度
      plane.rotation.x = -0.5 * Math.PI;
      plane.position.set(0, -4, 0);
      scene.add(plane);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    Mesh

    表示基于三角形多边形网格的对象的类。还可以作为其他类(如SkinnedMesh)的基础。

    很显然PlaneGeometry 和 MeshLambertMaterial大家可能是第一次见到

    Geometry

    对原生WebGL中的顶点位置position、顶点法向量normal、顶点颜色color、顶点纹理坐标uv、顶点索引index等顶点数据进行了封装
    立方体BoxGeometry、圆柱体CylinderGeometry、球体SphereGeometry等Three.js几何体类都是基于基类BufferGeometry二次封装

    Materials

    材质就像对象的蒙皮。它定义了几何图形的外观。Three.js提供了许多工作材料。我们应该根据我们的需要选择材料的类型。

    Three.js中最常用的材料:

    1、MeshBasicMateria
    Three.js中非常基本的材料

    2、MeshDepthMaterial
    它使用与摄影机的距离来确定如何以灰度为网格着色

    3、MeshNormalMaterial
    此材质使用面法线向量的x/y/z值的大小来计算和设置面上显示的颜色的红/绿/蓝值

    4、MeshLambertMaterial
    您可以使用此材质创建外观暗淡、无光泽的表面

    5、MeshPhongMaterial
    此材质类似于MeshLambertMaterial,但可以创建更有光泽的曲面

    6、MeshStandardMaterial
    它与MeshLambertMaterial或MeshPhongMaterial类似,但提供了更准确、更逼真的外观结果。它有两个特性:粗糙度和金属性,而不是光泽

    7、MeshPhysicalMaterial
    它与MeshStandardMaterial非常相似。可以控制材质的反射率

    以上介绍了const plane = new THREE.Mesh(planeGeometry, planeMaterial);各个部分的大概定义,
    所以可以看到一个立方体就是由geometry(什么形状)、materia(什么样子),代入到Mesh中实现。
    后面对各个材质大部分都会用到,具体的后面再说,想了解更深入些,大家可以用这个例子根据官方文档依次使用下,想学会这点主观能动性还是要有的

    createMultiMaterialObject再看这个就按理解了,官方定义是
    为材质中定义的每个材质创建一个包含新网格的新组。请注意,这与为1个网格定义多个材质的材质数组不同。这对于同时需要材质和线框实现的对象非常有用。其实就是可以实现一个模型同时具有两种材质的效果。

  • 相关阅读:
    STM32中I2C通信的完整C语言代码范例
    【SpringBoot】请求与响应参数 IoC与DI 总结
    React16、18 使用 Redux
    CSS 预处理器的 13 种风格
    Python卡方分布
    掌握这3点,企业就能规避收款业务中的合规风险
    Java 序列化和反序列化,为什么要实现Serializable?
    IDEA 报错:Process terminated【已解决】
    95.(cesium之家)cesium动态单体化-3D建筑物(楼栋)
    Nginx 面试题 40 问
  • 原文地址:https://blog.csdn.net/weixin_44384273/article/details/133071271