1. A concise explanation of the problem you’re experiencing.
We are making a application that provides realtime information on vehicles based on GPS position. As a way to distinguish which areas are supported, we are currently rendering roads on top of the terrain.
We first tried using the ImageMaterialProperty but the we wanted it to automatically update the repeat without having to set any number on our end. For that we followed the answers on this topics: using-wallpaper-material-with-primitive-collection and repeating-image-pattern but “Texture2D” is no longer supported.
Afterwards, I tried to create/use the material “Asphalt” described on the cesium-materials-pack I have noticed that it is no longer supported and the materials no longer work.
2. A minimal code example. If you’ve found a bug, this helps us reproduce and repair it.
The code to create a using the image anchor to calculate the amount of repeats:
//Call this once at application startup
Cesium.Material._materialCache.addMaterial('Wallpaper', {
fabric : {
type : 'Wallpaper',
uniforms : {
image : Cesium.Material.DefaultImageId,
anchor : new Cesium.Cartesian2(0, 0)
},
components : {
diffuse : 'texture2D(image, fract((gl_FragCoord.xy - anchor.xy) / vec2(imageDimensions.xy))).rgb',
alpha : 'texture2D(image, fract((gl_FragCoord.xy - anchor.xy) / vec2(imageDimensions.xy))).a'
}
},
translucent : false
});
//Create an instance and assign to anything that has a material property.
//scene - the scene
//image - the image (I think both a url or Image object are supported)
//anchor - A Cartesian3 that is the most southern and westard point of the geometry
var WallPaperMaterialProperty = function(scene, image, anchor) {
this._scene = scene;
this._image = image;
this._anchor = anchor;
this.definitionChanged = new Cesium.Event();
this.isConstant = true;
};
WallPaperMaterialProperty.prototype.getType = function(time) {
return 'Wallpaper';
};
WallPaperMaterialProperty.prototype.getValue = function(time, result) {
if (!Cesium.defined(result)) {
result = {
image : undefined,
anchor : undefined
};
}
result.image = this._image;
result.anchor = Cesium.SceneTransforms.wgs84ToDrawingBufferCoordinates(this._scene, this._anchor, result.anchor);
if(Cesium.defined(result.anchor)){
result.anchor.x = Math.floor(result.anchor.x);
result.anchor.y = Math.floor(result.anchor.y);
} else {
result.anchor = new Cesium.Cartesian2(0, 0);
}
return result;
};
WallPaperMaterialProperty.prototype.equals = function(other) {
return this === other || //
(other instanceof WallPaperMaterialProperty && //
this._image === other._image);
};
//Here's a working example.
var viewer = new Cesium.Viewer('cesiumContainer');
var entity = viewer.entities.add({
polygon : {
hierarchy : Cesium.Cartesian3.fromDegreesArray([-115.0, 37.0,
-115.0, 32.0,
-107.0, 33.0,
-102.0, 31.0,
-102.0, 35.0]),
material : new WallPaperMaterialProperty(viewer.scene, '../images/checkerboard.png', Cesium.Cartesian3.fromDegrees(-115.0, 31))
}
});
viewer.zoomTo(viewer.entities);
Code to reuse the “Asphalt” material:
Cesium.Material._materialCache.addMaterial('Wallpaper', {
fabric : {
type : "Asphalt",
uniforms : {
color : new Color(0.15, 0.15, 0.15, 1.0),
bumpSize : 0.2,
roughness : 0.2
},
source : `
uniform vec4 asphaltColor;
uniform float bumpSize;
uniform float roughness;
czm_material czm_getMaterial(czm_materialInput materialInput)
{
czm_material material = czm_getDefaultMaterial(materialInput);
// From Stefan Gustavson's Procedural Textures in GLSL in OpenGL Insights
//Main cellular pattern
vec4 color = asphaltColor;
vec2 st = materialInput.st;
vec2 F = czm_cellular(st / bumpSize);
color.rgb -= (F.x / F.y) * 0.1;
//Extra bumps for roughness
float noise = czm_snoise(st / bumpSize);
noise = pow(noise, 5.0) * roughness;
color.rgb += noise;
material.diffuse = color.rgb;
material.alpha = color.a;
return material;
}
});
3. Context. Why do you need to do this? We might know a better way to accomplish your goal.
We wanted to add a texture to the created roads not just a solid colour. However, if we use ImageMaterialProperty the look degrades significantly onZoom.
So our objective would either be creating a material with the look and feel of “Asphalt” or somehow creating another MaterialProperty that automatically updates the “repeat” to adapt the number of repetitions for each different “zoom”.
Is there any way in which we can achieve our objective?
4. The Cesium version you’re using, your operating system and browser.
-
Cesium Version: 1.105.2
-
Browser: Google Chrome
-
Operating System: MacOS Ventura