赞
踩
three.js提供了一个THREE.Materail 材质的抽象基类,所有其他材质类型都继承了以下属性和方法:
id(标识符):此材质实例的唯一编号,并在材质创建时赋值。第一个材质的值从 0 开始,每新加一个材质,这个值就增加 1。
uuid(通用唯一识别码):这是生成的唯一 ID,在内部使用。
name(名称):可以通过这个属性赋予材质名称,用于调试的目的。
opacity(不透明度): 定义物体的透明度。与 transparent 属性一起使用。该属性的赋值范围从 0 到 1。
transparent(是否透明):定义此材质是否透明,可以通过opacity属性来控制透明程度。
默认值为false,所以如果需要做透明渲染效果,需要设置transparent设置为true。
如果使用 alpha(透明度)通道的纹理,该属性应该设置为 true。
overdraw(过度描绘):当你使用 THREE.CanvasRender 时,多边形会被渲染得稍微大一点。当使用这个渲染器渲染的物体有间隙时,可以将这个属性设置为 true。
visible(是否可见):定义该材质是否可见。默认为true,如果设置为 false,那么在场景中就看不到该物体。
side(侧面):通过这个属性,可以定义几何体的渲染哪一面。
默认值为 THREE.FrontSide(前面),定义将要渲染材质的前面(外侧)。
设置为 THREE.BackSide(后面),定义将要渲染材质的后面(内侧)。
设置为 THREE.DoubleSide(双侧),定义将要渲染材质的内外两侧。
needsUpdate(是否更新):对于材质的某些修改,需要告诉 Three.js 材质已经改变了。如果该属性设置为 true,Three.js会使用新的材质属性更新它的缓存。
在使用过程中需要注意的有一下三点:
(1)opacity和transparent需要一起搭配使用,在transparent为true时,opacity才会起作用,下面举例示范;
- // 创建材质
- let color = new THREE.Color(Math.random(), Math.random(), Math.random())
- // 未向材质中添加 transparent 属性
- const material = new THREE.MeshBasicMaterial({
- color: color,
- opacity: 0.5,
- })
- // 创建材质
- let color = new THREE.Color(Math.random(), Math.random(), Math.random())
- // 向材质中添加 transparent 属性
- const material = new THREE.MeshBasicMaterial({
- color: color,
- transparent: true,
- opacity: 0.5,
- })
(2)当材质的属性发生改变时,需要将needsUpdate(指定需要重新编译材质)设置为true,才能触发材质的渲染更新。
- window.addEventListener('click', e => {
- // 当鼠标移动的时候播放视频
- // 判断视频是否属于播放状态
- if (video.paused) {
- this.$nextTick(res => {
- video.load()
- video.play()
- })
- let texture = new THREE.VideoTexture(video)
- skyMaterial.map = texture
- skyMaterial.map.needsUpdate = true
- }
- })
(3)side 决定了绘制那个面,还是两个面都进行绘制
- material.side = THREE.DonbleSide
- // 或者
- const material = new THREE.MeshStandardMaterial({
- side: DonbleSide,
- })
blending(融合):该属性决定物体上的材质如何与背景融合。一般的融合模式是 THREE.NormalBlending,在这种模式下只显示材质的上层。
blendSrc(混合源):
除了使用标准融合模式之外,还可以通过设置 blendsrc、 blenddst 和 blendequation 来创建自定义的融合模式。
这个属性定义了该物体(源)如何与背景(目标)相融合。默认值为THREE.SrcAlphaFactor,即使用 alpha(透明度)通道进行融合。
blendDst(混合目标): 这个属性定义了融合时如何使用背景(目标),默认值为 THREE.OneMinusSrcAlphaFactor,其含义是目标也使用源的 alpha 通道进行融合,只是使用的值是 1(源的 alpha 通道值),必须将材质的blending设置为CustomBlending才能生效。
blendEquation(融合公式):定义了如何使用 blendsrc 和 blenddst 的值。默认值为使它们相加(AddEquation)。通过使用这三个属性,可以创建自定义的融合模式。
depthTest / depthWrite:绘制不透明物体时,深度测试开启是能保证正确的遮挡关系,绘制透明物体时,关掉深度测试能保证正确的blend。
polygonOffset / polygonOffsetFactor / polygonOffsetUnits
alphatest:如果某个像素小于这个值,则不会显示。
定义:MeshBasicMaterial是一种比较简单的材质
特点:这种材质不受光照的影响,不考虑光照的影响,可以渲染基础的平面或者几何体。
color(颜色):材质的颜色,默认值为白色 (0xffffff)。可以通过this.cube.material.color.set(value)改变材质颜色属性
xxxMap(纹理贴图):demo10
wireframe(线框):默认值为false(即渲染为平面多边形), 设置这个属性可以将材质渲染成线框。
wireframeLinewidth(线框线宽):如果已经打开了 wireframe,这个属性定义线框中线的宽度。
wireframeLinecap(线框线段端点):定义线两端的外观
round(默认值):圆
square:方
butt:平
wireframeLinejoin(线框线段连接点):这个属性定义了线段的连接点如何显示。可选的值有:
round:圆(默认值)
bevel:斜角
miter:尖角
shading(着色): 该属性定义如何着色。可选的值有:
THREE.SmoothShading(默认值,这个将产生一个平滑的对象,看不到单个面)
THREE.NoShading
THREE.FlatShading
vertexColors(顶点颜色)
可以通过这个属性给每个顶点定义不同的颜色。默认值为:THREE.NoColors。如果将这个值设置为 THREE.VertexColors,渲染器会采用 THREE.Geometry 对象的 colors 属性的值。
该属性对 CanvasRenderer不起作用,但对 WebGLRender 起作用。比如我们可以使用该属性为线段的不同部分设置不同的颜色。也可以使用这个属性为这种材质类型创建渐变效果。
fog(雾化): 该属性指定当前材质是否受全局雾化效果设置的影响,默认为true。如果将该属性设置为 false,那么我们全局雾化效果设置就不会影响当前对象的渲染。
map:颜色贴图。
aoMap:该纹理的红色通道用作环境遮挡贴图,aoMap需要第二组UV。
envMap:环境贴图。
lightMap:光照贴图,lightMap需要第二组UV。
alphaMap:alpha贴图是一张灰度纹理,用于控制整个表面的不透明度。(黑色:完全透明;白色:完全不透明)。
specularMap:材质使用的高光贴图。
示例一:颜色纹理贴图
- // 导入纹理
- // TextureLoader创建一个纹理加载器对象,可以加载图片作为几何体纹理
- const textureLoader = new THREE.TextureLoader()
- // 执行load方法,加载纹理贴图成功后,返回一个纹理对象Texture
- const picTexture = textureLoader.load('./static/images/detail1.jpg')
-
- // 添加物体:纹理贴图映射到一个矩形平面上
- const cubeGeometry = new THREE.BoxBufferGeometry(1, 1, 1)
-
- // 设置材质
- const material = new THREE.MeshBasicMaterial({
- color: '#dda0dd',
- // 添加纹理贴图
- map: picTexture,
- transparent: true,
- opacity: 0.5,
- side: THREE.DoubleSide,
- })
- this.cube = new THREE.Mesh(cubeGeometry, material)
- // 将物体添加到场景中
- this.scene.add(this.cube)

实例二:基础示例
- // 添加物体
- // 创建几何体
- const geometry = new THREE.BoxGeometry(1, 1, 1)
- // 创建材质
- const material = new THREE.MeshBasicMaterial({ color: '#dda0dd' })
- // 根据几何体和材质创建物体
- this.cube = new THREE.Mesh(geometry, material)
- // 将几何体添加到场景中
- this.scene.add(this.cube)
-
- // 创建 GUI
- const gui = new dat.GUI()
- gui
- .add(this.cube.position, 'x')
- .min(0)
- .max(5)
- .step(0.01)
- .name('移动x轴')
- .onChange(value => {
- console.log('值被修改了')
- })
- .onFinishChange(value => {
- console.log('完全停下来')
- })
- // 修改物体的颜色
- const params = {
- color: '#dda0dd',
- fn: () => {
- // 让立方体运动起来
- gsap.to(this.cube.position, { x: 10, duration: 2, yoyo: true, repeat: -1 })
- },
- }
-
- // 设置选项框
- gui.add(this.cube, 'visible').name('是否显示')
- // 点击触发某个事件
- gui.add(params, 'fn').name('点击立方体运动')
- // 添加文件夹(折叠选项)
- let folder = gui.addFolder('设置立方体')
- folder.add(this.cube.material, 'wireframe')
- folder
- .addColor(params, 'color')
- .onChange(value => {
- this.cube.material.color.set(value)
- })
- .name('修改颜色')

一种按深度绘制几何体的材质。深度基于相机远近平面。白色最近,黑色最远。使用这种材质的物体,其外观不是由光照或者某个材质属性决定的,而是由物体到摄像机的距离决定的。我们可将这种材质与其他材质结合使用,从而很容易地创建出逐渐消失得效果。
- this.scene = new THREE.Scene()
- this.scene.overrideMaterial = new THREE.MeshDepthMaterial()
-
- // 环境光
- const ambientLight = new THREE.AmbientLight(0xffffff, 0.1) // 创建环境光
- this.scene.add(ambientLight) // 将环境光添加到场景
-
- addCube() {
- const cubeSize = Math.ceil(3 + Math.random() * 3)
- const cubeGeometry = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize)
-
- const cubeMaterial = new THREE.MeshLambertMaterial({
- color: 0xffffff,
- })
-
- this.cube = new THREE.Mesh(cubeGeometry, cubeMaterial)
-
- this.cube.castShadow = true
- this.cube.updateMatrix()
-
- // 设置方块位置
- this.cube.position.x = -50 + Math.round(Math.random() * 150)
- this.cube.position.y = Math.round(Math.random() * 10)
- this.cube.position.z = -150 + Math.round(Math.random() * 250)
-
- // 将方块添加到场景
- this.scene.add(this.cube)
- },
-
- // 更新属性
- updateFun() {
- this.camera.near = this.properties.near.value
- this.camera.far = this.properties.far.value
-
- this.camera.updateProjectionMatrix()
- const THIS = this
- THIS.scene.traverse(function (e) {
- if (e instanceof THREE.Mesh) {
- e.rotation.x += THIS.properties.speed.value
- e.rotation.y += THIS.properties.speed.value
- e.rotation.z += THIS.properties.speed.value
- }
- })
- },

由上图可以看出来,远近的明亮程度不一样,通过右上角gui相关数据调整相机的近面值及远面值。
这里要特别注意如下几个地方:
一种把法向量映射到RGB颜色的材质,使用这种材质,每一面的颜色是由从该面向外指的法向量计算得到的。
- // 创建法向量纹理
- var meshMaterial = new THREE.MeshNormalMaterial({
- flatShading: THREE.FlatShading,
- transparent: true,
- opacity: 0.7
- });
在此有两个比较重要的属性:ambient(环境色)和 emissive(发射的)
- // 创建网格模型
- const planeMaterial = new THREE.MeshLambertMaterial({
- color: 0x777777,
- }) // 材质对象Material
- const plane = new THREE.Mesh(geometry, planeMaterial)
- plane.receiveShadow = true
-
- // 设置平面位置
- plane.rotation.x = -0.5 * Math.PI
- plane.position.set(0, -20, 0)
-
- // 平面对象添加到场景中
- this.scene.add(plane)
-
- const sphereGeometry = new THREE.SphereGeometry(14, 20, 20)
- const cubeGeometry = new THREE.BoxGeometry(15, 15, 15)
- const planeGeometry = new THREE.PlaneGeometry(14, 14, 4, 4)
-
- // 创建材质
- this.meshMaterial = new THREE.MeshLambertMaterial({
- color: 0x7777ff,
- })
-
- // 创建球、方块、平面
- this.sphere = new THREE.Mesh(sphereGeometry, this.meshMaterial)
- this.cube = new THREE.Mesh(cubeGeometry, this.meshMaterial)
- this.plane = new THREE.Mesh(planeGeometry, this.meshMaterial)
-
- this.sphere.position.set(-12, 3, 2)
- this.cube.position = this.sphere.position
- this.plane.position = this.sphere.position
- this.activeMesh = this.sphere
-
- // 环境光
- const ambientLight = new THREE.AmbientLight(0xffffff, 0.1) // 创建环境光
- this.scene.add(ambientLight) // 将环境光添加到场景
-
- const spotLight = new THREE.SpotLight(0xffffff) // 创建聚光灯
- spotLight.position.set(-40, 60, -10)
- this.scene.add(spotLight)

通过 THREE.MeshPhongMaterial 可以创建一种具有镜面高光的光泽表面的材质。
为实例物体一个光源(环境光与点光源),并使用该材质创建一个小球。可以看到这个材质看上去比较光亮。
- // 创建球体
- const loader = new THREE.TextureLoader();
- const geometry = new THREE.SphereGeometry(50, 128, 128);
- // 定义地球材质
- const texture = loader.load('./static/images/earth_atmos_4096.jpg');
- // 添加浮雕凹凸贴图
- const bump = loader.load('./static/images/earth_bump.jpg');
- // 添加高光贴图
- const spec = loader.load('./static/images/earth_specular_2048.jpg');
- // 创建材质
- const material = new THREE.MeshPhongMaterial({
- map: texture,
- bumpMap: bump,
- bumpScale: 5,
- specularMap: spec,
- specular: new THREE.Color('#1a2948'),
- shininess: 2
- });
- const mesh = new THREE.Mesh(geometry, material);
- mesh.name = 'earth';
- // 添加地球到场景
- this.scene.add(mesh);
-
- // 添加光源
- const ambientLight = new THREE.AmbientLight(0x999999);
- const pointLight = new THREE.PointLight(0xffffff, 1, 200);
- pointLight.position.set(0, 100, 0);
- this.scene.add(ambientLight, pointLight);

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。