一、总的任务
1.数据来源:
将3dsmax中建好的模型,通过烘焙反贴,赋予SelfIllumMap(自发光材质)一个bitmap(位图贴图),用于表达物体的光影效果。加上本身的diffuseMap(本色贴图/漫反射贴图),每个材质一共有两个材质贴图。
2.任务:
three.js 可以加载json格式的材质,其中包含了metadata、scale、materials、vertices、morphTargets、normals、colors、uvs、faces、bones等数据。较难的是每个纹理顶点对应uv,以及导出max源文件的各个材质参数。
Tips:关注重点
- json中的faces、uvs
- json中的materials
二、3dsMax的一些基本概念
1.Matirial、 TextureMap
Material,材质,加了材质的模型是动态的和本质的,当外界环境变化的时候能做出相应的变化,所以更真实。maxsript中的Material 类代表在 3ds max 里赋给对象的材质。Material 类由 MAXWrapper 类派生而来
TextureMap ,贴图/纹理贴图,maxsript中的TextureMap类代表了二维贴图和三维贴图。用户可以把这些贴图赋给材质或某些对象的属性,还可以创建各种贴图如 Bitmap、Dent 和 Swirl,并存取其各种属性。TextureMap 类由 Material 类派生而来
(纹理更偏向于“图”,而材质更偏向于“属性”。纹理是静态的和表面的,不会因为外界环境(比如光照)变化而变化)
2.纹理顶点、纹理面片(UV Faces) VS 几何顶点、网格面片(Mesh Face)
maxsript中的 Mesh 类对象包含一个纹理顶点列表,这个列表完全独立于 Mesh 对象常规的顶点(也就是几何顶点)。
纹理顶点(UV Vertexs)和网格几何顶点(Mesh Vertexs)这两者之间也没有任何关联。由纹理顶点组成纹理面,Mesh 对象的每一个常规面必须有一个纹理面与之对应。每一个纹理面有三个纹理顶点,纹理顶点的坐标系为 UVW 坐标系,其数据类型为Point3;坐标分量分别为 U、V、W;
PS:虽然纹理顶点(UV Vertexs)和网格几何顶点(Mesh Vertexs)无对应关系,但纹理面片(UV Faces)必然和网格面片(Mesh Face)一一对应。Mesh类并不存在一个什么诸如"numTVFaces"之类的成员来标识纹理面片的数量。这当然毫无必要,纹理面片的数目不但和几何面片的数目相同,而且在索引上也是一一对应的关系。tvFace就是纹理面片数组,显然faces[i]对应的纹理面片是tvFace[i]。
3.贴图通道
贴图通道的本质是在多维材质的子材质与贴图坐标之间建立一种一一对应的关系。也就是说,每一个子材质可以拥有一个与之相对的贴图坐标,并且彼此独立。
max支持多个map channel(0:顶点颜色通道 1-99:纹理贴图通道 ,这两个大类的通道的UV原理是一样的,但调用上有所差异。
map channel为0:顶点颜色通道。 1-99:纹理贴图通道。所以,贴图通道索引<mapChannel >从 1 开始。
具体的纹理顶点的获取方式
meshop.getNumMapVerts <Mesh mesh> <Integer mapChannel> 返回一个整数,表示指定贴图通道的顶点数。
二.Json串中 纹理uv与面片的对应关系 的表示
faces和uvs
faces记录了比较丰富的信息,其中包括mesh的类型,面的索引,材质的索引,每个面顶点和uv坐标的索引关系。
Type:three 里面定义成type,这个type决定了mesh的类型,是不是有面的法向量的值的传入,是不是有材质,是不是有顶点颜色,是不是有面的顶点的UV坐标.....
对于每一个face,按照这个type 返回的值确定加载下面的内容中的哪些
- Face顶点的索引:()
- 材质的索引:(materialIndex)
- face顶点纹理(UV)的索引:(uvIndex)。对于一个face,有几个贴图通道则有几组uv,每一组有三个值,存储face的三个纹理顶点的索引。
- Face法向量的索引:(normalIndex)
- Face顶点法向量的索引:(normalIndex)
- FaceCoalor属性:(colorIndex)
- FaceVertexColor属性:(colorIndex)
Uvs是一个嵌套数组,存储的是每个贴图通道对应的uv坐标。一个贴图通道为一个子数组,子数组中每对UV值以逗号隔开,U、V之间也已逗号分隔。
三.材质参数的获取
1.第一步:three的材质数据结构
通过阅读three.js中的createMaterial和JSONLoader函数,判定json中material键值对所需要的值,以及faces和uvs的对应关系如下。
2.第二步 max脚本对于material数据组织
了解了three.js中的数据组织,接下来需要看的就是max怎么获取这些数据了。
图示仅是max的material类和textureMap类的一部分属性,主要是three需要的一些相关参数。(而且是我根据自己的理解画的,也许并不严谨)
3.剩下的任务就是找到对应关系,部分对应关系如下:
需要注意,colorAmbient、mapAmbient这部分表示环境光的参数,three中加载模型的时候不支持,所以环境光要在加载灯光的时候统一设置。
关于“transparent”这个参数,设置材质的不透明度百分比,Three根据传入的“opacity”为transparent赋值。
Three.js需要的键 | 含义/解释 | 在max中获取该值的调用关系 |
DbgName |
| <material>.name |
blending | 决定物体如何与背景进行融合。默认NormalBlending。可选参数还有:NoBlending、AdditiveBlending、SubtractiveBlending、MultiplyBlending、CustomBlending | 未找到对应 |
colorAmbient | colorAmbient is no longer supported.(three不再支持) | <Standard>.ambient |
mapAmbient | no longer supported(three不再支持) | 未找到对应 |
colorDiffuse | 指定对象表面在最佳光照条件下呈现的本色 | <Standard>.diffuse |
specularCoef | 设置高光区的尺寸,增大光泽数值,高光区变得小而锐 | <Standard>.glossiness (有疑问,但原脚本这么写) |
shading | 材质的明暗模式,Three有三种:basic、phong、standard。Max里面有7种明暗模式,默认blinn,没有basic和standard | <Standard>.shaderType |
mapBumpScale | 被three单独列出来,不和材质贴图bumpMap一起赋值 | 未找到对应 |
normalScale | 被three单独列出来,不和材质贴图normalMap一起赋值 | 未找到对应 |
flipSided |
| 未找到对应 |
doubleSided | 是否双面显示 | <Standard>.twoSided |
depthTest | 传参示例:"depthTest" : true, 深度测试 | 未找到对应 |
depthWrite | 传参示例:"depthWrite " : true, | 未找到对应 |
colorWrite |
| 未找到对应 |
opacity | 透明度,是一个0-1的数值 | <Standard>.opacity |
reflectivity | “specular代表反射率或者高光强度”??? Max的值是0-999,three要的值的范围?? | <Standard>.specularLevel |
visible |
| 未找到对应 |
wireframe | 设置是否可将材质以结构线框方式进行渲染 | <Standard>.wire |
vertexColors | 传参:true或者'face'。three中对应源码如下: if ( value === true ) json.vertexColors = VertexColors; if ( value === 'face' ) json.vertexColors = FaceColors; | 未找到对应 |