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) { // 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 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; } } }