How to get fixed coordinate in fragment shader when making a custom material?

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:

  1. 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.

  2. I find a built-in material GridMaterial that its grid line will always be fixed pixel, I find it use dFdx() and dFdy() 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.

1 Like