private void AddClearCoatNormalMap(MaterialGeneratorContext context) { var computeColorKeys = new MaterialComputeColorKeys(MaterialKeys.NormalMap, MaterialKeys.NormalValue, MaterialNormalMapFeature.DefaultNormalColor, false); var computeColorSource = OrangePeelNormalMap.GenerateShaderSource(context, computeColorKeys); // Orange Peel Normal Map var mixinNormalMap = new ShaderMixinSource(); // Inform the context that we are using matNormal (from the MaterialSurfaceNormalMap shader) context.UseStreamWithCustomBlend(MaterialShaderStage.Pixel, "matNormal", new ShaderClassSource("MaterialStreamNormalBlend")); context.Parameters.Set(MaterialKeys.HasNormalMap, true); mixinNormalMap.Mixins.Add(new ShaderClassSource("MaterialSurfaceNormalMap", OrangePeelIsXYNormal, OrangePeelScaleAndBias)); mixinNormalMap.AddComposition("normalMap", computeColorSource); context.AddShaderSource(MaterialShaderStage.Pixel, mixinNormalMap); }
public override void GenerateShader(MaterialGeneratorContext context) { if (DiffuseMap != null) { Vector4 diffuseMin = Vector4.Zero; Vector4 diffuseMax = Vector4.One; DiffuseMap.ClampFloat4(ref diffuseMin, ref diffuseMax); var computeColorSource = DiffuseMap.GenerateShaderSource(context, new MaterialComputeColorKeys(MaterialKeys.DiffuseMap, MaterialKeys.DiffuseValue, Color.White)); var mixin = new ShaderMixinSource(); mixin.Mixins.Add(new ShaderClassSource("MaterialSurfaceDiffuse")); mixin.AddComposition("diffuseMap", computeColorSource); context.UseStream(MaterialShaderStage.Pixel, DiffuseStream.Stream); context.UseStream(MaterialShaderStage.Pixel, ColorBaseStream.Stream); context.AddShaderSource(MaterialShaderStage.Pixel, mixin); } }
public void Visit(MaterialGeneratorContext context) { if (!Enabled) { return; } switch (context.Step) { case MaterialGeneratorStep.PassesEvaluation: MultipassGeneration(context); break; case MaterialGeneratorStep.GenerateShader: GenerateShader(context); break; } }
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; }
private void AddMetalFlakesGlossiness(MaterialGeneratorContext context) { var surfaceToEyeDistance = LODDistance.GenerateShaderSource(context, new MaterialComputeColorKeys(MaterialKeys.GlossinessMap, MaterialKeys.GlossinessValue, Color.White)); // Metal Flakes Glossiness Feature context.UseStream(MaterialShaderStage.Pixel, "matGlossiness"); var baseGlossinessComputeColorMap = BasePaintGlossinessMap.GenerateShaderSource(context, new MaterialComputeColorKeys(MaterialKeys.GlossinessMap, MaterialKeys.GlossinessValue)); var mixinGlossiness = new ShaderMixinSource(); // Computes glossiness factor for the metal flakes layer (based on the eye to surface distance and the base glossiness value) mixinGlossiness.Mixins.Add(new ShaderClassSource("MaterialSurfaceGlossinessMapMetalFlakes", BasePaintGlossinessInvert)); mixinGlossiness.AddComposition("glossinessMap", baseGlossinessComputeColorMap); mixinGlossiness.AddComposition("surfaceToEyeDistanceFactor", surfaceToEyeDistance); context.AddShaderSource(MaterialShaderStage.Pixel, mixinGlossiness); }
public virtual void Visit(MaterialGeneratorContext context) { // If not enabled, or Material or BlendMap are null, skip this layer if (!Enabled || Material is null || BlendMap is null || context.FindAsset is null) { return; } // Find the material from the reference var material = Material.Descriptor ?? context.FindAsset(Material) as IMaterialDescriptor; if (material is null) { context.Log.Error($"Unable to find material [{Material}]."); return; } // Check that material is valid var materialName = context.GetAssetFriendlyName(Material); if (!context.PushMaterial(material, materialName)) { return; } try { // TODO: Because we are not fully supporting Streams declaration in shaders, we have to workaround this limitation by using a dynamic shader (inline) // Push a layer for the sub-material context.PushOverrides(Overrides); context.PushLayer(BlendMap); // Generate the material shaders into the current context material.Visit(context); } finally { // Pop the stack context.PopLayer(); context.PopOverrides(); context.PopMaterial(); } }
public override void GenerateShader(MaterialGeneratorContext context) { base.GenerateShader(context); if (hasAlreadyTessellationFeature) { return; } // set the tessellation method used enumeration context.MaterialPass.TessellationMethod |= StrideTessellationMethod.Flat; // create and affect the shader source var tessellationShader = new ShaderMixinSource(); tessellationShader.Mixins.Add(new ShaderClassSource("TessellationFlat")); context.Parameters.Set(MaterialKeys.TessellationShader, tessellationShader); }
private void AddMetalFlakesDiffuse(MaterialGeneratorContext context) { var surfaceToEyeDistance = LODDistance.GenerateShaderSource(context, new MaterialComputeColorKeys(MaterialKeys.GlossinessMap, MaterialKeys.GlossinessValue, Color.White)); // Diffuse Feature (interpolated by the 'regular' diffuse map) var metalFlakesComputeColorSource = MetalFlakesDiffuseMap.GenerateShaderSource(context, new MaterialComputeColorKeys(MaterialKeys.DiffuseMap, MaterialKeys.DiffuseValue, Color.White)); var mixinDiffuse = new ShaderMixinSource(); // Diffuse uses a custom shader (to perform the interpolation) mixinDiffuse.Mixins.Add(new ShaderClassSource("MaterialSurfaceDiffuseMetalFlakes")); mixinDiffuse.AddComposition("diffuseMap", metalFlakesComputeColorSource); mixinDiffuse.AddComposition("surfaceToEyeDistanceFactor", surfaceToEyeDistance); context.UseStream(MaterialShaderStage.Pixel, MaterialDiffuseMapFeature.DiffuseStream.Stream); context.UseStream(MaterialShaderStage.Pixel, MaterialDiffuseMapFeature.ColorBaseStream.Stream); context.AddShaderSource(MaterialShaderStage.Pixel, mixinDiffuse); }
public override void GenerateShader(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); } }
/// <summary> /// Initializes a new instance of <see cref="MaterialBlendLayerContext"/>. /// </summary> /// <param name="context">The material generator context</param> /// <param name="parentLayerContext">The parent layer context</param> /// <param name="blendMap">The blend map used for this layer</param> public MaterialBlendLayerContext(MaterialGeneratorContext context, MaterialBlendLayerContext parentLayerContext, IComputeScalar blendMap) { if (context == null) { throw new ArgumentNullException(nameof(context)); } Context = context; Parent = parentLayerContext; BlendMap = blendMap; Children = new List <MaterialBlendLayerContext>(); ShadingModels = new MaterialShadingModelCollection(); ContextPerStage = new Dictionary <MaterialShaderStage, MaterialBlendLayerPerStageContext>(); foreach (MaterialShaderStage stage in Enum.GetValues(typeof(MaterialShaderStage))) { ContextPerStage[stage] = new MaterialBlendLayerPerStageContext(); } PendingPixelLayerContext = new MaterialBlendLayerPerStageContext(); }
public override void GenerateShader(MaterialGeneratorContext context) { base.GenerateShader(context); var attributes = context.CurrentMaterialDescriptor.Attributes; int glassPassIndex = context.PassIndex % 2; if (attributes.CullMode == CullMode.None) { context.MaterialPass.CullMode = context.PassIndex < 2 ? CullMode.Back : CullMode.Front; } else { context.MaterialPass.CullMode = attributes.CullMode; } // Compute transmittance context.GetShading(this).LightDependentExtraModels.Add(new ShaderClassSource("MaterialTransmittanceReflectanceStream")); context.Parameters.Set(MaterialTransmittanceReflectanceStreamKeys.RefractiveIndex, RefractiveIndex); context.MaterialPass.HasTransparency = true; if (glassPassIndex == 0) { // Transmittance pass context.MaterialPass.BlendState = new BlendStateDescription(Blend.Zero, Blend.SourceColor) { RenderTarget0 = { AlphaSourceBlend = Blend.One, AlphaDestinationBlend = Blend.Zero } }; // Shader output is matTransmittance // Note: we make sure to run after MaterialTransparencyBlendFeature so that shadingColorAlpha is fully updated context.AddFinalCallback(MaterialShaderStage.Pixel, AddMaterialSurfaceTransmittanceShading, MaterialTransparencyBlendFeature.ShadingColorAlphaFinalCallbackOrder + 1); } else if (glassPassIndex == 1) { // Reflectance pass context.MaterialPass.BlendState = BlendStates.Additive; } }
public override void GenerateShader(MaterialGeneratorContext context) { var alpha = Alpha ?? new ComputeFloat(0.5f); var tint = Tint ?? new ComputeColor(Color.White); alpha.ClampFloat(0, 1); // Use pre-multiplied alpha to support both additive and alpha blending if (context.MaterialPass.BlendState == null) { context.MaterialPass.BlendState = BlendStates.AlphaBlend; } context.MaterialPass.HasTransparency = true; // Disable alpha-to-coverage. We wanna do alpha blending, not alpha testing. context.MaterialPass.AlphaToCoverage = false; // TODO GRAPHICS REFACTOR //context.Parameters.SetResourceSlow(Effect.BlendStateKey, BlendState.NewFake(blendDesc)); var alphaColor = alpha.GenerateShaderSource(context, new MaterialComputeColorKeys(MaterialKeys.DiffuseSpecularAlphaBlendMap, MaterialKeys.DiffuseSpecularAlphaBlendValue, Color.White)); var mixin = new ShaderMixinSource(); mixin.Mixins.Add(new ShaderClassSource("ComputeColorMaterialAlphaBlend")); mixin.AddComposition("color", alphaColor); context.SetStream(MaterialShaderStage.Pixel, AlphaBlendStream.Stream, MaterialStreamType.Float2, mixin); context.SetStream(AlphaBlendColorStream.Stream, tint, MaterialKeys.AlphaBlendColorMap, MaterialKeys.AlphaBlendColorValue, Color.White); context.MaterialPass.Parameters.Set(MaterialKeys.UsePixelShaderWithDepthPass, true); if (DitheredShadows) { context.MaterialPass.Parameters.Set(MaterialKeys.UseDitheredShadows, true); } if (!context.Tags.Get(HasFinalCallback)) { context.Tags.Set(HasFinalCallback, true); context.AddFinalCallback(MaterialShaderStage.Pixel, AddDiffuseSpecularAlphaBlendColor); } }
protected virtual void GenerateShaderCompositions(MaterialGeneratorContext context, ShaderMixinSource shaderSource) { if (Fresnel != null) { shaderSource.AddComposition("fresnelFunction", Fresnel.Generate(context)); } if (Visibility != null) { shaderSource.AddComposition("geometricShadowingFunction", Visibility.Generate(context)); } if (NormalDistribution != null) { shaderSource.AddComposition("normalDistributionFunction", NormalDistribution.Generate(context)); } if (Environment != null) { shaderSource.AddComposition("environmentFunction", Environment.Generate(context)); } }
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 override void GenerateShader(MaterialGeneratorContext context) { base.GenerateShader(context); if (hasAlreadyTessellationFeature) { return; } // set the tessellation method used enumeration context.MaterialPass.TessellationMethod |= StrideTessellationMethod.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); }
public override void GenerateShader(MaterialGeneratorContext context) { // Make sure the parameters are not out of range ClampInputs(); // Set the blend state for both pass context.MaterialPass.BlendState = BlendStates.Additive; var isMetalFlakesPass = (context.PassIndex == 0); if (isMetalFlakesPass) { // Do the Base Paint first AddBaseDiffuse(context); AddBaseGlossiness(context); // Then the Metal Flakes AddMetalFlakesDiffuse(context); AddMetalFlakesNormal(context); AddMetalFlakesGlossiness(context); AddMetalFlakesMetalness(context); } else { // TODO Add reflections desaturation for environment reflections? // Ideally, this should be done on top of the regular specular model. // Unfortunately, after some tests, it seems that overriding the ComputeEnvironmentLightContribution is the only way to do so // Enable transparency for clear coat pass only context.MaterialPass.HasTransparency = true; AddClearCoatNormalMap(context); AddClearCoatGlossinessMap(context); AddClearCoatMetalnessMap(context); } }
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)); }
/// <summary> /// Called during prepass, used to enumerate extra passes. /// </summary> /// <param name="context">The context.</param> public virtual void MultipassGeneration(MaterialGeneratorContext context) { }
public override void MultipassGeneration(MaterialGeneratorContext context) { context.SetMultiplePasses("Hair", 3); }
public ShaderSource Generate(MaterialGeneratorContext context) { return(new ShaderClassSource("MaterialSpecularMicrofacetNormalDistributionBeckmann")); }
public ShaderSource Generate(MaterialGeneratorContext context, ValueParameterKey <float> uniqueAlphaThresholdKey) { return(new ShaderClassSource("MaterialHairDiscardFunctionTransparentPass", uniqueAlphaThresholdKey)); }
public void Visit(MaterialGeneratorContext context) { if (!Enabled) { return; } // 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 // If Specular has energy conservative, copy this to the diffuse lambertian model // TODO: Should we apply it to any Diffuse Model? var isEnergyConservative = (Specular as MaterialSpecularMapFeature)?.IsEnergyConservative ?? false; var lambert = DiffuseModel as IEnergyConservativeDiffuseModelFeature; if (lambert != null) { lambert.IsEnergyConservative = isEnergyConservative; } // Diffuse - these 2 features are always used as a pair context.Visit(Diffuse); if (Diffuse != null) { context.Visit(DiffuseModel); } // Surface Geometry context.Visit(Tessellation); context.Visit(Displacement); context.Visit(Surface); context.Visit(MicroSurface); // Specular - these 2 features are always used as a pair context.Visit(Specular); if (Specular != null) { context.Visit(SpecularModel); } // Misc context.Visit(Occlusion); context.Visit(Emissive); context.Visit(SubsurfaceScattering); // If hair shading is enabled, ignore the transparency feature to avoid errors during shader compilation. // Allowing the transparency feature while hair shading is on makes no sense anyway. if (!(SpecularModel is MaterialSpecularHairModelFeature) && !(DiffuseModel is MaterialDiffuseHairModelFeature)) { context.Visit(Transparency); } context.Visit(ClearCoat); // Pop overrides context.PopOverrides(); // Only set the cullmode to something if (context.Step == MaterialGeneratorStep.GenerateShader && CullMode != CullMode.Back) { if (context.MaterialPass.CullMode == null) { context.MaterialPass.CullMode = CullMode; } } }
public ShaderSource Generate(MaterialGeneratorContext context) { return(new ShaderClassSource("MaterialCelShadingLightDefault", IsBlackAndWhite)); }
public ShaderSource Generate(MaterialGeneratorContext context) { return(new ShaderClassSource("MaterialSpecularMicrofacetEnvironmentGGXPolynomial")); }
public ShaderSource Generate(MaterialGeneratorContext context) { return(new ShaderClassSource("MaterialSpecularMicrofacetVisibilityCookTorrance")); }
private void AddDiffuseSpecularAlphaBlendColor(MaterialShaderStage stage, MaterialGeneratorContext context) { context.AddShaderSource(MaterialShaderStage.Pixel, new ShaderClassSource("MaterialSurfaceDiffuseSpecularAlphaBlendColor")); }
public ShaderSource Generate(MaterialGeneratorContext context) { return(new ShaderClassSource("MaterialHairLightAttenuationFunctionNone")); }
public ShaderSource Generate(MaterialGeneratorContext context) { return(new ShaderClassSource("MaterialSubsurfaceScatteringScatteringProfileSkin")); }
/// <summary> /// Generates the shader for the feature. /// </summary> /// <param name="context">The context.</param> public abstract void GenerateShader(MaterialGeneratorContext context);
public ShaderSource Generate(MaterialGeneratorContext context) { return(new ShaderClassSource("MaterialSpecularMicrofacetFresnelThinGlass")); }