{
    "title": "Material",
    "description": "A material composed of uniforms, an czm_getMaterial GLSL function, and potentially other materials.",
    "type": "object",
    "properties": {
        "type": {
            "type": "string",
            "description": "A unique identifier for this material type."
        },
        
        "materials": {
            "type": "object",
            "description": "Materials used by this material.  This enables building a hierarchy of materials.  For example, reflection and refraction materials can be combined to create a Fresnel material, and then the Fresnel material can be combined with a specular map material to create a water material.",
            "properties": {
            },
            "additionalProperties": {
                "$ref": "Material.schema.json"
            }
        },
        
        "uniforms": {
            "type": "object",
            "description": "Uniform variables, and their default values, that are input to this material.  Texture and cube-map face uniform values are specified as an image URL or a <a href=\"https://developer.mozilla.org/en/data_URIs\">data URI</a>.  Alternatively, a placeholder RGBA white texture can be used by specifying czm_defaultImage or czm_defaultCubeMap for textures or cube-maps, respectively.",
            "properties": {
            },
            "additionalProperties": {
                "type": ["string", "number", "integer", "boolean", "object", "array"],

                "format": "uri",
                
                "items": {
                    "type": "number",
                    "description": "A floating-point component in a mat2, mat3, or mat4."
                },
                "minItems" : 4,
                "maxItems" : 16,
                
                "properties": {
                    "x": {
                        "type": ["number", "integer", "boolean"],
                        "description": "The x component of a floating-point, integer, or boolean vec2, vec3, or vec4."
                    },
                    "y": {
                        "type": ["number", "integer", "boolean"],
                        "description": "The y component of a floating-point, integer, or boolean vec2, vec3, or vec4."
                    },
                    "z": {
                        "type": ["number", "integer", "boolean"],
                        "description": "The z component of a floating-point, integer, or boolean vec3 or vec4."
                    },
                    "w": {
                        "type": ["number", "integer", "boolean"],
                        "description": "The w component of a floating-point, integer, or boolean vec4."
                    },
                    
                    "r": {
                        "type": ["number", "integer", "boolean"],
                        "description": "The r component of a floating-point, integer, or boolean vec2, vec3, or vec4."
                    },
                    "g": {
                        "type": ["number", "integer", "boolean"],
                        "description": "The g component of a floating-point, integer, or boolean vec2, vec3, or vec4."
                    },
                    "b": {
                        "type": ["number", "integer", "boolean"],
                        "description": "The b component of a floating-point, integer, or boolean vec3 or vec4."
                    },
                    "a": {
                        "type": ["number", "integer", "boolean"],
                        "description": "The a component of a floating-point, integer, or boolean vec4."
                    },
                    
                    "s": {
                        "type": ["number", "integer", "boolean"],
                        "description": "The r component of a floating-point, integer, or boolean vec2, vec3, or vec4."
                    },
                    "t": {
                        "type": ["number", "integer", "boolean"],
                        "description": "The g component of a floating-point, integer, or boolean vec2, vec3, or vec4."
                    },
                    "p": {
                        "type": ["number", "integer", "boolean"],
                        "description": "The b component of a floating-point, integer, or boolean vec3 or vec4."
                    },
                    "q": {
                        "type": ["number", "integer", "boolean"],
                        "description": "The a component of a floating-point, integer, or boolean vec4."
                    },
                    
                    "positiveX": {
                        "type": "string",
                        "format": "uri",
                        "description": "An image for the +x side of a cube map.  The image is specified as a URL.  For broadest client compatibility, the URL should be accessible via Cross-Origin Resource Sharing (CORS).  The URL may also be a <a href=\"https://developer.mozilla.org/en/data_URIs\">data URI</a>."
                    },
                    "negativeX": {
                        "type": "string",
                        "format": "uri",
                        "description": "An image for the -x side of a cube map.  The image is specified as a URL.  For broadest client compatibility, the URL should be accessible via Cross-Origin Resource Sharing (CORS).  The URL may also be a <a href=\"https://developer.mozilla.org/en/data_URIs\">data URI</a>."
                    },
                    "positiveY": {
                        "type": "string",
                        "format": "uri",
                        "description": "An image for the +y side of a cube map.  The image is specified as a URL.  For broadest client compatibility, the URL should be accessible via Cross-Origin Resource Sharing (CORS).  The URL may also be a <a href=\"https://developer.mozilla.org/en/data_URIs\">data URI</a>."
                    },
                    "negativeY": {
                        "type": "string",
                        "format": "uri",
                        "description": "An image for the -y side of a cube map.  The image is specified as a URL.  For broadest client compatibility, the URL should be accessible via Cross-Origin Resource Sharing (CORS).  The URL may also be a <a href=\"https://developer.mozilla.org/en/data_URIs\">data URI</a>."
                    },
                    "positiveZ": {
                        "type": "string",
                        "format": "uri",
                        "description": "An image for the +z side of a cube map.  The image is specified as a URL.  For broadest client compatibility, the URL should be accessible via Cross-Origin Resource Sharing (CORS).  The URL may also be a <a href=\"https://developer.mozilla.org/en/data_URIs\">data URI</a>."
                    },
                    "negativeZ": {
                        "type": "string",
                        "format": "uri",
                        "description": "An image for the -z side of a cube map.  The image is specified as a URL.  For broadest client compatibility, the URL should be accessible via Cross-Origin Resource Sharing (CORS).  The URL may also be a <a href=\"https://developer.mozilla.org/en/data_URIs\">data URI</a>."
                    }
                },
                "dependencies": {
                    "x": "y",
                    "y": "x",
                    "z": ["x", "y"],
                    "w": ["x", "y", "z"],
                    
                    "r": "g",
                    "g": "r",
                    "b": ["r", "g"],
                    "a": ["r", "g", "b"],

                    "s": "t",
                    "t": "s",
                    "p": ["s", "t"],
                    "q": ["s", "t", "p"],
                    
                    "positiveX": ["negativeX", "positiveY", "negativeY", "positiveZ", "negativeZ"],
                    "negativeX": ["positiveX", "positiveY", "negativeY", "positiveZ", "negativeZ"],
                    "positiveY": ["positiveX", "negativeX", "negativeY", "positiveZ", "negativeZ"],
                    "negativeY": ["positiveX", "negativeX", "positiveY", "positiveZ", "negativeZ"],
                    "positiveZ": ["positiveX", "negativeX", "positiveY", "negativeY", "negativeZ"],
                    "negativeZ": ["positiveX", "negativeX", "positiveY", "negativeY", "positiveZ"]
                },
                "additionalProperties": false
            }
        },
        
        "components": {
            "type": "object",
            "description": "The diffuse, specular, normal, emission, and alpha components returned by this material.  The components or source property is required, but not both.",
            "properties": {
                "diffuse" : {
                    "type": "string",
                    "default" : "vec3(0.0)",
                    "description": "A GLSL expression returning the diffuse component of this material.  The diffuse component is a vec3 defining incoming light that scatters evenly in all directions."
                },
                "specular" : {
                    "type": "string",
                    "default" : "0.0",
                    "description": "A GLSL expression returning the specular component of this material.  The specular component is a float defining the intensity of incoming light reflecting in a single direction."
                },
                "shininess" : {
                    "type": "string",
                    "default" : "1.0",
                    "description": "A GLSL expression returning the shininess component of this material.  Shininess is the sharpness of the specular reflection.  Higher values create a smaller, more focused specular highlight."
                },
                "normal" : {
                    "type": "string",
                    "description": "A GLSL expression returning the normal component of this material.  The normal component is a vec3 defining the surface's normal in eye coordinates.  It is used for effects such as normal mapping.  The default is the surface's unmodified normal."
                },
                "emission" : {
                    "type": "string",
                    "default" : "vec3(0.0)",
                    "description": "A GLSL expression returning the emission component of this material.  The emission component is a vec3 defining light emitted by the material equally in all directions.  The default is vec3(0.0), which emits no light."
                },
                "alpha" : {
                    "type": "string",
                    "default" : "1.0",
                    "description": "A GLSL expression returning the alpha component of this material.  The alpha component is a float defining the opacity of this material.  0.0 is completely transparent; 1.0 is completely opaque."
                }
            }
        },
        "source": {
            "type": "string",
            "description": "GLSL source for the czm_getMaterial function with a full function definition.  The components or source property is required, but not both.",
            "pattern" : "czm_getMaterial"
        }
    }
}