public override void Visit(MaterialGeneratorContext context)
        {
            base.Visit(context);

            if (HasAlreadyTessellationFeature)
            {
                return;
            }

            // set the tessellation method used enumeration
            context.Material.TessellationMethod |= ParadoxTessellationMethod.Flat;

            // create and affect the shader source
            var tessellationShader = new ShaderMixinSource();

            tessellationShader.Mixins.Add(new ShaderClassSource("TessellationFlat"));

            context.Parameters.Set(MaterialKeys.TessellationShader, tessellationShader);
        }
예제 #2
0
        public override void VisitFeature(MaterialGeneratorContext context)
        {
            // Push overrides of this attributes
            context.PushOverrides(Overrides);

            // Order is important, as some features are dependent on other
            // (For example, Specular can depend on Diffuse in case of Metalness)
            // We may be able to describe a dependency system here, but for now, assume
            // that it won't change much so it is hardcoded

            // Diffuse
            context.Visit(Diffuse);
            context.Visit(DiffuseModel);

            // Surface Geometry
            context.Visit(Tessellation);
            context.Visit(Displacement);
            context.Visit(Surface);
            context.Visit(MicroSurface);

            // If Specular has energy conservative, copy this to the diffuse lambertian model
            // TODO: Should we apply it to any Diffuse Model?
            bool isEnergyConservative = (Specular is MaterialSpecularMapFeature && ((MaterialSpecularMapFeature)Specular).IsEnergyConservative);

            var lambert = DiffuseModel as MaterialDiffuseLambertModelFeature;

            if (lambert != null)
            {
                lambert.IsEnergyConservative = isEnergyConservative;
            }

            // Specular
            context.Visit(Specular);
            context.Visit(SpecularModel);

            // Misc
            context.Visit(Occlusion);
            context.Visit(Emissive);
            context.Visit(Transparency);

            // Pop overrides
            context.PopOverrides();
        }
        public override void VisitFeature(MaterialGeneratorContext context)
        {
            var alpha = Alpha ?? new ComputeFloat(1f);
            var tint  = Tint ?? new ComputeColor(Color.White);

            // Use pre-multiplied alpha to support both additive and alpha blending
            var blendDesc = new BlendStateDescription(Blend.One, Blend.InverseSourceAlpha);

            context.Material.HasTransparency = true;
            context.Parameters.Set(Effect.BlendStateKey, BlendState.NewFake(blendDesc));

            context.SetStream(AlphaBlendStream.Stream, alpha, MaterialKeys.DiffuseSpecularAlphaBlendMap, MaterialKeys.DiffuseSpecularAlphaBlendValue, Color.White);
            context.SetStream(AlphaBlendColorStream.Stream, tint, MaterialKeys.AlphaBlendColorMap, MaterialKeys.AlphaBlendColorValue, Color.White);

            if (!context.Tags.Get(HasFinalCallback))
            {
                context.Tags.Set(HasFinalCallback, true);
                context.AddFinalCallback(MaterialShaderStage.Pixel, AddDiffuseSpecularAlphaBlendColor);
            }
        }
        public void Visit(MaterialGeneratorContext context)
        {
            // Exclude ambient occlusion from uv-scale overrides
            var revertOverrides = new MaterialOverrides();

            revertOverrides.UVScale = 1.0f / context.CurrentOverrides.UVScale;

            context.PushOverrides(revertOverrides);
            context.SetStream(OcclusionStream.Stream, AmbientOcclusionMap, MaterialKeys.AmbientOcclusionMap, MaterialKeys.AmbientOcclusionValue, Color.White);
            context.PopOverrides();

            context.SetStream("matAmbientOcclusionDirectLightingFactor", DirectLightingFactor, null, MaterialKeys.AmbientOcclusionDirectLightingFactorValue);

            if (CavityMap != null)
            {
                context.SetStream(CavityStream.Stream, CavityMap, MaterialKeys.CavityMap, MaterialKeys.CavityValue, Color.White);
                context.SetStream("matCavityDiffuse", DiffuseCavity, null, MaterialKeys.CavityDiffuseValue);
                context.SetStream("matCavitySpecular", SpecularCavity, null, MaterialKeys.CavitySpecularValue);
            }
        }
        public override void VisitFeature(MaterialGeneratorContext context)
        {
            base.VisitFeature(context);

            if (HasAlreadyTessellationFeature)
            {
                return;
            }

            // set the tessellation method used enumeration
            context.Material.TessellationMethod |= ParadoxTessellationMethod.PointNormal;

            // create and affect the shader source
            var tessellationShader = new ShaderMixinSource();

            tessellationShader.Mixins.Add(new ShaderClassSource("TessellationPN"));
            if (AdjacentEdgeAverage)
            {
                tessellationShader.Mixins.Add(new ShaderClassSource("TessellationAE4", "PositionWS"));
            }

            context.Parameters.Set(MaterialKeys.TessellationShader, tessellationShader);
        }
예제 #6
0
        public override void VisitFeature(MaterialGeneratorContext context)
        {
            var shaderSource = new ShaderMixinSource();

            shaderSource.Mixins.Add(new ShaderClassSource("MaterialSurfaceShadingSpecularMicrofacet"));

            if (Fresnel != null)
            {
                shaderSource.AddComposition("fresnelFunction", Fresnel.Generate());
            }

            if (Visibility != null)
            {
                shaderSource.AddComposition("geometricShadowingFunction", Visibility.Generate());
            }

            if (NormalDistribution != null)
            {
                shaderSource.AddComposition("normalDistributionFunction", NormalDistribution.Generate());
            }

            context.AddShading(this, shaderSource);
        }
예제 #7
0
        public virtual void Visit(MaterialGeneratorContext context)
        {
            // If not enabled, or Material or BlendMap are null, skip this layer
            if (!Enabled || Material == null || BlendMap == null || context.FindAsset == null)
            {
                return;
            }

            // Find the material from the reference
            var material = context.FindAsset(Material);

            if (material == null)
            {
                context.Log.Error("Unable to find material [{0}]", Material);
                return;
            }

            // TODO: Because we are not fully supporting Streams declaration in shaders, we have to workaround this limitation by using a dynamic shader (inline)
            // TODO: Handle MaterialOverrides

            // Push a layer for the sub-material
            context.PushOverrides(Overrides);
            context.PushLayer();

            // Generate the material shaders into the current context
            material.Visit(context);

            // Generate Vertex and Pixel surface shaders
            foreach (MaterialShaderStage stage in Enum.GetValues(typeof(MaterialShaderStage)))
            {
                Generate(stage, context);
            }

            // Pop the stack
            context.PopLayer();
            context.PopOverrides();
        }
예제 #8
0
        public override void VisitFeature(MaterialGeneratorContext context)
        {
            if (NormalMap != null)
            {
                // Inform the context that we are using matNormal (from the MaterialSurfaceNormalMap shader)
                context.UseStreamWithCustomBlend(MaterialShaderStage.Pixel, NormalStream.Stream, new ShaderClassSource("MaterialStreamNormalBlend"));
                context.Parameters.Set(MaterialKeys.HasNormalMap, true);

                var normalMap = NormalMap;
                // Workaround to make sure that normal map are setup
                var computeTextureColor = normalMap as ComputeTextureColor;
                if (computeTextureColor != null)
                {
                    if (computeTextureColor.FallbackValue.Value == Color.White)
                    {
                        computeTextureColor.FallbackValue.Value = DefaultNormalColor;
                    }
                }
                else
                {
                    var computeColor = normalMap as ComputeColor;
                    if (computeColor != null)
                    {
                        if (computeColor.Value == Color.Black || computeColor.Value == Color.White)
                        {
                            computeColor.Value = DefaultNormalColor;
                        }
                    }
                }

                var computeColorSource = NormalMap.GenerateShaderSource(context, new MaterialComputeColorKeys(MaterialKeys.NormalMap, MaterialKeys.NormalValue, DefaultNormalColor, false));
                var mixin = new ShaderMixinSource();
                mixin.Mixins.Add(new ShaderClassSource("MaterialSurfaceNormalMap", IsXYNormal, ScaleAndBias));
                mixin.AddComposition("normalMap", computeColorSource);
                context.AddSurfaceShader(MaterialShaderStage.Pixel, mixin);
            }
        }
        public void Visit(MaterialGeneratorContext context)
        {
            if (DisplacementMap == null)
            {
                return;
            }

            var materialStage = (MaterialShaderStage)Stage;

            // reset the displacement streams at the beginning of the stage
            context.AddStreamInitializer(materialStage, "MaterialDisplacementStream");

            // set the blending mode of displacement map to additive (and not default linear blending)
            context.UseStreamWithCustomBlend(materialStage, DisplacementStream, new ShaderClassSource("MaterialStreamAdditiveBlend", DisplacementStream));

            // build the displacement computer
            var displacement = DisplacementMap;

            if (ScaleAndBias) // scale and bias should be done by layer
            {
                displacement = new ComputeBinaryScalar(displacement, new ComputeFloat(2f), BinaryOperator.Multiply);
                displacement = new ComputeBinaryScalar(displacement, new ComputeFloat(1f), BinaryOperator.Subtract);
            }
            displacement = new ComputeBinaryScalar(displacement, Intensity, BinaryOperator.Multiply);

            // Workaround to inform compute colors that sampling is occurring from a vertex shader
            context.IsNotPixelStage = materialStage != MaterialShaderStage.Pixel;
            context.SetStream(materialStage, DisplacementStream, displacement, MaterialKeys.DisplacementMap, MaterialKeys.DisplacementValue);
            context.IsNotPixelStage = false;

            var scaleNormal    = materialStage != MaterialShaderStage.Vertex;
            var positionMember = materialStage == MaterialShaderStage.Vertex ? "Position" : "PositionWS";
            var normalMember   = materialStage == MaterialShaderStage.Vertex ? "meshNormal" : "normalWS";

            context.SetStreamFinalModifier <MaterialDisplacementMapFeature>(materialStage, new ShaderClassSource("MaterialSurfaceDisplacement", positionMember, normalMember, scaleNormal));
        }
예제 #10
0
        public virtual void Visit(MaterialGeneratorContext context)
        {
            var shaderSource = new ShaderClassSource("MaterialSurfaceShadingDiffuseLambert", IsEnergyConservative);

            context.AddShading(this, shaderSource);
        }
예제 #11
0
 public void Visit(MaterialGeneratorContext context)
 {
     context.SetStream(SpecularStream.Stream, SpecularMap, MaterialKeys.SpecularMap, MaterialKeys.SpecularValue);
     context.SetStream("matSpecularIntensity", Intensity, null, MaterialKeys.SpecularIntensityValue);
 }
예제 #12
0
 private void AddDiscardFromLuminance(MaterialShaderStage stage, MaterialGeneratorContext context)
 {
     context.AddSurfaceShader(MaterialShaderStage.Pixel, new ShaderClassSource("MaterialSurfaceTransparentAlphaDiscard"));
 }
 private void AddDiffuseSpecularAlphaBlendColor(MaterialShaderStage stage, MaterialGeneratorContext context)
 {
     context.AddSurfaceShader(MaterialShaderStage.Pixel, new ShaderClassSource("MaterialSurfaceDiffuseSpecularAlphaBlendColor"));
 }
예제 #14
0
        public static MaterialShaderResult Generate(MaterialDescriptor materialDescriptor, MaterialGeneratorContext context, string rootMaterialFriendlyName)
        {
            if (materialDescriptor == null)
            {
                throw new ArgumentNullException("materialDescriptor");
            }
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            var result = new MaterialShaderResult();

            context.Log = result;

            var material = context.Material;

            result.Material = context.Material;

            context.Parameters = material.Parameters;
            context.PushMaterial(materialDescriptor, rootMaterialFriendlyName);
            context.PushLayer();
            materialDescriptor.Visit(context);
            context.PopLayer();
            context.PopMaterial();

            if (!material.Parameters.ContainsKey(MaterialKeys.TessellationShader))
            {
                material.Parameters.Set(MaterialKeys.TessellationShader, null);
            }

            material.Parameters.Set(MaterialKeys.VertexStageSurfaceShaders, context.GenerateSurfaceShader(MaterialShaderStage.Vertex));
            material.Parameters.Set(MaterialKeys.DomainStageSurfaceShaders, context.GenerateSurfaceShader(MaterialShaderStage.Domain));
            material.Parameters.Set(MaterialKeys.PixelStageSurfaceShaders, context.GenerateSurfaceShader(MaterialShaderStage.Pixel));

            material.Parameters.Set(MaterialKeys.VertexStageStreamInitializer, context.GenerateStreamInitializer(MaterialShaderStage.Vertex));
            material.Parameters.Set(MaterialKeys.DomainStageStreamInitializer, context.GenerateStreamInitializer(MaterialShaderStage.Domain));
            material.Parameters.Set(MaterialKeys.PixelStageStreamInitializer, context.GenerateStreamInitializer(MaterialShaderStage.Pixel));

            return(result);
        }
예제 #15
0
        public static MaterialShaderResult Generate(MaterialDescriptor materialDescriptor, MaterialGeneratorContext context = null)
        {
            if (materialDescriptor == null)
            {
                throw new ArgumentNullException("materialDescriptor");
            }
            var result = new MaterialShaderResult();

            if (context == null)
            {
                context = new MaterialGeneratorContext(new Material());
            }
            context.Log = result;

            var material = context.Material;

            result.Material = context.Material;

            context.Parameters = material.Parameters;
            context.PushLayer();
            materialDescriptor.Visit(context);
            context.PopLayer();

            material.Parameters.Set(MaterialKeys.VertexStageSurfaceShaders, context.GenerateSurfaceShader(MaterialShaderStage.Vertex));
            material.Parameters.Set(MaterialKeys.DomainStageSurfaceShaders, context.GenerateSurfaceShader(MaterialShaderStage.Domain));
            material.Parameters.Set(MaterialKeys.PixelStageSurfaceShaders, context.GenerateSurfaceShader(MaterialShaderStage.Pixel));

            material.Parameters.Set(MaterialKeys.VertexStageStreamInitializer, context.GenerateStreamInitializer(MaterialShaderStage.Vertex));
            material.Parameters.Set(MaterialKeys.DomainStageStreamInitializer, context.GenerateStreamInitializer(MaterialShaderStage.Domain));
            material.Parameters.Set(MaterialKeys.PixelStageStreamInitializer, context.GenerateStreamInitializer(MaterialShaderStage.Pixel));

            return(result);
        }
예제 #16
0
 /// <summary>
 /// Generates the for the feature shader.
 /// </summary>
 /// <param name="context">The context.</param>
 public abstract void VisitFeature(MaterialGeneratorContext context);