材质资料
Apperance
Cesium 的材质封装在 Cesium.MaterialAppearance/Cesium.Material 类中。
一般,Cesium 的 Primitive 由 GeometryInstance 和 Appearance 组成,GeometryInstance 是 Geometry 的实例,即可以在显存中只存一份顶点属性,然后创建多个相同的 Geometry,达到节省显存的目的。
如果设置 flat 为 false,则几何需要有法线;若flat 为 true 的效果,没有明暗关系,扁平的。
Closed: 该几何是否是闭合的,如果是闭合的,可以设为 true,开启背面剔除,例如一个球体,一个立方体。
vertexShaderSource 和 fragmentShaderSource 让它们默认的就好。
renderState 是封装了一些 WebGL 的全局变量,例如是否开启深度测试、是否开启 stencil test、是否开启 blending 等等,回想一下图形管线中的逐片段操作。
Material
在 Material 类中,我们主要设置 fabric 属性
其中,minificationFilter 和 magnificationFilter 分别是纹理缩小和放大时的插值方式,使用默认值的双线性插值就好。
Translucent 属性表示的是该材质是否是半透明的,可以是一个布尔值或者是一个返回布尔值的函数,如果你的材质是不透明的,则需要设为 false。
Frbric
fabric资料参考
fabric 对象主要有 3 个属性。
type 是该材质的类型名,之后可以根据材质名复用这个材质。
uniform 是着色器的输入,回想一下图形管线的输入部分。
source 是片段着色器中的一个函数,你需要实现它,定义自己的着色逻辑,之后 Cesium 会在片段着色器中调用你写的这个方法,获取材质对应的属性,然后应用 Phong 反射模型和太阳光的方向、颜色对物体的表面进行着色。
czm_getMaterial 函数会传入一个参数,该参数是材质的输入,包含了纹理坐标、法线,着色点到相机的向量等等。你需要在这个函数内实现自己着色逻辑,然后将漫反射、发光颜色、不透明度等值赋给 material.diffuse、material.emission、material.alpha 等等。
CesiumGLSL这里可以查找到对应的czm相应的cesium着色器变量
案例实现(卫星观测)
定义 MaterialAppearance
首先,我们定义一个 MaterialAppearance,flat 属性设为 false,因为我们有法线,translucent 属性设为 true,因为我们之后会把材质的 alpha 值设为 0,需要混合,然后 closed 属性设为 false,因为我们的圆锥需要渲染背面。
定义Material
材质的 translucent 半透明属性也设为 true,然后定义材质类型名,材质类型名可以随便填一个,uniform 是你需要传给片段着色器的值,这里定义了时间、速度、环的粗细程度、环的个数和环的颜色。Uniform 也可以是纹理,直接把图片的路径作为字符串传进去就可以了。
片元着色器代码
然后是片段着色器的代码,这里我们先把材质的漫反射设为传入颜色的一半,把材质的自发光设为传入的颜色值。
然后获取到纹理坐标 st,st 和 uv 代表的含义都是一样的,都是纹理坐标。
然后将传入的速度和粗细程度 clamp 到 0.001 到 10 的范围内。
下面的 x 的范围是 0 到 1,因为用了 fract 函数,这个函数的意义是取输入的数的小数部分。
st.y 的范围是 0 到 1,假设环数为 10,那乘以环数后,范围就是 0 到 10。然后再加上时间和速度的乘积,让纹理坐标沿着 y 轴方向动起来
为了让曲线平滑,我们可以使用指数函数和三角函数,也就是最后的 pow 和 sin。
加上指数函数后的结果是这样子的,这是不同 sharp 从 0 到 10 时的结果,可以看到底部平滑了,但顶部太尖锐了。
最后再加上 sin 函数,最后的结果是这样子。
然后把这个值作为材质的不透明度,效果如下