Fabric в CesiumJS представляет собой декларативный формат описания материалов, используемых в рендеринге геометрии на поверхности и в трёхмерном пространстве. Он служит промежуточным слоем между высокоуровневыми объектами сцены и низкоуровневым GLSL-кодом шейдеров.
Основная идея заключается в том, что материал описывается как JSON-структура, содержащая:
Fabric используется в механизмах MaterialAppearance,
EllipsoidSurfaceAppearance, а также в описаниях сущностей
CZML и некоторых стилях Entity.
Типичная структура Fabric выглядит следующим образом:
{
type: 'Color',
uniforms: {
color: Cesium.Color.RED
}
}
или в расширенной форме:
{
type: 'MyCustomMaterial',
uniforms: {
time: 0.0,
speed: 2.0
},
source: `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
czm_material material = czm_getDefaultMaterial(materialInput);
material.diffuse = vec3(1.0, 0.0, 0.0);
material.alpha = 1.0;
return material;
}
`
}
Определяет тип материала.
Color, Image,
Checkerboard, Stripe,
PolylineGlow и др.sourceОбъект параметров, передаваемых в шейдер.
Примеры значений:
float)Cartesian2, Cartesian3)Color)Image → sampler2D)uniforms: {
color: Cesium.Color.BLUE.withAlpha(0.5),
repeat: new Cesium.Cartesian2(4.0, 4.0),
time: 1.0
}
GLSL-код фрагментного шейдера, реализующий логику материала.
Обязательная функция:
czm_material czm_getMaterial(czm_materialInput materialInput)
Она должна возвращать структуру czm_material,
содержащую:
diffuse — базовый цветalpha — прозрачностьИспользуется для композиции нескольких материалов в один.
{
components: {
diffuse: ['diffuseMap', 'colorOverlay'],
alpha: 'alphaMask'
}
}
Компонентный подход позволяет комбинировать несколько Fabric-описаний в единый материал.
CesiumJS предоставляет набор предопределённых Fabric-материалов.
Простейший материал, задающий сплошной цвет.
{
type: 'Color',
uniforms: {
color: Cesium.Color.YELLOW
}
}
Использует текстуру.
{
type: 'Image',
uniforms: {
image: 'texture.png',
repeat: new Cesium.Cartesian2(2.0, 2.0)
}
}
Шахматный паттерн.
{
type: 'Checkerboard',
uniforms: {
evenColor: Cesium.Color.WHITE,
oddColor: Cesium.Color.BLACK,
repeat: new Cesium.Cartesian2(8.0, 8.0)
}
}
Полосатый материал.
{
type: 'Stripe',
uniforms: {
horizontal: true,
offset: 0.0,
repeat: 5.0
}
}
Используется для линий с эффектом свечения.
{
type: 'PolylineGlow',
uniforms: {
glowPower: 0.2,
color: Cesium.Color.CYAN
}
}
Пользовательский материал создаётся через комбинацию
type и source.
const customMaterial = {
fabric: {
type: 'CustomPulse',
uniforms: {
frequency: 10.0,
color: Cesium.Color.ORANGE
},
source: `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
czm_material material = czm_getDefaultMaterial(materialInput);
float intensity = abs(sin(materialInput.st.s * frequency));
material.diffuse = color.rgb * intensity;
material.alpha = 1.0;
return material;
}
`
}
};
GLSL-код в Fabric имеет доступ к встроенным Cesium переменным:
materialInput.st — UV-координатыczm_frameNumber — номер кадраczm_viewerPosition — позиция камерыczm_material — структура результатаПример динамического эффекта:
float wave = sin(materialInput.st.t * 10.0 + czm_frameNumber * 0.1);
В CZML Fabric используется для описания материалов объектов напрямую в JSON-потоке.
{
"polygon": {
"material": {
"fabric": {
"type": "Stripe",
"uniforms": {
"evenColor": {
"rgba": [255, 0, 0, 255]
},
"oddColor": {
"rgba": [0, 0, 255, 255]
},
"repeat": 10.0
}
}
}
}
}
Особенность CZML заключается в сериализации типов Cesium в JSON-формат, где цвета и векторы представлены примитивными структурами.
Fabric является основой для MaterialAppearance:
const appearance = new Cesium.MaterialAppearance({
material: Cesium.Material.fromType('Color', {
color: Cesium.Color.GREEN
})
});
или через явное Fabric-описание:
const material = new Cesium.Material({
fabric: {
type: 'Color',
uniforms: {
color: Cesium.Color.RED
}
}
});
Композиционные Fabric позволяют накладывать эффекты слоями.
Пример комбинирования:
{
components: {
diffuse: ['baseTexture', 'lightingEffect'],
alpha: 'fadeEffect'
}
}
Каждый компонент может быть отдельным Fabric-материалом, что позволяет строить сложные визуальные эффекты без единого большого шейдера.
Fabric напрямую транслируется в GLSL, поэтому:
Критические моменты:
source ухудшают batching геометрииuniforms: {
time: 0.0
}
float wave = sin(materialInput.st.s * 10.0 + time);
material.alpha = step(0.5, materialInput.st.t);
material.diffuse = mix(colorA.rgb, colorB.rgb, materialInput.st.t);
czm_materialFabric не является самостоятельной системой рендеринга, а транслируется в:
Это делает Fabric промежуточным DSL (domain-specific language) между JavaScript и GPU-шейдером.
sourceczm_materialCartesian3)Fabric поддерживает:
if, for)czm_saturation,
czm_luminance)Пример смешанного эффекта:
float noise = fract(sin(dot(materialInput.st, vec2(12.9898,78.233))) * 43758.5453);
material.diffuse = mix(color.rgb, vec3(noise), 0.5);