I want to get a coordinate of 0~geometry’s max x(y) rather than 0~1 because I want to draw some fixed pixel shapes, but i don’t know how, could someone help me?
And I’ve also ask a question on stackoverflow: https://stackoverflow.com/questions/69025380/how-to-draw-fixed-pixels-images-in-custom-material-property-with-cesium/69025637#69025637.
And I tried some ways:
-
Use
gl_FragCoord
, that’s works fun but with a problem, the material will move when I move the screen, and even i change the pitch of camera, the material is still facing me. -
I find a built-in material
GridMaterial
that its grid line will always be fixed pixel, I find it usedFdx()
anddFdy()
in source code. I use them and really get the coord, it works fun in my glslCanvas, but when I copy my code to my cesium project and run it, the material was completely suck, the code and screen shots are shown below:
function SpotMaterialProperty(color) {
this._definitionChanged = new Cesium.Event()
this._color = undefined
this._colorSubscription = undefined
this._time = Date.now()
this.color = Cesium.defaultValue(color, Cesium.Color.WHITE)
}
Object.defineProperties(SpotMaterialProperty.prototype, {
isConstant: {
get: function () {
return false
}
},
definitionChanged: {
get: function () {
return this._definitionChanged
}
},
color: Cesium.createPropertyDescriptor('color')
})
SpotMaterialProperty.prototype.getType = function () {
return 'Spot'
}
SpotMaterialProperty.prototype.getValue = function (time, result) {
if (!Cesium.defined(result)) {
result = {}
}
result.color = Cesium.Property.getValueOrUndefined(this._color, time)
result.time = (Date.now() - this._time) / 1000
return result
}
SpotMaterialProperty.prototype.equals = function (other) {
return (
this === other ||
(other instanceof SpotMaterialProperty && Cesium.Property.equals(this._color, other._color))
)
}
SpotMaterialProperty.prototype.setNow = function () {
this._time = Date.now()
}
Cesium.Material.SpotMaterialSource = `
#extension GL_OES_standard_derivatives : enable
uniform float time;
uniform vec4 color;
vec2 get_coord(vec2 st) {
vec2 dx = dFdx(st);
vec2 dy = dFdy(st);
float pixel_size_x = length(dx);
float pixel_size_y = length(dy);
return vec2(st.x / pixel_size_x, st.y / pixel_size_y);
}
float random(vec2 st) {
return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) *
43758.5453123);
}
float in_range(float v, vec2 range) {
return max(range.s, min(range.t, v));
}
float flash(vec2 st) {
float alpha = time * .5 - random(st);
return in_range(alpha, vec2(0., 1.));
}
float circle(vec2 st) {
float x = floor(st.x);
float y = floor(st.y);
float rx = mod(x, 2.);
float ry = mod(y, 2.);
if(rx == 0. || ry == 0.) {
return 0.;
}
vec2 center = vec2(x + .5, y + .5);
float circle = step(.5, length(st - center));
return circle == 0. ? flash(vec2(x, y)) : 0.;
}
czm_material czm_getMaterial (czm_materialInput materialInput) {
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st.xy;
// vec2 coord = gl_FragCoord.xy;
vec2 coord = get_coord(st);
float size = 2.;
coord /= size;
vec4 f = color;
vec4 bg = vec4(f.rgb, f.a * .1);
float circle = circle(coord);
f.a *= circle;
f += bg;
material.diffuse = f.rgb;
material.alpha = f.a;
return material;
}`
Cesium.Material.SpotType = 'Spot'
Cesium.SpotMaterialProperty = SpotMaterialProperty
Cesium.Material._materialCache.addMaterial(Cesium.Material.SpotType, {
fabric: {
type: Cesium.Material.SpotType,
uniforms: {
color: Cesium.Color.WHITE,
time: 0
},
source: Cesium.Material.SpotMaterialSource
},
translucent: function (material) {
return material.uniforms.color.alpha < 1.0
}
})
It’s easy to see that the material became less and less clear as the level increased, even like a noise view.
If there anyone that could help? I really need help, thanks in advance.