How can I pass material.uniform.color to custom fragment shader in MaterialAppearance

today, I start ready to learn write my own custom fragment shader in MaterialAppearance.But when I tried to pass user defined uniform color to custom fragment shader. Chrome tells me that color is undefined, how to pass it,please help!
here is my code:
var redColor = (56.0/255.0) + ((187.0/255.0) - (56.0/255.0))

  var greenColor = (139.0/255.0) + ((186.0/255.0) - (139.0/255.0))

  var blueColor = (255.0/255.0) + ((236.0/255.0) - (255.0/255.0))

  const aper = new Cesium.MaterialAppearance({

    translucent: true,

    material:new Cesium.Material.fromType('Color', {

        color : new Cesium.Color(redColor,greenColor,blueColor,1.0)

    }),

    vertexShaderSource: `

            attribute vec3 position3DHigh;

            attribute vec3 position3DLow;

            attribute vec3 normal;

            attribute vec2 st;

            attribute float batchId;

            varying vec4 v_positionEC;

            varying vec3 v_normalEC;

            void main()

            {

                vec4 p = czm_computePosition();

                vec4 eyePosition = czm_modelViewRelativeToEye * p;

                v_positionEC =  czm_inverseModelView * eyePosition;      // position in eye coordinates

                v_normalEC = czm_normal * normal;                         // normal in eye coordinates

                gl_Position = czm_modelViewProjectionRelativeToEye * p;

            }

      `,

   

    fragmentShaderSource: `varying vec4 v_positionEC;

                            varying vec3 v_normalEC;

                            void main() {

                              float l = sqrt(pow(v_positionEC.x,2.0) + pow(v_positionEC.y,2.0) + pow(v_positionEC.z,2.0));

                              

                              float cy3 = fract((abs(l - 100000.0))/600000.0);

                              float cr = color.r*cy3;

                              float cg = color.g*cy3;

                              float cb = color.b*cy3;

                              gl_FragColor = vec4(cr, cg, cb, 1.0);

                    }`

  })

  let instance =  new Cesium.GeometryInstance({

    geometry: new Cesium.PolygonGeometry({

      polygonHierarchy : new Cesium.PolygonHierarchy(

        Cesium.Cartesian3.fromDegreesArray([

          116.0, 29.0,

          // 126.0, 25.0,

          110.0, 20.0,

          126.0, 20.0,

          133.0, 29.0

        ])

      ),

      

      extrudedHeight: 300000

    })

  });

  var primitive = new Cesium.Primitive({

    geometryInstances: [instance],

    appearance: aper,

    releaseGeometryInstances: false,

    compressVertices: false,

  })

here is the error message
image
And I found an example
and code likes this still goes error:

const aper = new Cesium.MaterialAppearance({

        translucent: true,

        material : new Cesium.Material({

          strict: false,

          translucent: false,

          fabric: {

            uniforms: {

              color : new Cesium.Color(redColor,greenColor,blueColor,1.0)

            },

          },

        }),


        vertexShaderSource: `

                attribute vec3 position3DHigh;

                attribute vec3 position3DLow;

                attribute vec3 normal;

                attribute vec2 st;

                attribute float batchId;

                varying vec4 v_positionEC;

                varying vec3 v_normalEC;

                void main()

                {

                    vec4 p = czm_computePosition();

                    vec4 eyePosition = czm_modelViewRelativeToEye * p;

                    v_positionEC =  czm_inverseModelView * eyePosition;      // position in eye coordinates

                    v_normalEC = czm_normal * normal;                         // normal in eye coordinates

                    gl_Position = czm_modelViewProjectionRelativeToEye * p;

                }

          `,

       

        fragmentShaderSource: `varying vec4 v_positionEC;

                                varying vec3 v_normalEC;

                                void main() {

                                  float l = sqrt(pow(v_positionEC.x,2.0) + pow(v_positionEC.y,2.0) + pow(v_positionEC.z,2.0));

                                  //(l - 100000.0)/600000.0

                                  float cy3 = fract((abs(l - 100000.0))/600000.0);

                                  float cr = color.r*cy3;

                                  float cg = color.g*cy3;

                                  float cb = color.b*cy3;

                                  gl_FragColor = vec4(cr, cg, cb, 1.0*cy3);

                        }`

      })

      let instance =  new Cesium.GeometryInstance({

        geometry: new Cesium.PolygonGeometry({

          polygonHierarchy : new Cesium.PolygonHierarchy(

            Cesium.Cartesian3.fromDegreesArray([

              116.0, 29.0,

              // 126.0, 25.0,

              110.0, 20.0,

              126.0, 20.0,

              133.0, 29.0

            ])

          ),

          extrudedHeight: 300000

        })

      });

      var primitive = new Cesium.Primitive({

        geometryInstances: [instance],

        appearance: aper,

        releaseGeometryInstances: false,

        compressVertices: false,

      })

@Noah-Gilga

Thank you for sharing this question with the community! To be candid, I do not have a lot of experience creating custom shaders. However, it seems like the best place to start would be to investigate how you are updating the color variable. For reference, here is our Color documentation

https://cesium.com/learn/cesiumjs/ref-doc/Color.html?classFilter=color

Something like

var redColor = new Cesium.Color(1.0,0.0,0.0,1.0);

seems appropriate. Please let me know if you have any other questions or concerns!

-Sam

@sam.rothstein
Hi Sam, thanks for your answer.I have used the color variable like this and use it in MaterialAppearance.uniforms :

var redColor = (56.0/255.0) + ((187.0/255.0) - (56.0/255.0));
var greenColor = (139.0/255.0) + ((186.0/255.0) - (139.0/255.0));
var blueColor = (255.0/255.0) + ((236.0/255.0) - (255.0/255.0));

uniforms: {
   testColor : new Cesium.Color(redColor,greenColor,blueColor,1.0)
},

But when i declare testColor in fragmentShaderSource as an uniform variable, program goes wrong and said “uniformMap[mu.name] is not a function”.Here’s my demo in sandcastle.

Well, in your shared example you’re creating uniforms for the Cesium.MaterialAppearance, but it doesn’t support that so that won’t work. I think the idea is to inject the shader into the same level where you’ve got a Fabric, that’s where the uniforms can be accessed. Haven’t played much with this part of Cesium, so grains of salt apply accordingly.

Cheers,

Alex

2 Likes

Are there any docs on this? Thank you

you got the solution right now?I have a same problem

Hi @pengpengpengpen9 ,
Thanks for posting in the Cesium forums!

I am not sure if your question is general or specific.

We have overview documentation on custom shaders here cesium/Documentation/CustomShaderGuide/README.md at main · CesiumGS/cesium · GitHub

And several sandcastle examples covering common use cases with custom shaders

If your question is more specific, are you able to share more details and possibly sample code that we can use to assist you?

Thank you,
Luke