原文出自:www.hangge.com 转载请保留原文链接:http://www.hangge.com/blog/cache/detail_1816.html
原文出自:www.hangge.com 转载请保留原文链接:http://www.hangge.com/blog/cache/detail_1815.html
原文出自:www.hangge.com 转载请保留原文链接:http://www.hangge.com/blog/cache/detail_1819.html
原文出自:www.hangge.com 转载请保留原文链接:http://www.hangge.com/blog/cache/detail_1830.html
git项目示例源码地址: https://github.com/jdk137/learnThree.js
在线示例地址:
4. 3 材质结合: 基础材质 + 深度材质
4. 4 MeshNormalMaterial 网格法向材质
4. 6 MeshLambertMaterial 网格lambert材质
4. 7 MeshPhongMaterial 网格phong材质
4. 8 ShaderMaterial 着色器材质
4. 10 LineDashMaterial 虚线材质
我们知道一个材质结合 THREE.Geometry 对象,可以构成 THREE.Mesh 对象。材质就像物体的皮肤,决定了几何体的外表。例如皮肤定义了一个几何体看起来是否像金属、透明与否、或者显示为线框。
本文先简单介绍下 Three.js 里的各种材质,以及它们共有的一些属性。
Three.js - 材质的使用详解1(各种材质、及共有属性简介)
一、Three.js 库提供的所有材质
名称 | 描述 |
MeshBasicMaterial(网格基础材质) | 基础材质,用于给几何体赋予一种简单的颜色,或者显示几何体的线框。 |
MeshDepthMaterial(网格深度材质) | 这个材质使用从摄像机到网格的距离来决定如何给网格上色。 |
MeshNormalMaterial(网格法向材质) | 这是一种简单的材质,根据法向向量计算物体表面的颜色。 |
MeshFaceMaterial(网格面材质) | 这是一个容器,可以为几何体的各个表面指定不同的材质。 |
MeshLambertMaterial(网格 Lambert 材质) | 这是一种考虑光照影响的材质,用于创建暗淡的、不光亮的物体。 |
MeshPhongMaterial(网格 Phong 式材质) | 这是一种考虑光照影响的材质,用于创建光亮的物体。 |
ShaderMaterial(着色器材质) | 这种材质允许使用自定义的着色器程序,直接控制顶点的放置方式以及像素的着色方式。 |
LineBasicMaterial(直线基础材质) | 这种材质可以用于 THREE.Line(直线)几何体,用来创建着色的直线。 |
LineDashMaterial(虚线材质) | 这种材质与 LineBasicMaterial(直线基础材质)一样,但允许创建出一种虚线的效果。 |
二、材质的共有属性
Three.js 提供了一个材质基类 THREE.Material,它列出了所有的共有属性。这些共有属性可以分成三类。
1,基础属性
这些属性是最常用的。通过这些属性,可以控制物体的不透明度、是否可见以及如何被引用(通过 ID 或者自定义名称)。
名称 | 描述 |
id(标识符) | 用来识别材质,并在材质创建时赋值。第一个材质的值从 0 开始,每新加一个材质,这个值就增加 1。 |
uuid(通用唯一识别码) | 这是生成的唯一 ID,在内部使用。 |
name(名称) | 可以通过这个属性赋予材质名称,用于调试的目的。 |
opacity(不透明度) | 定义物体的透明度。与 transparent 属性一起使用。该属性的赋值范围从 0 到 1。 |
transparent(是否透明) |
|
overdraw(过度描绘) | 当你使用 THREE.CanvasRender 时,多边形会被渲染得稍微大一点。当使用这个渲染器渲染的物体有间隙时,可以将这个属性设置为 true。 |
visible(是否可见) | 定义该材质是否可见。如果设置为 false,那么在场景中就看不到该物体。 |
side(侧面) | 通过这个属性,可以定义几何体的哪一面应用材质。
|
needsUpdate(是否更新) | 对于材质的某些修改,你需要告诉 Three.js 材质已经改变了。如果该属性设置为 true,Three.js会使用新的材质属性更新它的缓存。 |
2,融合属性
每个物体都有一系列的融合属性。这些属性决定了物体如何与背景融合。
名称 | 描述 |
blending(融合) | 该属性决定物体上的材质如何与背景融合。一般的融合模式是 THREE.NormalBlending,在这种模式下只显示材质的上层。。 |
blendsrc(融合源) | 除了使用标准融合模式之外,还可以通过设置 blendsrc、 blenddst 和 blendequation 来创建自定义的融合模式。 这个属性定义了该物体(源)如何与背景(目标)相融合。默认值为 THREE.SrcAlphaFactor,即使用 alpha(透明度)通道进行融合。 |
blenddst(融合目标) | 这个属性定义了融合时如何使用背景(目标),默认值为 THREE.OneMinusSrcAlphaFactor,其含义是目标也使用源的 alpha 通道进行融合,只是使用的值是 1(源的 alpha 通道值)。 |
blendequation(融合公式) | 定义了如何使用 blendsrc 和 blenddst 的值。默认值为使它们相加(AddEquation)。通过使用这三个属性,可以创建自定义的融合模式。 |
3,高级属性
这些高级属性可以控制底层 WebGL 上下文对象渲染物体的方式。不过大多数情况下是不需要使用这些属性的。
名称 | 描述 |
depthTest | 这是一个高级 WebGL 属性。使用这个属性可以打开或关闭 GL_DEPTH_TEST 参数。此参数控制是否使用像素深度来计算新像素的值。通常情况下不必修改这个属性。更多信息可以在 OpenGL 规范中找到。 |
depthWrite | 这是另外一个内部属性。这个属性可以用来决定这个材质是否影响 WebGL 的深度缓存。如果你将一个物体用作二维贴图(例如一个套子),应该将这个属性设置为 false。但是,通常不应该修改这个属性。 |
polygonOffset polygonOffsetFactor polygonOffsetUnits |
通过这些属性,可以控制 WebGL 的 POLYGON_OFFSET_FILL 特性。一般不需要使用它们。有关这些属性具体做什么的解释,可以参考 OpenGL 规范。 |
alphatest | 可以给这个属性指定一个值(从 0 到 1)。如果某个像素的 alpha 值小于该值,那么该像素不会显示出来。可以使用这个属性移除一些与透明度相关的毛边。 |
三、配置材质属性的两种方法
(1)有如下两种方式用来配置材质的属性。通常来说如果知道所有属性的值,最好的方式是在创建材质对象时使用构造方法传入参数(方法1)。
(2)这两种方式中参数使用相同的格式。唯一例外的是 color 属性:
- 第一种方式中,可以只传人十六进制值,Three.js 会自己创建一个 THREE.Color 对象。
- 第二种方式中,必须创建一个 THREE.color 对象。
方法1:可以在构造函数中通过参数对象的方式传入参数。
1 2 3 4 5 6 |
|
方法2:还可以创建一个实例,并分别设置属性。
1 2 3 4 5 |
|
Three.js - 材质的使用详解2(网格基础材质、深度材质、法向材质、面材质)
一、THREE.MeshBasicMaterial(网格基础材质)
MeshBasicMaterial 是一种非常简单的材质,这种材质不考虑场景中光照的影响。使用这种材质的网格会被渲染成简单的平面多边形,而且也可以显示几何体的线框。
1,属性介绍
除了那些共有属性之外,MeshBasicMaterial 还有如下特有的属性。
名称 | 描述 |
color(颜色) | 设置材质的颜色。 |
wireframe(线框) | 设置这个属性可以将材质渲染成线框,非常适用于调试。 |
wireframeLinewidth(线框线宽) | 如果已经打开了 wireframe,这个属性定义线框中线的宽度。 |
wireframeLinecap(线框线段端点) | 这个属性定义了线框模式下顶点间线段的端点如何显示。可选的值包括:
|
wireframeLinejoin(线框线段连接点) | 这个属性定义了线段的连接点如何显示。可选的值有:
|
shading(着色) | 该属性定义如何着色。可选的值有:
|
vertexColors(顶点颜色) | 可以通过这个属性给每个顶点定义不同的颜色。默认值为:THREE.NoColors。如果将这个值设置为 THREE.VertexColors,渲染器会采用 THREE.Geometry 对象的 colors 属性的值。 该属性对 CanvasRenderer不起作用,但对 WebGLRender 起作用。比如我们可以使用该属性为线段的不同部分设置不同的颜色。也可以使用这个属性为这种材质类型创建渐变效果。 |
fog(雾化) | 该属性指定当前材质是否受全局雾化效果设置的影响。如果将该属性设置为 false,那么我们全局雾化效果设置就不会影响当前对象的渲染。 |
2,使用样例
这里我们创建一个小方块,使用的材质颜色为紫色且半透明。
1 2 3 4 5 6 7 8 9 10 |
|
二、THREE.MeshDepthMaterial(网格深度材质)
使用这种材质的物体,其外观不是由光照或者某个材质属性决定的,而是由物体到摄像机的距离决定的。我们可将这种材质与其他材质结合使用,从而很容易地创建出逐渐消失得效果。
1,属性介绍
除了那些共有属性之外,MeshDepthMaterial 还有如下两个控制线框显示的属性。
名称 | 描述 |
wireframe(线框) | 设置这个属性可以将材质渲染成线框,非常适用于调试。 |
wireframeLinewidth(线框线宽) | 如果已经打开了 wireframe,这个属性定义线框中线的宽度。 |
2,样例效果图
下面是一个通过联合材质创建出的新效果(两种材质融合起作用):
- 我们往场景中添加 20 个自动旋转的方块,位置随机。
- 这些方块从 THREE.MeshDepthMaterial 对象获得亮度。
- 并从 THREE.MeshBasicMaterial 对象获得颜色。
3,样例代码
这里要特别注意如下几个地方:
- 要把 THREE.MeshBasicMaterial 的 transparent 属性设置为 true,并指定一个融合模式。否则 THREE.js 不会执行任何融合操作,方块始终未纯绿色。
- 融合模式这里使用的是 THREE.MultiplyBlending,该模式会把前景色和背景色相乘,得到想要的结果。
- 当 THREE.SceneUtils.createMultiMaterialObject() 方法创建一个网格的时候,几何体会被复制,返回一个网格组(里面两个网格完全相同)。当渲染的物体有一个在别的物体上,并且有一个物体是透明的,那么渲染时会出现画面闪烁问题。这里我们通过缩小带有 THREE.MeshDepthMaterial 材质的网格,就可以避免这种现象。
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 |
|
三、THREE.MeshNormalMaterial(网格法向量材质)
使用这种材质,每一面的颜色是由从该面向外指的法向量计算得到的。
1,属性介绍
除了那些共有属性之外,MeshNormalMaterial 还有如下属性。
名称 | 描述 |
wireframe(线框) | 设置这个属性可以将材质渲染成线框,非常适用于调试。 |
wireframeLinewidth(线框线宽) | 如果已经打开了 wireframe,这个属性定义线框中线的宽度。 |
shading(着色方法) | THREE.FlatShading:平面着色 THREE.SmoothShading:平滑着色 |
2,使用样例
(1)效果图
- 下面是一个使用 MeshNormalMaterial 材质的球体。左右两侧的 shading(着色方法)分别为 THREE.FlatShading 和 THREE.SmoothShading。
- 法向量所指的方向决定了在使用 MeshNormalMaterial 材质时,每个面获取的颜色。由于球体各个面的法向量都不相同,所以我们看到的是一个色彩斑斓的球体。
- 而且即使在球体旋转时,这些颜色也基本保持在原来的位置(不会跟着面的移动而移动)。
(2)样例代码
1 2 3 4 5 6 7 |
|
3,使用 THREE.ArrowHelper 添加箭头
法向量是指与面垂直的向量。法向量在 Three.js 库中有很广泛的应用。它可以用来决定光的反射,有助于将纹理映射到三维模型,并提供有关如何计算光照、阴影和为表面像素着色的信息。
为了便于观察,这里我们遍历 THREE.SphereGeometry 的所有面。对于每个 THREE.Face3 对象来说,我们把构成该面的顶点相加再除以 3 来计算中心(质心)。使用这个质心连同该面的法向量来绘制箭头(THREE.ArrowHelper)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
四、THREE.MeshFaceMaterial(网格面材质)
THREE.MeshFaceMaterial 并不是一种真正的材质,而更像是一种材质容器。它允许给几何体的每个面指定不同的材质。
1,效果图
我们使用 MeshFaceMaterial 给方块的每个面指定一种不同颜色的材质。
2,样例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Three.js - 材质的使用详解3(网格Lambert、Phong、着色器材质)
一、THREE.MeshLambertMaterial(网格 Lambert 材质)
这种材质可以用来创建暗淡的并不光亮的表面。该材质非常易用,而且会与场景中的光源产生反应。
1,属性介绍
(1)它拥有材质基类 THREE.Material 定义的的所有属性(点击查看)。
(2)同时也有 color、wireframe、 wireframeLinewidth、wireframeLinecap、wireframeLinejoin、shadingv、vertexColors、fog 这些 THREE.MeshBasicMaterial 定义的所有属性(点击查看)
(3)该材质还有如下独有的属性:
名称 | 描述 |
ambient(环境色) | 这是材质的环境色。它跟前面讲过的环境光源一起使用。这个颜色会与环境光提供的颜色相乘。默认值为白色。 |
emissive(发射的) | 这是该材质发射的颜色。它其实并不像一个光源,只是一种纯粹的、不受其他光照影响的颜色。默认值为黑色。 |
wrapAround | 如果这个属性设置为 true,则启动半 lambert 光照技术。有了它,光下降得更微妙。如果网格有粗糙、黑暗的地区,启用此属性阴影将变得柔和并且分布更加均匀。 |
wrapRGB | 当 wrapAround 属性设置为 true 时,可以使用 THREE.Vector3 来控制光下降的速度。 |
2,使用样例
这里我们在舞台上添加一个聚光灯,并使用该材质创建一个小球。可以看到这个材质看上去比较暗淡。
1 2 3 4 5 6 7 8 9 10 11 |
|
二、THREE.MeshPhongMaterial(网格 Phong 材质)
通过 THREE.MeshPhongMaterial 可以创建一种光亮的材质。
1,属性介绍
(1)它拥有材质基类 THREE.Material 定义的的所有属性(点击查看)。
(2)同时也有 color、wireframe、wireframeLinewidth、wireframeLinecap、wireframeLinejoin、shadingv、vertexColors、fog 这些 THREE.MeshBasicMaterial 定义的所有属性(点击查看)
(3)该材质还有如下独有的属性:
名称 | 描述 |
ambient(环境色) | 这是材质的环境色。它跟前面讲过的环境光源一起使用。这个颜色会与环境光提供的颜色相乘。默认值为白色。 |
emissive(发射的) | 这是该材质发射的颜色。它其实并不像一个光源,只是一种纯粹的、不受其他光照影响的颜色。默认值为黑色。 |
specular | 该属性指定该材质的光亮程度及高光部分的颜色。
|
shininess | 该属性指定镜面高光部分的亮度。默认值:30 |
metal | 如果此属性设置为 true,Three.js 会使用稍微不同的方式计算像素的颜色,以使物体看起来更像金属。要注意的是,这个效果非常小。 |
wrapAround | 如果这个属性设置为 true,则启动半 lambert 光照技术。有了它,光下降得更微妙。如果网格有粗糙、黑暗的地区,启用此属性阴影将变得柔和并且分布更加均匀。 |
wrapRGB | 当 wrapAround 属性设置为 true 时,可以使用 THREE.Vector3 来控制光下降的速度。 |
2,使用样例
这里我们在舞台上添加一个聚光灯,并使用该材质创建一个小球。可以看到这个材质看上去比较光亮。
1 2 3 4 5 6 7 8 9 10 11 |
|
三、THREE.ShaderMaterial(着色器材质)
1,功能特点
- THREE.ShaderMaterial 是 Three.js 库中最通用、最复杂的材质之一。通过它,可以使用自己定制的着色器,直接在 WebGL 环境中运行。
- 着色器可以将 Three.js 中的 JavaScript 网格转换为屏幕上的像素。通过这些自定义的着色器,可以明确地指定对象如何渲染,以及如何覆盖或修改 Three.js 库中的默认值。
2,属性介绍
(1)它拥有材质基类 THREE.Material 定义的的所有属性(点击查看)。
(2)该材质还有如下独有的属性:
名称 | 描述 |
wireframe | 设置这个属性可以将材质渲染成线框。非常适合调试目的。 |
wireframeLinewidth | 如果已经打开了 wireframe,这个属性定义线框中线的宽度。 |
linewidth | 该属性定义了要绘制的线的宽度。 |
shading | 该属性定义如何着色。可选的值有 THREE.SmoothShading 和 THREE.Flat Shading。 |
vertexColors | 可以通过这个属性给每个顶点定义不同的颜色。该属性对 CanvasRenderer 不起作用,但是对 WebGLRenderer 起作用。 |
fog | 该属性指定当前材质是否受全局雾化效果设置的影响。 |
fragmentShader | 这个着色器定义的是每个传入的像素的颜色。你需要传入像素着色器程序的字符串值。 |
vertexShader | 这个着色器允许你修改每一个传入的顶点的位置。你需要传入顶点着色器程序的字符串值。 |
uniforms | 通过这个属性可以向你的着色器发信息。同样的信息会发给每一个顶点和片段。 |
defines | 转换成 #define 代码片段。这些片段可以用来设置着色器程序里的一些额外的全局变量。 |
attributes | 该属性可以修改每个顶点和片段。通常用来传递位置数据和与法向量相关的数据。如果要用这个属性,那么你需要为几何体中的每个顶点提供信息。 |
lights | 该属性定义光照数据是否传递给着色器。默认值:false。 |
3,使用样例
(1)下面在场景中添加一个不断旋转的方块,该方块使用的是着色器材质,可以看到方块的颜色会不断地过渡变化。
(2)要使用 THREE.ShaderMaterial 材质,必须传入两个不同的着色器:
- vertexShader:它会在几何体的每一个顶点上执行。可以用这个着色器通过改变顶点的位置来对几何体进行变换。本样例我们不调整顶点位置,所以这个方块的形状是不变的。
- fragmentShader:它会在几何体的每一个片段上执行。我们会返回这个特定片段应该显示的颜色。本样例我们根据传入的外部值,不断地计算并返回颜色。
关于着色器:
着色器不是用 JavaScript 编写的。需要使用类似 C 的 GLSL 语言(WebGL 支持 OpenGL ES 着色语言 1.0 一更多关于 GLSL 的信息,参考 https://www.khronos.org/webgl/)来写着色器。
(3)还要注意的是 uniforms 变量。我们通过这个变量从渲染器向着色器传递信息。本样例中渲染循环(render)每执行一次,其中 time 变量就会增加 0.1。这个信息就会传递给 vertexShader、fragmentShader,分别样例计算方块顶点的新位置(这个本样例没有),以及颜色。
(4)下面是完整代码
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 |
|
4,着色器资源
我们自己去写一些着色些可能会很困难,好在下面两个网站为我们提供了许多现成的着色器代码,我们只需要直接拿来在自己的对象中使用就可以了。
同时网站还提供一个试验环境,可以在这里创建和分享着色器。
Three.js - 材质的使用详解4(线性几何体材质)
2017-10-24发布:hangge阅读:638
线性几何体材质(LineBasicMaterial、LineDashedMaterial)比较特殊,只能用于一个特别的集合体:THREE.Line(线段)。顾名思义,这个几何体只是一条线,线段由顶点组成,不包含任何面。
一、THREE.LineBasicMaterial(实线)
这是用于线段的基础材质。
1,属性介绍
该材质非常简单,有如下几个属性:
名称 | 描述 |
color | 该属性定义线的颜色。如果指定了 vertexColors。这个属性就会被忽略。 |
linewidth | 该属性定义线的宽度。 |
linecap | 这个属性定义了线框模式下顶点间线段的端点如何显示。可选值包括:
|
linejoin | 这个属性定义了线段的连结点如何显示。可选值有:
|
vertexColors | 将这个属性设置成 THREE.VertexColors 值,就可以给每个顶点指定一种颜色。 |
fog | 该属性指定当前材质是否受全局雾化效果设置的影响。 |
2,使用样例
这里我们在舞台上显示一条 gosper 曲线,同时对线段的每个顶点都会指定一种颜色。
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 |
|
附:gosper曲线函数
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 |
|
二、THREE.LineDashedMaterial(虚线)
这种材质与 THREE.LineBasicMaterial 的区别是:可以通过指定虚线和空白间隙的长度来创建出虚线效果。
1,属性介绍
该材质除了拥有 THREE.LineBasicMaterial 全部的属性外,还有如下几个额外的属性,可以用来定义虚线的宽度和虚线之间的间隙的宽度。
名称 | 描述 |
scale | 缩放 dashSize 和 gapSize。
|
dashSize | 虚线段的长度。 |
gapSize | 虚线间隔的宽度。 |
2,使用样例
这个材质的用法和上面的 THREE.LineBasicMaterial 基本一样。唯一的区别是必须调用 computeLineDistances() 方法来计算线段顶点之间的距离。如果不这么做,间隔就不会正确地显示。
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 |
|