重读Cesium(八): Appearance相关介绍(一)

前几篇文章中我们介绍了Primitive的相关内容,我们会发现在Primitive中Appearance是Primitive的重要组成部分。我们已经可以简单的使用Appearance来设置Primitive几何图形的外观。这篇文章,我们来详细的了解一下Appearance

Appearance分类

Cesium中一共有以下几种Appearance,不同的Appearance适用于不同的场景,如果你在某个场景中,使用错了Appearance,会导致看不见渲染结果的。
在这里插入图片描述
还有一个DebugAppearance,我们不说这个,这个是用于测试的。

MaterialAppearance材质外观

对于所有的几何对象都适用,cesium的材质包括颜色,图片,法线贴图,凹凸贴图,网格贴图,棋盘贴图等。支持传入material
在这里插入图片描述

EllipsoidSurfaceAppearance椭球体表面外观

支持所有材质,但需要具有法线,切线,副切线属性,是MaterialAppearance的另一个版本,主要用于地球表面平行的几何类型,如我们在前几篇中提到的PolygonGeometry,RectangleGeometry这些不适用与地表垂直的几何类型。使用llipsoidSurfaceAppearance时可以在计算大量顶点属性时节省内存。
在这里插入图片描述

PerInstanceColorAppearance实例化材质外观

使用每个GeometryInstance自带的颜色属性,可以实现不同的实例渲染不同颜色。我们在前几篇有提到Primitive通过实例化几何时可以同时显示大量的几何实体,但是一个Primitive只能存在一个Appearance,那么我们想每个几何实体的外观不同的话,就可以通过perInstanceColorAppearance这个类去实现了。
在这里插入图片描述

PolylineColorAppearance线几何对象的颜色外观

使用每个GeometryInstance自带的颜色属性,可以实现不同的实例渲染不同颜色。我们提到过PolylineGeometry支持根据顶点颜色进行着色,那么我们此时就需要结合PolylineColorAppearance类一起去实现了。
在这里插入图片描述

PolylineMaterialAppearance线几何对象的材质的外观

可以对线几何对象使用各种材质。支持传入material
在这里插入图片描述

Material材质

Material我们一般叫作材质,用于表达物体的表面外观。在我们肉眼看到的世界中,每一种物体对光都会产生不同的反应,这就使得不同物体的表面看起来不一样。
Cesium中内置的Material类大概有20多种材质类型,不同的几何应用不同的材质,这样可以使得场景渲染出来的视觉效果更加丰富。

Material的使用

我们可以看看官方API中给的example
在这里插入图片描述

// 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类的使用方法

1.Cesium.Material.fromType('Color')

let material = Cesium.Material.fromType('Color',{
color:new Cesium.Color(1.0, 1.0, 0.0, 1.0)
})

2.new Cesium.Material()

let material = new Cesium.Material({
  fabric: {
    type: 'Color',
    uniforms: {
      color: new Cesium.Color(1.0, 1.0, 0.0, 1.0)
    }
  }
});

这种方法直接传入一个fabric(fabric 是对材质描述json对象)。此方法适用于创建一个新材质,代码虽然冗长,但是灵活性最高。
Fabric拥有5个属性:
1.type:用于声明fabric对象最终会生成什么材质。若是之前没有指定过,则第一次调用new Cesium.Material(),这个新材质会被缓存,可以之后从缓存中取用
2.uniforms:拥有若干个uniform的全局变量,可以在渲染前传入,也可以在渲染后修改
3.source:glsl 源代码,它主要是对 czm_getMaterial 这个函数(Cesium 内置的 glsl 函数)的实现,返回值是 czm_material,实现自定义渲染效果
4.components:几个基本材质因子的 glsl 代码快捷入口,是 source 的一种简略实现,可以通过修改子因素直接改变材质的渲染结果
5.materials:允许再塞进去子一级的 fabric,构成复合材质

Material内部构成

1.Uniforms

uniforms是传入着色器Source中的一些全局变量,因为Source是GLSL源代码,所以数据类型会有些区别。统一值,用于向着色器内传递数据。
在这里插入图片描述
比较常用的比如:
1.float:浮点数
2.vec {2, 3, 4} :长度为2,3,4的float向量
3.sampler2D:访问一个二维纹理,s轴和t轴垂直大小在0到1之间,(0, 0)在左下角

2.Source 材质着色器代码

Source为glsl 源代码,它主要是对 这个Cesium 内置的 glsl 函数的实现,返回值是 czm_material,实现自定义渲染效果
默认情况下,材质Source的默认函数实现为:

czm_material czm_getMaterial(czm_materialInput materialInput)
{
	czm_material material =  czm_getDefaultMaterial(materialInput);  
	return material;
}

其中,czm_materialInput结构体为:

struct czm_materialInput
{
  float s;
  vec2 st;
  vec3 str;
  mat3 tangentToEyeMatrix;
  vec3 positionToEyeEC;
  vec3 normalEC;
};

czm_materialInput结构体在源码Shaders/Builtin/Structs/materialInput.js中定义,用于存储输入的纹理坐标,法线等数据。它包含了6个属性,分别为:
在这里插入图片描述
czm_material结构体为:

struct czm_material
{
  vec3 diffuse;
  float specular;
  float shininess;
  vec3 normal;
  vec3 emission;
  float alpha;
};

czm_material结构体在源码Shaders/Builtin/Structs/material.js中定义,用于存储Material着色器计算的结果。它包含了6个属性,其中diffuse为渲染返回的最基本的颜色,其他属性分别为:
在这里插入图片描述

Cesium内置材质

Cesium官方网站 可以查看,内置材质共计23种。列举两个比较常用的:
在这里插入图片描述
Color材质的Source源码:

uniform vec4 color_0;
czm_material czm_getMaterial(czm_materialInput materialInput)
{
	czm_material material = czm_getDefaultMaterial(materialInput);
	material.diffuse = czm_gammaCorrect(color_0.rgb); 
	material.alpha = color_0.a; 
	return material;
}

通过GLSL函数这段代码首先声明变量,用于接收我们上述提到的uniforms传递的数据(这些变量会自动添加一个序号,在Appearance中使用时也要添加这个序号)。
然后定义czm_getMaterial方法,方法的参数materialInput 是一个czm_materialInput 类型,方法内部通过materialInput作为输入参数又调用了Cesium内置算法进行计算,将rgb值传给material.diffuse,将alpha值传给material.alpha最终将计算结果存储到czm_material类型的变量material中作为返回值。

Image材质的Source为:

uniform vec4 color_2;
uniform vec2 repeat_1;
uniform sampler2D image_0;
czm_material czm_getMaterial(czm_materialInput materialInput)
{
	czm_material material = czm_getDefaultMaterial(materialInput);
	material.diffuse = czm_gammaCorrect(texture2D(image_0, fract(repeat_1 * materialInput.st)).rgb * color_2.rgb); 
	material.alpha = texture2D(image_0, fract(repeat_1 * materialInput.st)).a * color_2.a; 
	return material;
}

通过GLSL代码可以看出,Image材质的渲染逻辑就是传入一个图片纹理,根据纹理坐标采样图片纹理上的rgb值,还可以混合一个颜色值,将值赋予给material.diffuse,最后返回material
texture2D函数是webgl内置函数,传入两个参数,一个是图片,一个是纹理坐标

动态扩散圆示例

new Cesium.Material({
            fabric: {
                uniforms: {
                    color: Cesium.Color.fromCssColorString('#00E8FF'),
                    time: 10
                },
                source:`czm_material czm_getMaterial(czm_materialInput materialInput)
                       {
                           czm_material material = czm_getDefaultMaterial(materialInput);
                           material.diffuse = 1.5 * color.rgb;
                           vec2 st = materialInput.st;
                           float dis = distance(st, vec2(0.5, 0.5));
                           float per = fract(czm_frameNumber * time / 1000.0);
                           if(dis > per * 0.5) {
                             material.alpha = 0.0;
                             discard;
                           }else{
                             material.alpha = color.a * dis / per / 1.0;
                           }
                           return material;
                       }`
            }
        })

分析代码:

material.diffuse = 1.5*color.rgb:控制的效果是这个颜色的亮度。把1.5改成0.5它会明显变得更暗。如果把1.5改成3或者6,明显可以看到颜色更亮了
materialInput.st:整个画布的二维纹理坐标,vec2类型,第一个值是水平方向,如果是线,则为沿线方向,第二个值是垂直方向
dis:扩散中心,从哪个位置开始扩散的。如果改成distance(st, vec2(0.0, 0.5),那么它扩散的中心就变成了下方中点
czm_frameNumber:这个是当前渲染的帧数
fract():获取小数部分
discard:关键词在opengl中是片段截取的意思,相当于这一块不要了
请添加图片描述

Appearance构成

我们已MaterialAppearance为例,MaterialAppearance构造函数如下:
在这里插入图片描述
1.flat:平面着色,不考虑光照,当设置为true时,着色器就不使用光照计算,而去使用平面着色。
2.material :使用Cesium内置的材质进行着色计算。
3.vertexShaderSource:顶点着色器
4.fragmentShaderSource:片元着色器

下一篇节我们着重讲解一下vertexShaderSource顶点着色器与fragmentShaderSource片元着色器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GIS肆月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值