declare namespace pc {

    /**
     * @name pc.Material
     * @class A material determines how a particular mesh instance is rendered. It specifies the shader and render state that is
     * set before the mesh instance is submitted to the graphics device.
     * @description Create a new Material instance
     * @property {Number} alphaTest The alpha test reference value to control which fragments are written to the currently
     * active render target based on alpha value. All fragments with an alpha value of less than the alphaTest reference value
     * will be discarded. alphaTest defaults to 0 (all fragments pass).
     * @property {Boolean} alphaToCoverage Enables or disables alpha to coverage (WebGL2 only). When enabled, and if hardware anti-aliasing is on,
     * limited order-independent transparency can be achieved. Quality depends on the number of MSAA samples of the current render target.
     * It can nicely soften edges of otherwise sharp alpha cutouts, but isn't recommended for large area semi-transparent surfaces.
     * Note, that you don't need to enable blending to make alpha to coverage work. It will work without it, just like alphaTest.
     * @property {Boolean} alphaWrite If true, the alpha component of fragments generated by the shader of this material is written to
     * the color buffer of the currently active render target. If false, the alpha component will not be written. Defaults to true.
     * @property {Number} blendType Controls how primitives are blended when being written to the currently active render target.
     * Can be one of the following values:
     * <ul>
     * <li>{@link pc.BLEND_SUBTRACTIVE}: Subtract the color of the source fragment from the destination fragment and write the result to the frame buffer.</li>
     * <li>{@link pc.BLEND_ADDITIVE}: Add the color of the source fragment to the destination fragment and write the result to the frame buffer.</li>
     * <li>{@link pc.BLEND_NORMAL}: Enable simple translucency for materials such as glass. This is equivalent to enabling a source blend mode of pc.BLENDMODE_SRC_ALPHA and a destination blend mode of pc.BLENDMODE_ONE_MINUS_SRC_ALPHA.</li>
     * <li>{@link pc.BLEND_NONE}: Disable blending.</li>
     * <li>{@link pc.BLEND_PREMULTIPLIED}: Similar to pc.BLEND_NORMAL expect the source fragment is assumed to have already been multiplied by the source alpha value.</li>
     * <li>{@link pc.BLEND_MULTIPLICATIVE}: Multiply the color of the source fragment by the color of the destination fragment and write the result to the frame buffer.</li>
     * <li>{@link pc.BLEND_ADDITIVEALPHA}: Same as pc.BLEND_ADDITIVE except the source RGB is multiplied by the source alpha.</li>
     * </ul>
     * Defaults to pc.BLEND_NONE.
     * @property {Boolean} blueWrite If true, the blue component of fragments generated by the shader of this material is written to
     * the color buffer of the currently active render target. If false, the blue component will not be written. Defaults to true.
     * @property {Number} cull Controls how triangles are culled based on their face direction with respect to the viewpoint.
     * Can be one of the following values:
     * <ul>
     * <li>{@link pc.CULLFACE_NONE}: Do not cull triangles based on face direction.</li>
     * <li>{@link pc.CULLFACE_BACK}: Cull the back faces of triangles (do not render triangles facing away from the view point).</li>
     * <li>{@link pc.CULLFACE_FRONT}: Cull the front faces of triangles (do not render triangles facing towards the view point).</li>
     * <li>{@link pc.CULLFACE_FRONTANDBACK}: Cull both front and back faces (triangles will not be rendered).</li>
     * </ul>
     * Defaults to pc.CULLFACE_BACK.
     * @property {Boolean} depthTest If true, fragments generated by the shader of this material are only written to the
     * current render target if they pass the depth test. If false, fragments generated by the shader of this material are
     * written to the current render target regardless of what is in the depth buffer. Defaults to true.
     * @property {Boolean} depthWrite If true, fragments generated by the shader of this material write a depth value to
     * the depth buffer of the currently active render target. If false, no depth value is written. Defaults to true.
     * @property {Boolean} greenWrite If true, the green component of fragments generated by the shader of this material is written to
     * the color buffer of the currently active render target. If false, the green component will not be written. Defaults to true.
     * @property {String} name The name of the material.
     * @property {Boolean} redWrite If true, the red component of fragments generated by the shader of this material is written to
     * the color buffer of the currently active render target. If false, the red component will not be written. Defaults to true.
     * @property {pc.Shader} shader The shader used by this material to render mesh instances.
     * @property {pc.StencilParameters} stencilFront Stencil parameters for front faces (default is null).
     * @property {pc.StencilParameters} stencilBack Stencil parameters for back faces (default is null).
     * @author Will Eastcott and Arthur Rahteenko
     */
    class Material {

        alphaTest: number;
        alphaToCoverage: boolean;
        alphaWrite: boolean;
        blendType: number;
        blueWrite: boolean;
        cull: number;
        depthTest: boolean;
        depthWrite: boolean;
        greenWrite: boolean;
        name: string;
        redWrite: boolean;
        shader: pc.Shader;
        stencilFront: pc.StencilParameters;
        stencilBack: pc.StencilParameters;

        /**
         * @function
         * @name pc.Material#getParameter
         * @description Retrieves the specified shader parameter from a material.
         * @param {String} name The name of the parameter to query.
         * @returns {Object} The named parameter.
         * @author Will Eastcott
         */
        getParameter(name: string): number | any[] | pc.Texture;

        /**
         * @function
         * @name pc.Material#setParameter
         * @description Sets a shader parameter on a material.
         * @param {String} name The name of the parameter to set.
         * @param {Number|Array|pc.Texture} data The value for the specified parameter.
         * @author Will Eastcott
         */
        setParameter(name: string, data: number | any[] | pc.Texture, passFlags?: number): void;

        /**
         * @function
         * @name pc.Material#deleteParameter
         * @description Deletes a shader parameter on a material.
         * @param {String} name The name of the parameter to delete.
         * @author Will Eastcott
         */
        deleteParameter(name: string): void;

        /**
         * @function
         * @name pc.Material#setParameters
         * @description Pushes all material parameters into scope.
         * @author Will Eastcott
         */
        setParameters(): void;

        /**
         * @function
         * @name pc.Material#update
         * @description Applies any changes made to the material's properties.
         */
        update(): Error;

        /**
         * @function
         * @description Initializes the material with the properties in the specified data.
         * @name pc.Material#init
         * @param {Object} data The initial data for the material.
         */
        init(data: any): Error;
    }

    /**
     * @name pc.StencilParameters
     * @class Holds stencil test settings
     * @description Create a new StencilParameters instance
     * @property {Number} func Sets stencil test function. See pc.GraphicsDevice#setStencilFunc
     * @property {Number} ref Sets stencil test reference value. See pc.GraphicsDevice#setStencilFunc
     * @property {Number} fail Sets operation to perform if stencil test is failed. See pc.GraphicsDevice#setStencilOperation
     * @property {Number} zfail Sets operation to perform if depth test is failed. See pc.GraphicsDevice#setStencilOperation
     * @property {Number} zpass Sets operation to perform if both stencil and depth test are passed. See pc.GraphicsDevice#setStencilOperation
     * @property {Number} readMask Sets stencil test reading mask. See pc.GraphicsDevice#setStencilFunc
     * @property {Number} writeMask Sets stencil test writing mask. See pc.GraphicsDevice#setStencilOperation
    */
    class StencilParameters {
        constructor(options?: {
            func?: number;
            ref?: number;
            readMask?: number;
            writeMask?: number;
            fail?: number;
            zfail?: number;
            zpass?: number;
        })

        func: number;
        ref: number;
        readMask: number;
        writeMask: number;
        fail: number;
        zfail: number;
        zpass: number;


    }
}
