Get glb attribute in vertex shader

Hi,

@Marco13 can you tell me why I can’t access the attribute _DIRECTION to this glb file ?

content.glb (2.1 KB)

Primitive is missing attribute _DIRECTION, disabling custom vertex shader

I tried https://gltf.report/ and I have the attribute in the mesh !

( Yes I’m testing glb file :stuck_out_tongue: )

That’s not really much context here, but from quickly looking at the model the message that you posted (and making a few guesses), I think that the statement from the Custom Shader Guide is relevant here:

Custom attributes are also available, though they are renamed to use lowercase letters and underscores. For example, an attribute called _SURFACE_TEMPERATURE in the model would become fsInput.attributes.surface_temperature in the shader.

So a bare-bone, skeleton sandcastle with a custom shader for this model could be this:

const viewer = new Cesium.Viewer("cesiumContainer");

const url = "http://localhost:8003/content.glb";
const model = await Cesium.Model.fromGltfAsync({
  url: url,
});
viewer.scene.primitives.add(model);

const customShader = new Cesium.CustomShader({
  fragmentShaderText: `
    void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material)
    {
        vec4 direction = fsInput.attributes.direction;
        material.diffuse = direction.xyz;
    }
    `,
});
model.customShader = customShader;

Ok, i will look into it, @Marco13 can you add an offset option for the function :

    const model: Cesium.Model = await Cesium.Model.fromGltfAsync({
        // *** Use the 'gltf' option with the ArrayBuffer or Uint8Array ***
        gltf: uint8Array,

        // Positioning and other options remain the same
        modelMatrix: Cesium.Matrix4.IDENTITY,
        // scale: 1.0,
        // minimumPixelSize: 128,
        customShader: cs,
    })

with this function, it’s possible ( i know it’s not official ):

    const model: Cesium.Model = await Cesium.Model.fromPnts({
        arrayBuffer: buffer,
        resource,
        modelMatrix: Cesium.Matrix4.IDENTITY,
        enablePick: false,
        byteOffset: offset
    })

Do I have to make a merge request to do it ? @Gabby_Getz ?

it would avoid copy large data … because I’ve to do before :

const uint8Array = new Uint8Array(buffer, offset)

@Marco13
contentArrow.glb (2.1 KB)
you can find there a simple glb file, it’s impossible to get the attribute vsInput.attributes.TEXCOORD_0 work, or vsInput.attributes.texcoord_0

void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {

    vec2 uv = fsInput.attributes.texcoord_0;

    vec4 baseColor = texture(material.baseColorTexture, uv);

    fragOutput.color = baseColor;
}

the json inside :

{
   "asset":{
      "version":"2.0",
      "generator":"GlbWriter"
   },
   "scenes":[
      {
         "nodes":[
            0
         ]
      }
   ],
   "scene":0,
   "nodes":[
      {
         "mesh":0
      }
   ],
   "meshes":[
      {
         "primitives":[
            {
               "attributes":{
                  "POSITION":0,
                  "TEXCOORD_0":1,
                  "_CORNEROFFSET":2,
                  "_DIRECTION":3
               },
               "mode":4,
               "indices":4,
               "material":0
            }
         ]
      }
   ],
   "images":[
      {
         "bufferView":2,
         "mimeType":"image/png",
         "name":"ArrowAtlas"
      }
   ],
   "samplers":[
      {
         "magFilter":9729,
         "minFilter":9987,
         "wrapS":33071,
         "wrapT":33071
      }
   ],
   "textures":[
      {
         "source":0,
         "sampler":0
      }
   ],
   "materials":[
      {
         "pbrMetallicRoughness":{
            "baseColorTexture":{
               "index":0
            }
         },
         "doubleSided":true,
         "alphaMode":"BLEND",
         "name":"ArrowMaterial"
      }
   ],
   "accessors":[
      {
         "bufferView":0,
         "byteOffset":0,
         "componentType":5126,
         "count":4,
         "type":"VEC3",
         "min":[
            -703854.1875,
            3489286,
            5288048
         ],
         "max":[
            -703854.1875,
            3489286,
            5288048
         ]
      },
      {
         "bufferView":0,
         "byteOffset":12,
         "componentType":5126,
         "count":4,
         "type":"VEC2"
      },
      {
         "bufferView":0,
         "byteOffset":20,
         "componentType":5126,
         "count":4,
         "type":"VEC2"
      },
      {
         "bufferView":0,
         "byteOffset":28,
         "componentType":5126,
         "count":4,
         "type":"VEC3"
      },
      {
         "bufferView":1,
         "byteOffset":0,
         "componentType":5121,
         "count":6,
         "type":"SCALAR",
         "max":[
            3
         ],
         "min":[
            0
         ]
      }
   ],
   "bufferViews":[
      {
         "buffer":0,
         "byteOffset":692,
         "byteLength":160,
         "byteStride":40,
         "target":34962
      },
      {
         "buffer":0,
         "byteOffset":852,
         "byteLength":6,
         "target":34963
      },
      {
         "buffer":0,
         "byteOffset":0,
         "byteLength":691
      }
   ],
   "buffers":[
      {
         "byteLength":858
      }
   ]
}

But texCoord_0 should work.

const viewer = new Cesium.Viewer("cesiumContainer");

const url = "http://localhost:8003/contentArrow.glb";
const model = await Cesium.Model.fromGltfAsync({
  url: url,
});
viewer.scene.primitives.add(model);

const customShader = new Cesium.CustomShader({
  fragmentShaderText: `
    void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material)
    {
        vec2 tc = fsInput.attributes.texCoord_0;
        material.diffuse = vec3(tc.x, tc.y, 1.0);
    }
    `,
});
model.customShader = customShader;

When there is a compilation error, then it should dump out the shader string that failed to compile. Examining this might bring insights. In this case, it may be worth mentioning that texture coordinates are not just “arbitrary attributes” (in fact, I’m nearly surprised that they can be accessed like that).

1 Like