Cesium开发高级篇 | 02材质设置

无论是通过Entity类,还是通过Primitive类添加的空间几何数据,Cesium都提供了对应的方法或材质相关类对材质进行修改。在讲解材质设置之前,首先我们先简单地介绍下什么是材质。比较粗浅的理解是,材质可以是几何对象表面的任意一种着色(Cesium.Color)、可以是贴在其表面的一张图片、也可以是一个纹理或图案,比如下图中的条形或棋盘形的图案。


针对于两种方式(Entity和Primitive)绘制的几何对象,Cesium也提供了Material类和MaterialProperty类,分别对通过Primitive和Entity两种方式生成的几何对象的material属性进行赋值。这里特别要注意,Primitive的appearance(或继承类)的material属性为Material类型,Entity的xxxGraphics的material属性为MaterialProperty或Color类型,请大家不要记混。


Primitive.appearance.material
Entity.xxxGraphics.material
Cesium中的material属性设置

Material类

Material类专为Appearance类而生,用于修改Primitive的几何对象材质。同时,Apperance也有自己的继承类,通过修改部分继承类的material属性,也可实现Primitive几何对象材质的修改。Appearance的继承类如下图所示,其中橘黄色背景的子类,能修改其material属性。


通过Material类修改材质相对来说比较复杂,需要对OpenGL以及底层渲染机制进行了解。Cesium中的Material类的内部机制是通过一种json格式的Fabric对象来表达物体的外观特征,而这些外观特征是由漫反射(diffuse)、镜面反射(specular)、法向量(normal)、自发光(emission)以及透明度(alpha)组合(即一个Components)而成。详细可查看Cesium对Fabric的解说https://github.com/CesiumGS/cesium/wiki/Fabric

Cesium为我们提供了23种现成的Material类型,可通过Material.fromType方法和Fabric两种方式去获取并设置几何对象材质。如下是通过Material类的两种方式实现着色的示例:

// Create a color material with fromType:
polygon.material = Cesium.Material.fromType('Color');
polygon.material.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 1.0);

// Create the default material:
polygon.material = new Cesium.Material();
// Create a color material with full Fabric notation:
polygon.material = new Cesium.Material({
    fabric : {
        type : 'Color',
        uniforms : {
            color : new Cesium.Color(1.0, 1.0, 0.0, 1.0)
        }
    }
});

具体可查阅Material类文档说明:http://127.0.0.1:5500/Build/Documentation/Material.html?classFilter=material,以及Material的沙盒示例:https://sandcastle.cesium.com/index.html?src=Materials.html

从Material的Fabric对象组成来看,要想创建一个新的Material,用户只需要指定type、uniforms、compontents三个属性,构建一个Fabric的JSON对象。如果想写一些自定义的shader,则需要再指定source属性。


MaterialProperty类

MaterialProperty类专为Entity而生,它是一个抽象类,我们无法对它进行实例化。要使用该类对材质进行设置,需要实例化其子类。MaterialProperty类的继承类,如下图所示:


1.ColorMaterialProperty 颜色材质
ColorMaterialProperty类相对来说比较简单,你可以直接使用Cesium.Color替换它,两个类实现的效果最终是一样的,都是给几何对象直接着色。

var color = Cesium.Color.BLUE.withAlpha(0.5);
    var colorMaterial = new Cesium.ColorMaterialProperty(color);
    viewer.entities.add({
      position: Cesium.Cartesian3.fromDegrees(-55.0, 40.0, 100000.0),
      ellipse: {
        semiMajorAxis: 300000.0, // 长半轴距离
        semiMinorAxis: 200000.0, // 短半轴距离
        height: 20000.0,
        material: colorMaterial,
      },
    });

2.ImageMaterialProperty 贴图材质
ImageMaterialProperty类可以给几何对象表面贴上一张图片。

var imgUrl = "./images/bumpmap.png";
    var imgMaterial = new Cesium.ImageMaterialProperty({
      image: imgUrl,
      repeat: new Cesium.Cartesian2(4, 4),
      color: Cesium.Color.BLUE,
    });
    viewer.entities.add({
      position: Cesium.Cartesian3.fromDegrees(-65.0, 40.0, 100000.0),
      ellipse: {
        semiMajorAxis: 300000.0, // 长半轴距离
        semiMinorAxis: 200000.0, // 短半轴距离
        height: 20000.0,
        material: imgMaterial,
      },
    });

3.CheckerboardMaterialProperty 棋盘纹理

var checkerboardMaterial = new Cesium.CheckerboardMaterialProperty({
      evenColor: Cesium.Color.WHITE,
      oddColor: Cesium.Color.BLACK,
      repeat: new Cesium.Cartesian2(4, 4),
    });
    viewer.entities.add({
      position: Cesium.Cartesian3.fromDegrees(-75.0, 40.0, 100000.0),
      ellipse: {
        semiMajorAxis: 300000.0, // 长半轴距离
        semiMinorAxis: 200000.0, // 短半轴距离
        height: 20000.0,
        material: checkerboardMaterial,
      },
    });

4.StripeMaterialProperty 条纹纹理

var stripeMaterial = new Cesium.StripeMaterialProperty({
      orientation: Cesium.StripeOrientation.VERTICAL,
      evenColor: Cesium.Color.WHITE,
      oddColor: Cesium.Color.BLACK,
      repeat: 16,
    });
    viewer.entities.add({
      position: Cesium.Cartesian3.fromDegrees(-85.0, 40.0, 100000.0),
      ellipse: {
        semiMajorAxis: 300000.0, // 长半轴距离
        semiMinorAxis: 200000.0, // 短半轴距离
        height: 20000.0,
        material: stripeMaterial,
      },
    });

5.GridMaterialProperty 网格

 var gripMaterial = new Cesium.GridMaterialProperty({
      color: Cesium.Color.YELLOW,
      cellAlpha: 0.5,
      lineCount: new Cesium.Cartesian2(8, 8),
      lineThickness: new Cesium.Cartesian2(2.0, 2.0),
      lineOffset: new Cesium.Cartesian2(0.0, 0.0),
    });
    viewer.entities.add({
      position: Cesium.Cartesian3.fromDegrees(-95.0, 40.0, 100000.0),
      ellipse: {
        semiMajorAxis: 300000.0, // 长半轴距离
        semiMinorAxis: 200000.0, // 短半轴距离
        height: 20000.0,
        material: gripMaterial,
      },
    });

6.PolylineGlowMaterialProperty 发光材质

var glowingLine = viewer.entities.add({
      name: "Glowing blue line on the surface",
      polyline: {
        positions: Cesium.Cartesian3.fromDegreesArray([-75, 37, -125, 37]),
        width: 10,
        material: new Cesium.PolylineGlowMaterialProperty({
          glowPower: 0.8,
          taperPower: 0.5,
          color: Cesium.Color.CORNFLOWERBLUE,
        }),
      },
    });

7.PolylineOutlineMaterialProperty 外轮廓材质

var orangeOutlined = viewer.entities.add({
      name:
        "Orange line with black outline at height and following the surface",
      polyline: {
        positions: Cesium.Cartesian3.fromDegreesArrayHeights([
          -75,
          39,
          250000,
          -125,
          39,
          250000,
        ]),
        width: 5,
        material: new Cesium.PolylineOutlineMaterialProperty({
          color: Cesium.Color.ORANGE,
          outlineWidth: 5,
          outlineColor: Cesium.Color.BLACK,
        }),
      },
    });

8.PolylineArrowMaterialProperty 带有箭头的线

var purpleArrow = viewer.entities.add({
      name: "Purple straight arrow at height",
      polyline: {
        positions: Cesium.Cartesian3.fromDegreesArrayHeights([
          -75,
          43,
          500000,
          -125,
          43,
          500000,
        ]),
        width: 10,
        arcType: Cesium.ArcType.NONE,
        material: new Cesium.PolylineArrowMaterialProperty(Cesium.Color.PURPLE),
      },
    });

9.PolylineDashMaterialProperty 虚线

var dashedLine = viewer.entities.add({
      name: "Blue dashed line",
      polyline: {
        positions: Cesium.Cartesian3.fromDegreesArrayHeights([
          -75,
          45,
          500000,
          -125,
          45,
          500000,
        ]),
        width: 4,
        material: new Cesium.PolylineDashMaterialProperty({
          color: Cesium.Color.CYAN,
        }),
      },
    });

上述9种方式生成的效果图如下所示:


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,640评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,254评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,011评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,755评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,774评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,610评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,352评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,257评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,717评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,894评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,021评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,735评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,354评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,936评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,054评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,224评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,974评论 2 355

推荐阅读更多精彩内容