public override void GenerateShader(MaterialGeneratorContext context)
        {
            // TODO: Look through the compositions and don't add the discard mixin if it has already been added?
            // TODO: That doesn't seem to work well because the diffuse shader doesn't get recreated when the specular one is being recreated... unless I'm wrong about that.

            var shaderSource = new ShaderMixinSource();

            shaderSource.Mixins.Add(new ShaderClassSource("MaterialSurfaceShadingSpecularHair", (int)ShadingModel, DebugRenderPasses));

            shaderSource.AddComposition("hairLightAttenuationFunction", LightAttenuationFunction.Generate(context));
            shaderSource.AddComposition("hairDirectionFunction", HairDirectionFunction.Generate(context));
            shaderSource.AddComposition("hairShadowingFunction", HairShadowingFunction.Generate(context));
            shaderSource.AddComposition("environmentFunction", Environment.Generate(context));

            AddSpecularHighlightsShiftNoiseTexture(context, shaderSource);
            AddSecondarySpecularGlintsNoiseTexture(context, shaderSource);

            HairShared.SetMaterialPassParameters(context, shaderSource, AlphaThreshold); // Set the rendering parameters and generate the pass-dependent compositions.

            // Set the additional parameters used only in the specular shading model:
            var parameters = context.MaterialPass.Parameters;

            parameters.Set(MaterialSurfaceShadingSpecularHairKeys.HairScalesAngle, MathUtil.DegreesToRadians(ScalesAngle));
            parameters.Set(MaterialSurfaceShadingSpecularHairKeys.HairSpecularShiftRatio, SpecularShiftRatio);
            parameters.Set(MaterialSurfaceShadingSpecularHairKeys.HairSpecularColor1, SpecularColor1);
            parameters.Set(MaterialSurfaceShadingSpecularHairKeys.HairSpecularColor2, SpecularColor2);
            parameters.Set(MaterialSurfaceShadingSpecularHairKeys.HairSpecularExponent1, SpecularExponent1);
            parameters.Set(MaterialSurfaceShadingSpecularHairKeys.HairSpecularExponent2, SpecularExponent2);
            parameters.Set(MaterialSurfaceShadingSpecularHairKeys.HairSpecularScale1, SpecularScale1);
            parameters.Set(MaterialSurfaceShadingSpecularHairKeys.HairSpecularScale2, SpecularScale2);
            parameters.Set(MaterialSurfaceShadingSpecularHairKeys.HairShiftNoiseScale, ShiftNoiseScale);
            parameters.Set(MaterialSurfaceShadingSpecularHairKeys.HairGlintsNoiseStrength, GlintsNoiseStrength);
            parameters.Set(MaterialKeys.UsePixelShaderWithDepthPass, true); // Indicates that the material requries the full pixel shader durin the depth-only passes (Z prepass or shadow map rendering).

            if (DebugRenderPasses)
            {
                parameters.Set(MaterialHairSharedKeys.PassID, context.PassIndex);   // For debugging the different hair passes.
            }

            var shaderBuilder = context.AddShading(this);

            shaderBuilder.LightDependentSurface = shaderSource;
        }
        public override void GenerateShader(MaterialGeneratorContext context)
        {
            var shaderSource = new ShaderMixinSource();

            shaderSource.Mixins.Add(new ShaderClassSource("MaterialSurfaceShadingDiffuseHair", IsEnergyConservative, (int)ShadingModel, DebugRenderPasses));

            shaderSource.AddComposition("hairLightAttenuationFunction", LightAttenuationFunction.Generate(context));
            shaderSource.AddComposition("hairDirectionFunction", HairDirectionFunction.Generate(context));
            shaderSource.AddComposition("hairShadowingFunction", HairShadowingFunction.Generate(context));

            HairShared.SetMaterialPassParameters(context, shaderSource, AlphaThreshold); // Set the rendering parameters and generate the pass-dependent compositions.

            context.Parameters.Set(MaterialKeys.UsePixelShaderWithDepthPass, true);      // Indicates that material requries using the pixel shader stage during the depth-only pass (Z prepass or shadow map rendering).

            if (DebugRenderPasses)
            {
                context.Parameters.Set(MaterialHairSharedKeys.PassID, context.PassIndex);   // For debugging the different hair passes.
            }

            var shaderBuilder = context.AddShading(this);

            shaderBuilder.LightDependentSurface = shaderSource;
        }