Search code examples
glslfragment-shaderdeck.gl

Deck.gl v9 custom fragment shader is broken (Error: Error during linking: Fragment shader is not compiled.)


I'm using deck.gl to visualise a text layer with rounded corners on the _TextBackground sublayer. My code is basically a copy of the following example but it won't work with deck.gl v9 (works fine on 8.x, if you change the version on codepen)

const {Deck, TextLayer, _TextBackgroundLayer} = deck;

const data = [
  {position: [-122.45, 37.78], text: 'San Francisco'},
  {position: [-0.122, 51.51], text: 'London'},
  {position: [-58.59, -34.62], text: 'Buenos Aires'},
  {position: [174.57, -36.86], text: 'Aukland'}
];

class MyBackgroundLayer extends _TextBackgroundLayer {
  getShaders() {
    return {
      ...super.getShaders(),
      inject: {
        'fs:#decl': `
uniform float cornerRadius;
        `,
        'fs:#main-end': `
if (cornerRadius > 0.0) {
  vec2 r = (abs(uv - 0.5) - 0.5) * dimensions + cornerRadius;
  if (r.x > 0.0 && r.y > 0.0) {
    float a = smoothstep(cornerRadius + 0.5, max(cornerRadius - 0.5, 0.0), length(r));
    if (a == 0.0) discard;
    gl_FragColor.a *= a;
  }
}`
      }
    }
  }
  
  draw(params) {
    const {cornerRadius = 0} = this.props;
    params.uniforms.cornerRadius = cornerRadius;
    super.draw(params);
  }
}

new Deck({
  initialViewState: {
    longitude: 0,
    latitude: 0,
    zoom: 0
  },
  controller: true,
  layers: [
    new TextLayer({
      data,
      getText: d => d.text,
      getPosition: d => d.position,
      getColor: [255, 255, 255],
      getSize: 20,
      background: true,
      getBackgroundColor: [0, 0, 0],
      backgroundPadding: [20, 4],
      
      _subLayerProps: {
        background: {
          type: MyBackgroundLayer,
          cornerRadius: 10
        }
      }
    })
  ]
});

According to their docs:

The new (v9) version of luma.gl has been rewritten to adopt a WebGPU-compatible interface, while maintaining full support for WebGL2. deck.gl v9 has been extensively refactored on top of the new luma.gl API, but the deck.gl API itself includes minimal changes. This should allow applications to smoothly update to the latest version.

I can't seem to get it to work, and the deckgl examples haven't been very helpful. If anyone has any pointers please let me know, thanks!


Solution

  • Turns out geck.gl v9 shades have been updated to use GLSL 300, which has removed the default output variables like gl_FragColor Simply renaming it to fragColor fixes the issue