Example #1
0
        public override void GenerateShader(MaterialGeneratorContext context)
        {
            // determine if an tessellation material have already been added in another layer
            hasAlreadyTessellationFeature = context.GetStreamFinalModifier <MaterialTessellationBaseFeature>(MaterialShaderStage.Domain) != null;

            // Notify problem on multiple tessellation techniques and return
            if (hasAlreadyTessellationFeature)
            {
                context.Log.Warning("A material cannot have more than one layer performing tessellation. The first tessellation method found, will be used.");
                return;
            }

            // reset the tessellation stream at the beginning of the stage
            context.AddStreamInitializer(MaterialShaderStage.Domain, "MaterialTessellationStream");

            // set the desired triangle size desired for this material
            context.Parameters.Set(TessellationKeys.DesiredTriangleSize, TriangleSize);

            // set the tessellation method and callback to add Displacement/Normal average shaders.
            if (AdjacentEdgeAverage && !context.Tags.Get(HasFinalCallback))
            {
                context.Tags.Set(HasFinalCallback, true);
                context.MaterialPass.TessellationMethod = StrideTessellationMethod.AdjacentEdgeAverage;
                context.AddFinalCallback(MaterialShaderStage.Domain, AddAdjacentEdgeAverageMacros);
                context.AddFinalCallback(MaterialShaderStage.Domain, AddAdjacentEdgeAverageShaders);
            }
        }
        public override void GenerateShader(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));
        }