public override int GetHashCode()
 {
     unchecked
     {
         var hashCode = (int)ShadingModel;
         hashCode = (hashCode * 397) ^ SpecularExponent1.GetHashCode();
         hashCode = (hashCode * 397) ^ SpecularColor1.GetHashCode();
         hashCode = (hashCode * 397) ^ SpecularScale1.GetHashCode();
         hashCode = (hashCode * 397) ^ SpecularExponent2.GetHashCode();
         hashCode = (hashCode * 397) ^ SpecularColor2.GetHashCode();
         hashCode = (hashCode * 397) ^ SpecularScale2.GetHashCode();
         hashCode = (hashCode * 397) ^ SpecularShiftRatio.GetHashCode();
         hashCode = (hashCode * 397) ^ ScalesAngle.GetHashCode();
         hashCode = (hashCode * 397) ^ ShiftNoiseScale.GetHashCode();
         hashCode = (hashCode * 397) ^ GlintsNoiseStrength.GetHashCode();
         hashCode = (hashCode * 397) ^ AlphaThreshold.GetHashCode();
         hashCode = (hashCode * 397) ^ HairSpecularHighlightsShiftNoise.GetHashCode();
         hashCode = (hashCode * 397) ^ HairSecondarySpecularGlintsNoise.GetHashCode();
         hashCode = (hashCode * 397) ^ HairDirectionFunction.GetHashCode();
         hashCode = (hashCode * 397) ^ HairShadowingFunction.GetHashCode();
         hashCode = (hashCode * 397) ^ LightAttenuationFunction.GetHashCode();
         hashCode = (hashCode * 397) ^ Environment.GetHashCode();
         return(hashCode);
     }
 }
 public override int GetHashCode()
 {
     unchecked
     {
         var hashCode = IsEnergyConservative.GetHashCode();
         hashCode = (hashCode * 397) ^ (int)ShadingModel;
         hashCode = (hashCode * 397) ^ HairDirectionFunction.GetHashCode();
         hashCode = (hashCode * 397) ^ HairShadowingFunction.GetHashCode();
         hashCode = (hashCode * 397) ^ LightAttenuationFunction.GetHashCode();
         hashCode = (hashCode * 397) ^ AlphaThreshold.GetHashCode();
         return(hashCode);
     }
 }
        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;
        }
 public bool Equals(MaterialSpecularHairModelFeature other)
 {
     if (ReferenceEquals(null, other))
     {
         return(false);
     }
     if (ReferenceEquals(this, other))
     {
         return(true);
     }
     return(ShadingModel == other.ShadingModel && SpecularExponent1.Equals(other.SpecularExponent1) && SpecularColor1.Equals(other.SpecularColor1) && SpecularScale1.Equals(other.SpecularScale1) && SpecularExponent2.Equals(other.SpecularExponent2) && SpecularColor2.Equals(other.SpecularColor2) && SpecularScale2.Equals(other.SpecularScale2) && SpecularShiftRatio.Equals(other.SpecularShiftRatio) && ScalesAngle.Equals(other.ScalesAngle) && ShiftNoiseScale.Equals(other.ShiftNoiseScale) && GlintsNoiseStrength.Equals(other.GlintsNoiseStrength) && AlphaThreshold.Equals(other.AlphaThreshold) && HairSpecularHighlightsShiftNoise.Equals(other.HairSpecularHighlightsShiftNoise) && HairSecondarySpecularGlintsNoise.Equals(other.HairSecondarySpecularGlintsNoise) && HairDirectionFunction.Equals(other.HairDirectionFunction) && HairShadowingFunction.Equals(other.HairShadowingFunction) && LightAttenuationFunction.Equals(other.LightAttenuationFunction) && Environment.Equals(other.Environment));
 }
 protected bool Equals(MaterialDiffuseHairModelFeature other)
 {
     return(IsEnergyConservative == other.IsEnergyConservative && ShadingModel == other.ShadingModel && HairDirectionFunction.Equals(other.HairDirectionFunction) && HairShadowingFunction.Equals(other.HairShadowingFunction) && LightAttenuationFunction.Equals(other.LightAttenuationFunction) && AlphaThreshold.Equals(other.AlphaThreshold));
 }