文章转自: https://blog.csdn.net/weixin_38676065/article/details/126123975

学习参考文章:https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric

自定义材质不是必须的,但想要呈现绚丽的效果,还得自定义材质来实现。

文章目录

内置材质

类型

使用

自定义材质

组件

源代码

输入变量

fabric 对象

实例

效果

代码

分析

内置材质

类型

材质通过漫反射、镜面反射、法线、发射和 alpha 分量的组合来定义表面外观。 这些值是使用名为 Fabric 的 JSON 模式指定的,该模式在幕后被解析并组装成 glsl 着色器代码。内置的材质可以直接拿来使用,最常用的就是Color和Image。部分材质及它的uniforms如下:

材料类型描述uniforms

Color单纯的颜色color

Imagejpg 或 png 的贴图图片image、repeat

Checkerboard国际象棋格子lightColor、darkColor、repeat

Stripe竖条纹旗帜horizontal、evenColor、oddColor、offset、repeat

Dot行列点阵lightColor、darkColor、repeat

Grid线状网格color、cellAlpha、lineCount、lineThickness、lineOffset

DiffuseMap漫反射贴图image、channels、repeat

SpecularMap单通道贴图image、channel、repeat

AlphaMap单通道的不透明度贴图image、channel、repeat

NormalMap三通道贴图image、channels、repeat、strength

BumpMap单通道的凹凸贴图image、channels、repeat、strength

EmissionMap三通道的自发光贴图image、channel、repeat

PolylineArrow箭头线,终点在折线末端color

PolylineGlow发光线color、glowPower、taperPower

PolylineOutline描边线color、outlineColor、outlineWidth

Water水面贴图,看起来有水波动效baseWaterColor、blendColor、specularMap、normalMap、frequency、animationSpeed、amplitude、specularIntensity

RimLighting边缘会比较亮color、rimColor、width

使用

通过几何对象的 material 属性可以创建材质,这个属性是 Cesium.Material对象,使用内置材质设置material 非常简单。

// color

polygon.appearance.material = Cesium.Material.fromType('color');

// image

polygon.appearance.material = Cesium.Material.fromType('Image')

polygon.appearance.material.uniforms.image = 'image.png'

1

2

3

4

5

6

7

上面就创建了自定义的颜色和贴图的材质。Cesium.Material.fromType() 方法是一个简写,完整的写法是如下,Fabric 是 Cesium 中用于描述材质的一种 JSON 规定,里面type属性是材质的类型,也就是材质标识,uniforms是对应材质的一些变量,可以设置材质的颜色、图片等,不同材质的uniforms不一样。

// color

polygon.appearance.material = new Cesium.Material({

fabric: {

type: 'Color',

uniforms: {

color: new Cesium.Color(1.0, 0.0, 0.0, 0.5)

}

}

})

polygon.appearance.material.uniforms.color = Cesium.Color.WHITE

// image

polygon.appearance.material = new Cesium.Material({

fabric: {

type: 'Image',

uniforms: {

image: 'image.png'

}

}

})

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

自定义材质

使用 fabric 对象 + GLSL 代码和其他素材,就可以创建自定义材质。

let fabric = {

// ...

}

polygon.appearance.material = new Cesium.Material({

fabric: fabric

})

1

2

3

4

5

6

7

8

let fabric = {

type : 'MyNewMaterial',

// ...其他 fabric JSON 的属性

}

polygon.appearance.material = new Cesium.Material({

fabric : fabric

});

// ... 然后在另一处需要这个 fabric

anotherPolygon..appearance.material = Material.fromType('MyNewMaterial');

1

2

3

4

5

6

7

8

9

10

组件

白色的漫反射材质或许是最常用的:

let fabric = {

components: {

diffuse: 'vec3(1.0)'

}

}

1

2

3

4

5

6

稍微复杂一些,加一点镜面反射,使得正射视角看反光最强,侧面变弱:

let fabric = {

components : {

diffuse : 'vec3(0.5)',

specular : '0.1'

}

}

1

2

3

4

5

6

Fabric 是 Cesium 中用于描述材质的一种 JSON 规定,components 属性包含了 fabric 所定义的材质的各种子因素。每个子因素均使用简短的 glsl 代码字符串表示,因此上面写的 vec(0.5) 就表示 rgb 均为 0.5 的一种颜色。这个简单的 glsl 代码可以使用所有 glsl 内置的函数,例如 mix、cos、texture2D 等。components 可以定义 6 个属性:

名称默认值描述

diffuse‘vec3(0.0)’漫反射颜色,即物体的基本颜色

specular‘0.0’镜面反射,定义的是单方向反射光强度

shininess‘1.0’镜面反射的清晰度,这个值越大会出现更小的高光光斑

normal法线,默认无法线

emission‘vec3(0.0)’自发光,默认不发光

alpha‘1.0’不透明度,0.0 是完全透明,1.0 是不透明。

源代码

components 还有一个更强大而灵活的选择是 glsl 源代码,通过 glsl 的方式修改材质。这个途径将设置的 glsl 代码传递到 czm_getMaterial 函数,这个函数执行后返回材质的 components:

struct czm_materialInput

{

float s;

vec2 st;

vec3 str;

mat3 tangentToEyeMatrix;

vec3 positionToEyeEC;

vec3 normalEC;

};

struct czm_material

{

vec3 diffuse;

float specular;

float shininess;

vec3 normal;

vec3 emission;

float alpha;

};

czm_material czm_getMaterial(czm_materialInput materialInput);

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

默认情况下,材质的默认值会被返回:

czm_material czm_getMaterial(czm_materialInput materialInput)

{

return czm_getDefaultMaterial(materialInput);

}

1

2

3

4

5

这个时候的 fabric 对象是:

let fabric = {

components: {

source: `czm_material czm_getMaterial(czm_materialInput materialInput) { return czm_getDefaultMaterial(materialInput); }`

}

}

1

2

3

4

5

6

上面修改了漫反射和镜面反射的例子可以通过 glsl 改写为:

let fabric = {

source: `czm_material czm_getMaterial(czm_materialInput materialInput)

{

czm_material m = czm_getDefaultMaterial(materialInput);

m.diffuse = vec3(0.5);

m.specular = 0.5;

return m;

}`

}

1

2

3

4

5

6

7

8

9

10

使用 glsl 代替 components 虽然看起来代码比较冗长,但是提供了灵活性。

如果不是有特别的需求,使用 components 属性指定材质的各种因子就可以了。但是,不管是哪一种,在这些 glsl 代码中,都是可以直接使用 glsl 的内置函数和 Cesium 预定义的 函数、结构体、常量的。

输入变量

materialInput 变量在 source 和 components 中均可以使用,在 glsl 代码的定义中,这个变量是 czm_materialInput 结构体有如下字段:

名称类型描述

sfloat一维纹理坐标

stvec2二维纹理坐标

strvec3三维纹理坐标,三维纹理的二维部分不一定就是二维纹理坐标,切记。例如,在一个椭球几何中,s可能就是从下到上,st可能是经纬度,str三维纹理就是包围盒的三轴方向。

tangentToEyeMatrixmat3用于法线贴图、凹凸贴图的转换矩阵,转换切线空间坐标到视图坐标

positionToEyeECvec3从 fragment 到 视图空间坐标的向量(不知道这个 fragment 说的是什么),用于反射和折射等。向量的长度是 fragment 到视图(相机)的距离。

normalECvec3fragment 在视图坐标中的法线(已归一化),作用于凹凸贴图、反射、折射等例如可以这么设置来可视化纹理坐标:

let fabric = {

components: {

diffuse: 'vec3(materialInput.st, 0.0)'

}

}

1

2

3

4

5

6

一样的,可以把 diffuse 组件设置为 materialInput.normalEC 来可视化法线。

除了 materialInput 这个传入的参数,还可以访问 Cesium 提供的 uniform 变量。

例如,可以通过一个 color uniform 去设置 diffuse 组件和 alpha 组件,来创建自己的 Color 材质:

let fabric = {

type: 'MyColor',

uniforms: {

color: new Color(1.0, 0.0, 0.0, 1.0)

},

components: {

diffuse: 'color.rgb',

alpha: 'color.a'

}

}

1

2

3

4

5

6

7

8

9

10

11

在 fabric 中,glsl 中的 uniform 变量、new Cesium.Material() 和 Cesium.Material.fromType() 返回的 js 对象中的 uniform 变量与 uniforms 属性的子属性(例如这里的 uniforms.color)具有相同的名称。

子属性的值(对于标量来说)或子属性(对于向量来说)即 uniform 的值。

下例,通过 image uniform 来实现自定义的 DiffuseMap 材质:

let fabric = {

type: 'OurDiffuseMap',

uniforms: {

image: 'czm_defaultImage'

},

components: {

diffuse: 'texture2D(image, materialInput.st).rgb'

}

}

1

2

3

4

5

6

7

8

9

czm_defaultImage 是 1x1 分辨率的图片,根据上面的说法,这可以从 dataurl 或图片文件中获取,例如:

polygon.appearance.material = Material.fromType('OurDiffuseMap');

polygon.appearance.material.uniforms.image = 'diffuse.png';

1

2

3

还有一个多维数据集的变量:czm_defaultCubeMap。

支持 glsl 的 uniform 类型,例如 float、vec3、mat4 等。

对于 uniform 数组还不支持,不过在规划中了。

在 fabric 这个对象中,uniforms 下的所有属性均被 glsl 认作是 uniform 变量,可以直接当变量使用,例如上例中的 texture2D(image, materialInput.st) 中的 image 参数。

在这里,规定了 image 这个 uniform 的类型是 Cesium 内置的 czm_defaultImage 结构体类型。

fabric 对象

fabric 是一个有官方规定如何写的 js 对象,它拥有 5 个属性:

type:用于声明 fabric 对象最终会生成什么材质,如果是官方内置的,直接用官方内置的,否则则创建自定义的材质并缓存。

materials:允许再塞进去子一级的 fabric,构成复合材质。

source:是 glsl 源代码,它主要是对 czm_getMaterial 这个 Cesium 内置的 glsl 函数的实现,返回值是 czm_material

components:是几个基本材质因子的 glsl 代码快捷入口,是 source 的一种简略实现。

uniforms:一些全局变量,可以在 glsl 代码中用到这个 uniform 定义的所有变量了。

实例

效果

发光特效

代码

材质代码:

const Cesium = require('cesium/Cesium')

function DynamicWallMaterialProperty (options) {

this._definitionChanged = new Cesium.Event()

this._color = undefined

this._colorSubscription = undefined

this.color = options.color

this.duration = options.duration

this.trailImage = options.trailImage

this._time = (new Date()).getTime()

this.viewer = options.viewer

}

Object.defineProperties(DynamicWallMaterialProperty.prototype, {

isConstant: {

get: function () {

return false

}

},

definitionChanged: {

get: function () {

return this._definitionChanged

}

},

color: Cesium.createPropertyDescriptor('color')

})

DynamicWallMaterialProperty.prototype.getType = function (time) {

return 'DynamicWall'

}

DynamicWallMaterialProperty.prototype.getValue = function (time, result) {

if (!Cesium.defined(result)) {

result = {}

}

result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.WHITE, result.color)

if (this.trailImage) {

result.image = this.trailImage

} else {

result.image = Cesium.Material.DynamicWallImage

}

if (this.duration) {

result.time = (((new Date()).getTime() - this._time) % this.duration) / this.duration

}

this.viewer.scene.requestRender()

return result

}

DynamicWallMaterialProperty.prototype.equals = function (other) {

return this === other ||

(other instanceof DynamicWallMaterialProperty &&

Cesium.Property.equals(this._color, other._color))

}

Cesium.DynamicWallMaterialProperty = DynamicWallMaterialProperty

Cesium.Material.DynamicWallType = 'DynamicWall'

Cesium.Material.DynamicWallImage = require('./colors.png')

Cesium.Material.DynamicWallSource = `

czm_material czm_getMaterial(czm_materialInput materialInput)

{

czm_material material = czm_getDefaultMaterial(materialInput);

vec2 st = materialInput.st;

vec4 colorImage = texture2D(image, vec2(fract(st.t - time), st.t));

vec4 fragColor;

fragColor.rgb = color.rgb / 1.0;

fragColor = czm_gammaCorrect(fragColor);

material.alpha = colorImage.a * color.a;

material.diffuse = color.rgb;

material.emission = fragColor.rgb;

return material;

}

`

Cesium.Material._materialCache.addMaterial(Cesium.Material.DynamicWallType, {

fabric: {

type: Cesium.Material.DynamicWallType,

uniforms: {

color: new Cesium.Color(1.0, 1.0, 1.0, 1),

image: Cesium.Material.DynamicWallImage,

time: 0

},

source: Cesium.Material.DynamicWallSource

},

translucent: function (material) {

return true

}

})

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

分析

上面是自定义材质的代码,大部分自定义材质代码的模板也是如此,不同的就是glsl里的代码和uniforms变量。uniforms变量里定义的属性,可以直接在Cesium.Material.DynamicWallSource中的glsl代码里使用。简单的光效不学glsl语言也可以模仿网上案例修改一下参数,复杂的光效就得对glsl有一定的了解。

————————————————

版权声明:本文为CSDN博主「一指流沙叹风华」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/weixin_38676065/article/details/126123975

Cesium中自定义材质material相关推荐

  1. Cesium中自定义材质(以飞线材质为例)

    1.entity自定义材质 entity材质类型为Cesium.MaterialProperty.自定义材质实例如下,例子为实现飞线材质 import * as Cesium from 'cesium ...

  2. Cesium实现一材质多贴图,一个模型多张贴图,自定义attribute

    思路: Material.fabric.uniforms添加自定义的两张贴图image_0,image_1. Geometry.attributes添加imgIdx自定义属性,用于标识该顶点使用哪张贴 ...

  3. Shader cesium中材质

    Shader 首先,在本文开始前,我们先普及一下材质的概念,这里推荐材质,普及材质的内容都是截取自该网站,我觉得他写的已经够好了.在开始普及概念前,推荐一首我此刻想到的歌<光---陈粒>. ...

  4. Cesium 1.02.0 及以上版本下自定义材质报错:[Cesium WebGL] ERROR: 0:1: ‘varying‘ : Illegal use of reserved word

    Cesium 1.02.0 及以上版本下自定义材质报错:[Cesium WebGL] ERROR: 0:1: 'varying' : Illegal use of reserved word 报错原因 ...

  5. Forest 3.6.2中多种材质的混合使用与自定义编辑

    Forest插件是一款便捷种植树木等内容的三维建模软件插件.基于二维平面面片,从视觉上展示树木.草地.花丛.人群等效果. 在2的版本中见过forest,与3.6以后的版本还是有明显不同的,包括使用上, ...

  6. 【Unity3D】材质 Material ( 材质简介 | 创建材质 | 设置材质属性 | 对 3D 物体应用材质 | 资源拖动到 Inspector 检查器中的 Material 属性中 )

    文章目录 一.材质 Material 简介 二.创建材质 三.设置材质属性 四.对 3D 物体应用材质 五.资源拖动到 Inspector 检查器中的 Material 属性中 一.材质 Materi ...

  7. Cesium 源码分析 Material

    Cesium关于实例的创建都是封装在类的静态函数中,这个习惯很好,方便创建和管理,对外只提供创建的方法,正如Material中的Material.fromType()函数一样,传递参数创建材质. Ma ...

  8. Cesium中图元Primitive详细介绍及案例

    Cesium从入门到项目实战总目录: 点击 文章目录 Cesium中图元Primitive详细介绍 Cesium中Primitive案例 Cesium中图元Primitive详细介绍 在Cesium中 ...

  9. Cesium 中两种添加 model 方法的区别

    概述 Cesium 中包含两种添加 model 的方法,分别为: 通过 viewer.entities.add() 函数添加 通过 viewer.scene.primitives.add() 函数添加 ...

最新文章

  1. 这样的“牛”人,绝佳客户最好能多碰上上几个是我们当程序员的好运
  2. JMeter断言介绍
  3. python多进程优化_『Python』多进程处理
  4. 如何用css实现等高布局。
  5. CodeForces - 803C Maximal GCD(贪心 + 枚举)
  6. MySQL怎么存base64编码_MySQL中如何将字符串转为base64编码?
  7. Spring5参考指南:Environment
  8. java的基础语法是什么_java语法基础
  9. Parallax Mapping
  10. [css] 移动端页面不满一屏时如何实现满屏背景?
  11. typeahead有什么作用_typeahead使用配置参数。
  12. 计算机配置交换机线缆线序,H3C S7500X-G系列交换机
  13. 远程windows蓝屏解决办法
  14. 微信赞赏功能升级设置中的坑
  15. java实现登陆验证码
  16. 输入两个实数,用一个函数求出它们之和
  17. docker下载安装和常用命令
  18. Javaweb的服务器有哪些
  19. BGP 十一条选路原则与BGP路由传递的注意事项介绍
  20. 解决报错:Cause: java.sql.SQLSyntaxErrorException: Table 'myactiviti.act_ge_property' doesn't exist

热门文章

  1. 机械制造技术基础【2】
  2. 前端页面 原生php+H5 视频播放一 专辑列表页(专辑页list)
  3. java循环链表实现魔术师发牌问题
  4. 东方国信 Java一面
  5. 用 Windows 的 diskpart 命令修复U盘
  6. oracle instr函数(oracle 用instr 来代替 like)
  7. Linux系统下的一些常用基本命令
  8. 家庭NAS服务器(1)服务器的配置与选择
  9. 超级细菌战:一场人类无法打赢的战争
  10. #父与子的编程之旅#第八章