static void SetMaterialKeywords(Material material, WorkflowMode workflowMode) { // Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation // (MaterialProperty value might come from renderer material property block) SetKeyword(material, "_NORMALMAP", material.GetTexture("_BumpMap") || material.GetTexture("_DetailNormalMap")); if (workflowMode == WorkflowMode.Specular) { SetKeyword(material, "_SPECGLOSSMAP", material.GetTexture("_SpecGlossMap")); } else if (workflowMode == WorkflowMode.Metallic) { SetKeyword(material, "_METALLICGLOSSMAP", material.GetTexture("_MetallicGlossMap")); } SetKeyword(material, "_PARALLAXMAP", material.GetTexture("_ParallaxMap")); SetKeyword(material, "_DETAIL_MULX2", material.GetTexture("_DetailAlbedoMap") || material.GetTexture("_DetailNormalMap")); // A material's GI flag internally keeps track of whether emission is enabled at all, it's enabled but has no effect // or is enabled and may be modified at runtime. This state depends on the values of the current flag and emissive color. // The fixup routine makes sure that the material is in the correct state if/when changes are made to the mode or color. MaterialEditor.FixupEmissiveFlag(material); bool shouldEmissionBeEnabled = (material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0; SetKeyword(material, "_EMISSION", shouldEmissionBeEnabled); if (material.HasProperty("_SmoothnessTextureChannel")) { SetKeyword(material, "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A", GetSmoothnessMapChannel(material) == SmoothnessMapChannel.AlbedoAlpha); } }
//////////////////////////////////// // Material Data Functions // //////////////////////////////////// #region MaterialDataFunctions public static void SetMaterialKeywords(Material material, Action <Material> shadingModelFunc = null, Action <Material> shaderFunc = null) { // Clear all keywords for fresh start material.shaderKeywords = null; SetupMaterialLightingMode(material); SetupMaterialShadingEvaluationMode(material); // Setup blending SetupMaterialBlendMode(material); // Receive Shadows // if(material.HasProperty("_ReceiveShadows")) // CoreUtils.SetKeyword(material, "_RECEIVE_SHADOWS_OFF", material.GetFloat("_ReceiveShadows") == 0.0f); SetupMaterialFogKeyword(material); SetupMaterialReflectionKeyword(material); // Emission if (material.HasProperty("_EmissiveColor")) { MaterialEditor.FixupEmissiveFlag(material); } bool shouldEmissionBeEnabled = (material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0; if (material.HasProperty("_EmissionEnabled") && !shouldEmissionBeEnabled) { shouldEmissionBeEnabled = material.GetFloat("_EmissionEnabled") >= 0.5f; } CoreUtils.SetKeyword(material, "_EMISSION", shouldEmissionBeEnabled); // Shader specific keyword functions shadingModelFunc?.Invoke(material); shaderFunc?.Invoke(material); }
//////////////////////////////////// // Material Data Functions // //////////////////////////////////// #region MaterialDataFunctions public static void SetMaterialKeywords(Material material, Action <Material> shadingModelFunc = null, Action <Material> shaderFunc = null) { // Clear all keywords for fresh start material.shaderKeywords = null; // Setup blending - consistent across all Universal RP shaders SetupMaterialBlendMode(material); // Receive Shadows if (material.HasProperty("_ReceiveShadows")) { SetKeyword(material, "_RECEIVE_SHADOWS_OFF", material.GetFloat("_ReceiveShadows") == 0.0f); } // Emission if (material.HasProperty("_EmissionColor")) { MaterialEditor.FixupEmissiveFlag(material); } bool shouldEmissionBeEnabled = (material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0; if (material.HasProperty("_EmissionEnabled") && !shouldEmissionBeEnabled) { shouldEmissionBeEnabled = material.GetFloat("_EmissionEnabled") >= 0.5f; } SetKeyword(material, "_EMISSION", shouldEmissionBeEnabled); // Normal Map if (material.HasProperty("_BumpMap")) { SetKeyword(material, "_NORMALMAP", material.GetTexture("_BumpMap")); } // Shader specific keyword functions shadingModelFunc?.Invoke(material); shaderFunc?.Invoke(material); }
static void SetMaterialKeywords(Material material) { // Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation // (MaterialProperty value might come from renderer material property block) int workflow = material.GetInt("_Workflow"); int samplingMode = material.GetInt("_SamplingMode"); int blendModeEnum = material.GetInt("_BlendMode"); MGUI.SetKeyword(material, "_NORMALMAP", material.GetTexture("_BumpMap") || material.GetTexture("_DetailNormalMap")); MGUI.SetKeyword(material, "_WORKFLOW_PACKED_ON", workflow == 1); MGUI.SetKeyword(material, "_SPECGLOSSMAP", material.GetTexture("_SpecGlossMap")); MGUI.SetKeyword(material, "_METALLICGLOSSMAP", material.GetTexture("_MetallicGlossMap")); MGUI.SetKeyword(material, "_DETAIL_MULX2", material.GetTexture("_DetailAlbedoMap")); MGUI.SetKeyword(material, "_REFLECTION_FALLBACK_ON", material.GetTexture("_ReflCube")); MGUI.SetKeyword(material, "_REFLECTION_OVERRIDE_ON", material.GetTexture("_ReflCubeOverride")); MGUI.SetKeyword(material, "_SCREENSPACE_REFLECTIONS_ON", material.GetInt("_SSR") == 1); MGUI.SetKeyword(material, "_SPECULARHIGHLIGHTS_OFF", material.GetInt("_SpecularHighlights") == 0); MGUI.SetKeyword(material, "_GLOSSYREFLECTIONS_OFF", material.GetInt("_GlossyReflections") == 0); MGUI.SetKeyword(material, "_STOCHASTIC_ON", samplingMode == 1); MGUI.SetKeyword(material, "_TSS_ON", samplingMode == 2); MGUI.SetKeyword(material, "_TRIPLANAR_ON", samplingMode == 3); MGUI.SetKeyword(material, "_DECAL_ON", samplingMode == 4); MGUI.SetKeyword(material, "_DETAIL_ROUGH_ON", material.GetTexture("_DetailRoughnessMap")); MGUI.SetKeyword(material, "_DETAIL_AO_ON", material.GetTexture("_DetailAOMap")); MGUI.SetKeyword(material, "_SUBSURFACE_ON", material.GetInt("_Subsurface") == 1); MGUI.SetKeyword(material, "_AUDIOLINK_ON", material.GetInt("_AudioLinkEmission") > 0); MGUI.SetKeyword(material, "_DETAIL_SAMPLEMODE_ON", material.GetInt("_DetailSamplingMode") == 1); MGUI.SetKeyword(material, "_ALPHAMASK_ON", blendModeEnum > 0 && material.GetInt("_UseAlphaMask") == 1); MGUI.SetKeyword(material, "_BICUBIC_SAMPLING_ON", material.GetInt("_BicubicLightmap") == 1); MGUI.SetKeyword(material, "BAKERY_SH", material.GetInt("_BakeryMode") == 1); MGUI.SetKeyword(material, "BAKERY_RNM", material.GetInt("_BakeryMode") == 2); MGUI.SetKeyword(material, "_FILTERING_ON", material.GetInt("_Filtering") == 1); if (samplingMode < 3) { if (!material.GetTexture("_PackedMap")) { MGUI.SetKeyword(material, "_PARALLAXMAP", material.GetTexture("_ParallaxMap")); } else { MGUI.SetKeyword(material, "_PARALLAXMAP", material.GetInt("_UseHeight") == 1); } } else { MGUI.SetKeyword(material, "_PARALLAXMAP", false); } // A material's GI flag internally keeps track of whether emission is enabled at all, it's enabled but has no effect // or is enabled and may be modified at runtime. This state depends on the values of the current flag and emissive color. // The fixup routine makes sure that the material is in the correct state if/when changes are made to the mode or color. MaterialEditor.FixupEmissiveFlag(material); bool shouldEmissionBeEnabled = (material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0; MGUI.SetKeyword(material, "_EMISSION", shouldEmissionBeEnabled); material.SetShaderPassEnabled("Always", material.GetInt("_SSR") == 1); }
public void DrawSection(MaterialEditor materialEditor) { EditorGUI.BeginChangeCheck(); TSFunctions.DrawSelector(Enum.GetNames(typeof(ToonyStandardGUI.BlendMode)), _blendMode, Styles.blendMode, materialEditor); if (EditorGUI.EndChangeCheck()) { foreach (Material mat in _blendMode.targets) { ToonyStandardGUI.SetupMaterialWithBlendMode(mat, (ToonyStandardGUI.BlendMode)_blendMode.floatValue, mat.GetFloat("_OutlineOn") > 0); } } // Draw cull mode materialEditor.ShaderProperty(_Cull, Styles.cullMode); EditorGUILayout.Space(); // Draw main properties materialEditor.TexturePropertySingleLine(Styles.mainTex, _MainTex, _Color); if ((ToonyStandardGUI.BlendMode)_blendMode.floatValue == ToonyStandardGUI.BlendMode.Cutout) { EditorGUI.indentLevel += MaterialEditor.kMiniTextureFieldLabelIndentLevel + 1; materialEditor.ShaderProperty(_Cutoff, Styles.cutOff); EditorGUI.indentLevel -= MaterialEditor.kMiniTextureFieldLabelIndentLevel + 1; } materialEditor.TexturePropertySingleLine(Styles.normal, _BumpMap, _BumpScale); materialEditor.TexturePropertySingleLine(Styles.ramp, _Ramp, _RampColor); materialEditor.ShaderProperty(_RampOffset, Styles.rampOffset); materialEditor.ShaderProperty(_ShadowIntensity, Styles.shadowIntensity); // Emission EditorGUI.BeginChangeCheck(); if (materialEditor.EmissionEnabledProperty()) { materialEditor.TexturePropertySingleLine(Styles.emission, _Emission, _EmissionColor); materialEditor.LightmapEmissionProperty(MaterialEditor.kMiniTextureFieldLabelIndentLevel); } if (EditorGUI.EndChangeCheck()) { foreach (Material mat in _Emission.targets) { MaterialEditor.FixupEmissiveFlag(mat); bool shouldEmissionBeEnabled = (mat.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0; TSFunctions.SetKeyword(mat, "_EMISSION", shouldEmissionBeEnabled); if (shouldEmissionBeEnabled) { mat.SetOverrideTag("IsEmissive", "true"); } else { mat.SetOverrideTag("IsEmissive", "false"); } } } materialEditor.TextureScaleOffsetProperty(_MainTex); EditorGUILayout.Space(); }
private void ManageKeywordsEmission() { //emission foreach (Material mat in _emissionColor.targets) { EmissionRealtimeSetup(mat); MaterialEditor.FixupEmissiveFlag(mat); //bool shouldEmissionBeEnabled = (mat.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0; EditorHelper.SetKeyword(Properties.emissionColor.GetValue(mat).maxColorComponent > 0, Keywords.emission, mat); //black color emissive = emission Off } }
public override void MaterialChanged(Material material) { SetupMaterialBlendMode(material); // A material's GI flag internally keeps track of whether emission is enabled at all, it's enabled but has no effect // or is enabled and may be modified at runtime. This state depends on the values of the current flag and emissive color. // The fixup routine makes sure that the material is in the correct state if/when changes are made to the mode or color. if (material.HasProperty("_EmissionColor")) { MaterialEditor.FixupEmissiveFlag(material); } }
private static void SetMaterialKeywords(Material material) { MaterialEditor.FixupEmissiveFlag(material); bool shouldEmissionBeEnabled = (material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0; if (shouldEmissionBeEnabled) { material.EnableKeyword("EMISSION_ENABLED"); } else { material.DisableKeyword("EMISSION_ENABLED"); } }
private void SetMaterialKeywords(Material material) { material.shaderKeywords = null; SetupMaterialBlendMode(material); UpdateMaterialSpecularSource(material); CoreUtils.SetKeyword(material, "_NORMALMAP", material.GetTexture("_BumpMap")); // A material's GI flag internally keeps track of whether emission is enabled at all, it's enabled but has no effect // or is enabled and may be modified at runtime. This state depends on the values of the current flag and emissive color. // The fixup routine makes sure that the material is in the correct state if/when changes are made to the mode or color. MaterialEditor.FixupEmissiveFlag(material); bool shouldEmissionBeEnabled = (material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0; CoreUtils.SetKeyword(material, "_EMISSION", shouldEmissionBeEnabled); }
static void SetMaterialKeywords(Material material) { // Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation // (MaterialProperty value might come from renderer material property block) bool isSpecularWorkFlow = (WorkflowMode)material.GetFloat("_WorkflowMode") == WorkflowMode.Specular; bool hasGlossMap = false; if (isSpecularWorkFlow) { hasGlossMap = material.GetTexture("_SpecGlossMap"); } else { hasGlossMap = material.GetTexture("_MetallicGlossMap"); } CoreUtils.SetKeyword(material, "_SPECULAR_SETUP", isSpecularWorkFlow); CoreUtils.SetKeyword(material, "_METALLICSPECGLOSSMAP", hasGlossMap); CoreUtils.SetKeyword(material, "_SPECGLOSSMAP", hasGlossMap && isSpecularWorkFlow); CoreUtils.SetKeyword(material, "_METALLICGLOSSMAP", hasGlossMap && !isSpecularWorkFlow); CoreUtils.SetKeyword(material, "_NORMALMAP", material.GetTexture("_BumpMap")); CoreUtils.SetKeyword(material, "_SPECULARHIGHLIGHTS_OFF", material.GetFloat("_SpecularHighlights") == 0.0f); CoreUtils.SetKeyword(material, "_GLOSSYREFLECTIONS_OFF", material.GetFloat("_GlossyReflections") == 0.0f); CoreUtils.SetKeyword(material, "_OCCLUSIONMAP", material.GetTexture("_OcclusionMap")); //CoreUtils.SetKeyword(material, "_PARALLAXMAP", material.GetTexture("_ParallaxMap")); //CoreUtils.SetKeyword(material, "_DETAIL_MULX2", material.GetTexture("_DetailAlbedoMap") || material.GetTexture("_DetailNormalMap")); CoreUtils.SetKeyword(material, "_RECEIVE_SHADOWS_OFF", material.GetFloat("_ReceiveShadows") == 0.0f); // A material's GI flag internally keeps track of whether emission is enabled at all, it's enabled but has no effect // or is enabled and may be modified at runtime. This state depends on the values of the current flag and emissive color. // The fixup routine makes sure that the material is in the correct state if/when changes are made to the mode or color. MaterialEditor.FixupEmissiveFlag(material); bool shouldEmissionBeEnabled = (material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0; CoreUtils.SetKeyword(material, "_EMISSION", shouldEmissionBeEnabled); if (material.HasProperty("_SmoothnessTextureChannel")) { CoreUtils.SetKeyword(material, "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A", GetSmoothnessMapChannel(material) == SmoothnessMapChannel.AlbedoAlpha); } }
public static void SetupMaterialEmissionKeyword(Material material) { if (material.HasProperty(LegacyPropertyIDs._EmissiveColor)) { MaterialEditor.FixupEmissiveFlag(material); } bool shouldEmissionBeEnabled = (material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0; if (material.HasProperty(LegacyPropertyIDs._EmissionEnabled) && !shouldEmissionBeEnabled) { shouldEmissionBeEnabled = material.GetFloat(LegacyPropertyIDs._EmissionEnabled) >= 0.5f; } CoreUtils.SetKeyword(material, Keywords._EMISSION, shouldEmissionBeEnabled); }
static void SetMaterialKeywords(Material material) { // Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation // (MaterialProperty value might come from renderer material property block) SetKeyword(material, "_NORMALMAP", material.GetTexture("_BumpMap")); SetKeyword(material, "_NORMALMAP", material.GetTexture("_BumpMap")); SetKeyword(material, "_METALLICGLOSSMAP", material.GetTexture("_MetallicGlossMap")); // A material's GI flag internally keeps track of whether emission is enabled at all, it's enabled but has no effect // or is enabled and may be modified at runtime. This state depends on the values of the current flag and emissive color. // The fixup routine makes sure that the material is in the correct state if/when changes are made to the mode or color. MaterialEditor.FixupEmissiveFlag(material); bool shouldEmissionBeEnabled = (material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0; SetKeyword(material, "_EMISSION", shouldEmissionBeEnabled); }
static void SetMaterialKeywords(Material material, WorkflowMode workflowMode) { // Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation // (MaterialProperty value might come from renderer material property block) //TCP2: no more keywords, these features are toggled in the Shader Generator /* * SetKeyword (material, "_NORMALMAP", material.HasProperty("_BumpMap") || material.HasProperty("_DetailNormalMap")); * if (workflowMode == WorkflowMode.Specular) * SetKeyword (material, "_SPECGLOSSMAP", material.GetTexture ("_SpecGlossMap")); * else if (workflowMode == WorkflowMode.Metallic) * SetKeyword (material, "_METALLICGLOSSMAP", material.GetTexture ("_MetallicGlossMap")); * SetKeyword (material, "_PARALLAXMAP", material.GetTexture ("_ParallaxMap")); * SetKeyword (material, "_DETAIL_MULX2", material.GetTexture ("_DetailAlbedoMap") || material.GetTexture ("_DetailNormalMap")); */ #if UNITY_5_6_OR_NEWER // A material's GI flag internally keeps track of whether emission is enabled at all, it's enabled but has no effect // or is enabled and may be modified at runtime. This state depends on the values of the current flag and emissive color. // The fixup routine makes sure that the material is in the correct state if/when changes are made to the mode or color. if (material.HasProperty("_EmissionColor")) { MaterialEditor.FixupEmissiveFlag(material); bool shouldEmissionBeEnabled = material.HasProperty("_EmissionColor") && (material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0; SetKeyword(material, "_EMISSION", shouldEmissionBeEnabled); } else if (material.IsKeywordEnabled("_EMISSION")) { SetKeyword(material, "_EMISSION", false); } #else // Setup lightmap emissive flags var shouldEmissionBeEnabled = material.HasProperty("_EmissionColor") && ShouldEmissionBeEnabled(material, material.GetColor("_EmissionColor")); var flags = material.globalIlluminationFlags; if ((flags & (MaterialGlobalIlluminationFlags.BakedEmissive | MaterialGlobalIlluminationFlags.RealtimeEmissive)) != 0) { flags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack; if (!shouldEmissionBeEnabled) { flags |= MaterialGlobalIlluminationFlags.EmissiveIsBlack; } material.globalIlluminationFlags = flags; } #endif }
/// <summary> /// Initializzation that happens the first time the window is created /// </summary> /// <param name="materialEditor">Material editor provided by the custom inspector</param> /// <param name="properties">Array of materialProperties provided by the custom inspector</param> public void Start(MaterialEditor materialEditor, MaterialProperty[] properties) { //Temporary code for transitioning between 2017 to 2018 if (FindProperty("_NeedsFix", properties).floatValue == 0.5) { #if UNITY_2018_1_OR_NEWER FindProperty("_NeedsFix", properties).floatValue = 0; #else FindProperty("_NeedsFix", properties).floatValue = 1; #endif } EditorGUIUtility.labelWidth = 0f; material = materialEditor.target as Material; //Initialize properties FindProperties(properties); //Set some values based on the inspector level setting inspectorLevel = (InspectorLevel)EditorPrefs.GetInt("TSInspectorLevel"); switch (inspectorLevel) { case InspectorLevel.Basic: _Occlusion.floatValue = 0f; _FakeLight.floatValue = 0f; _RimLightOn.floatValue = 0; _workflow.floatValue = (float)Workflow.Metallic; _MetallicMap.textureValue = null; _GlossinessMap.textureValue = null; _SpMode.floatValue = (float)SpMode.Standard; _indirectSpecular.floatValue = (float)IndirectSpecular.Probe; _HighlightRamp.textureValue = TSConstants.DefaultRamp; _HighlightRampOffset.floatValue = 0f; _DetailMapOn.floatValue = 0f; break; case InspectorLevel.Normal: break; case InspectorLevel.Expert: break; } foreach (Material mat in _SpecularOn.targets) { TSFunctions.SetKeyword(mat, "_ENABLE_SPECULAR", mat.GetFloat(_SpecularOn.name) != 0); TSFunctions.SetKeyword(mat, "_DETAIL_MAP", mat.GetFloat(_DetailMapOn.name) != 0); } // Setup various keyword based settings SetupMaterialWithBlendMode(material, (BlendMode)material.GetFloat("_Mode")); SetupIndirectSource(material, (IndirectSpecular)material.GetFloat("_IndirectSpecular")); SetupWorkflow(material, (Workflow)material.GetFloat("_Workflow")); SetupSpMode(material, (SpMode)_SpMode.floatValue); // Setup emission MaterialEditor.FixupEmissiveFlag(material); bool shouldEmissionBeEnabled = (material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0; TSFunctions.SetKeyword(material, "_EMISSION", shouldEmissionBeEnabled); if (shouldEmissionBeEnabled) { material.SetOverrideTag("IsEmissive", "true"); } else { material.SetOverrideTag("IsEmissive", "false"); } // Add sections based on the inspector level group = new OrderedSectionGroup(); if (inspectorLevel == InspectorLevel.Basic) { group.addSection(new OrderedSection(Styles.specularOptions, DrawBasicSpecularOptionsSection, CheckBasicSpecularOptionsSection, SpecularOptionsIndex)); } else { group.addSection(new OrderedSection(Styles.rampOptions, DrawRampOptionsSection, CheckRampOptionsChanges, RampOptionsIndex)); group.addSection(new OrderedSection(Styles.rimOptions, DrawRimLightOptionsSection, CheckRimLightOptionsSection, RimLightOptionsIndex)); group.addSection(new OrderedSection(Styles.specularOptions, DrawSpecularOptionsSection, CheckSpecularOptionsSection, SpecularOptionsIndex)); group.addSection(new OrderedSection(Styles.detailOptions, DrawDetailOptionsSection, CheckDrawDetailOptionsSection, DetailOptionsIndex)); } }
public void DrawSection(MaterialEditor materialEditor) { EditorGUI.BeginChangeCheck(); TSFunctions.DrawSelector(Enum.GetNames(typeof(ToonyStandardGUI.BlendMode)), _blendMode, Styles.blendMode, materialEditor); if (EditorGUI.EndChangeCheck()) { foreach (Material mat in _blendMode.targets) { ToonyStandardGUI.SetupMaterialWithBlendMode(mat, (ToonyStandardGUI.BlendMode)_blendMode.floatValue, mat.GetFloat("_OutlineOn") > 0); } } //draw cull mode materialEditor.ShaderProperty(_Cull, Styles.cullMode); EditorGUILayout.Space(); //draw main properties materialEditor.TexturePropertySingleLine(Styles.mainTex, _MainTex, _Color); if ((ToonyStandardGUI.BlendMode)_blendMode.floatValue == ToonyStandardGUI.BlendMode.Cutout) { EditorGUI.indentLevel += MaterialEditor.kMiniTextureFieldLabelIndentLevel + 1; materialEditor.ShaderProperty(_Cutoff, Styles.cutOff); EditorGUI.indentLevel -= MaterialEditor.kMiniTextureFieldLabelIndentLevel + 1; } materialEditor.TexturePropertySingleLine(Styles.normal, _BumpMap, _BumpScale); if (level == InspectorLevel.Normal) { Rect r = TSFunctions.GetControlRectForSingleLine(); EditorGUI.BeginChangeCheck(); materialEditor.TexturePropertyMiniThumbnail(r, _OcclusionMap, Styles.occlusion.text, Styles.occlusion.tooltip); if (EditorGUI.EndChangeCheck()) { gui.RegenerateMSOT(false); } TSFunctions.ProperSlider(MaterialEditor.GetRectAfterLabelWidth(r), ref _Occlusion); } else { materialEditor.ShaderProperty(_Occlusion, Styles.occlusion); } //emission EditorGUI.BeginChangeCheck(); if (materialEditor.EmissionEnabledProperty()) { materialEditor.TexturePropertySingleLine(Styles.emission, _Emission, _EmissionColor); materialEditor.LightmapEmissionProperty(MaterialEditor.kMiniTextureFieldLabelIndentLevel); } if (EditorGUI.EndChangeCheck()) { foreach (Material mat in _Emission.targets) { MaterialEditor.FixupEmissiveFlag(mat); bool shouldEmissionBeEnabled = (mat.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0; TSFunctions.SetKeyword(mat, "_EMISSION", shouldEmissionBeEnabled); if (shouldEmissionBeEnabled) { mat.SetOverrideTag("IsEmissive", "true"); } else { mat.SetOverrideTag("IsEmissive", "false"); } } } //if in expert mode show the MSOT map and a button for the texture packer if (level == InspectorLevel.Expert) { EditorGUILayout.BeginHorizontal(); materialEditor.TexturePropertySingleLine(Styles.MSOT, _MSOT); if (GUILayout.Button(Styles.TexturePackerButton)) { EditorGUILayout.EndHorizontal(); isTexturePackerOpen = !isTexturePackerOpen; Styles.ToggleTexturePackerContent(isTexturePackerOpen); } else { EditorGUILayout.EndHorizontal(); } if (isTexturePackerOpen) { EditorGUILayout.BeginVertical("box"); packer.DrawGUI(); EditorGUILayout.EndVertical(); if (_MSOT.textureValue != (Texture)packer.resultTex && packer.resultTex != null) { _MSOT.textureValue = packer.resultTex; packer.resultTex = null; } } } EditorGUILayout.Space(); materialEditor.TextureScaleOffsetProperty(_MainTex); //EditorGUILayout.Space(); //materialEditor.RenderQueueField(); EditorGUILayout.Space(); }
// All Setup Keyword functions must be static. It allow to create script to automatically update the shaders with a script if ocde change static public void SetupBaseUnlitKeywords(Material material) { bool alphaTestEnable = material.GetFloat(kAlphaCutoffEnabled) > 0.0f; SurfaceType surfaceType = (SurfaceType)material.GetFloat(kSurfaceType); BlendMode blendMode = (BlendMode)material.GetFloat(kBlendMode); if (surfaceType == SurfaceType.Opaque) { material.SetOverrideTag("RenderType", alphaTestEnable ? "TransparentCutout" : ""); material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_ZWrite", 1); material.renderQueue = alphaTestEnable ? (int)UnityEngine.Rendering.RenderQueue.AlphaTest : -1; } else { material.SetOverrideTag("RenderType", "Transparent"); material.SetInt("_ZWrite", 0); material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent; switch (blendMode) { case BlendMode.Lerp: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); break; case BlendMode.Add: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One); break; case BlendMode.SoftAdd: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusDstColor); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One); break; case BlendMode.Multiply: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); break; case BlendMode.Premultiply: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); break; } } bool doubleSidedEnable = material.GetFloat(kDoubleSidedEnable) > 0.0f; if (doubleSidedEnable) { material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Off); } else { material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Back); } SetKeyword(material, "_DOUBLESIDED_ON", doubleSidedEnable); SetKeyword(material, "_ALPHATEST_ON", alphaTestEnable); if (material.HasProperty(kDistortionEnable)) { bool distortionEnable = material.GetFloat(kDistortionEnable) > 0.0f; if (distortionEnable) { material.SetShaderPassEnabled("DistortionVectors", true); } else { material.SetShaderPassEnabled("DistortionVectors", false); } bool distortionDepthTest = material.GetFloat(kDistortionDepthTest) > 0.0f; if (distortionDepthTest) { material.SetInt("_ZTestMode", (int)UnityEngine.Rendering.CompareFunction.LessEqual); } else { material.SetInt("_ZTestMode", (int)UnityEngine.Rendering.CompareFunction.Always); } SetKeyword(material, "_DISTORTION_ON", distortionEnable); } // A material's GI flag internally keeps track of whether emission is enabled at all, it's enabled but has no effect // or is enabled and may be modified at runtime. This state depends on the values of the current flag and emissive color. // The fixup routine makes sure that the material is in the correct state if/when changes are made to the mode or color. MaterialEditor.FixupEmissiveFlag(material); }
//Instead of LitGUI.SetMaterialKeywords public static void CustomSetMaterialKeywords(Material material) { if (material == null) { throw new ArgumentNullException("material"); } //Copied from BaseShaderGUI.SetMaterialKeywords material.shaderKeywords = null; CustomSetupMaterialBlendMode(material); if (material.HasProperty("_ReceiveShadows")) { CoreUtils.SetKeyword(material, "_RECEIVE_SHADOWS_OFF", material.GetFloat("_ReceiveShadows") == 0f); } if (material.HasProperty("_EmissionColor")) { MaterialEditor.FixupEmissiveFlag(material); } bool flag = (material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0; if (material.HasProperty("_EmissionEnabled") && !flag) { flag = (material.GetFloat("_EmissionEnabled") >= 0.5f); } CoreUtils.SetKeyword(material, "_EMISSION", flag); if (material.HasProperty("_BumpMap")) { CoreUtils.SetKeyword(material, "_NORMALMAP", material.GetTexture("_BumpMap")); } //Modified from LitShader.SetMaterialKeywords CoreUtils.SetKeyword(material, "_METALLICSPECGLOSSMAP", (material.GetTexture("_MetallicGlossMap") != null)); if (material.HasProperty("_EnvironmentReflections")) { CoreUtils.SetKeyword(material, "_ENVIRONMENTREFLECTIONS_OFF", material.GetFloat("_EnvironmentReflections") == 0f); } //Custom Add bool isHighQuality = false; if (material.HasProperty("_SettingQualityLevel")) { isHighQuality = material.GetFloat("_SettingQualityLevel") < 1; CoreUtils.SetKeyword(material, "_SETTING_QUALITY_LEVEL_1", !isHighQuality); } if (material.HasProperty("_EmissionEdge")) { int edgeMode = (int)material.GetFloat("_EmissionEdge"); CoreUtils.SetKeyword(material, "_EMISSION_EDGE", flag && edgeMode != 0); CoreUtils.SetKeyword(material, "_EMISSION_EDGE_GHOST", flag && edgeMode == 2); } if (material.HasProperty("_ExtraPassMask")) { int mask = (int)material.GetFloat("_ExtraPassMask"); bool isZWriteAlways = (mask & (int)ExtraPass.ZWriteAlways) != 0; material.SetShaderPassEnabled("ZWriteAlways", isZWriteAlways); bool isOutline = (mask & (int)ExtraPass.Outline) != 0; material.SetShaderPassEnabled("Outline", isOutline); material.SetShaderPassEnabled("Outline_Stencil", isOutline); CoreUtils.SetKeyword(material, "TCP2_TANGENT_AS_NORMALS", isOutline && !isHighQuality); CoreUtils.SetKeyword(material, "TCP2_COLORS_AS_NORMALS", isOutline && isHighQuality); //CoreUtils.SetKeyword(material, "_OUTLINE", isOutline); bool isShadowCaster = (mask & (int)ExtraPass.ShadowCaster) != 0; material.SetShaderPassEnabled("SHADOWCASTER", isShadowCaster); } }
public static void SetupBaseUnlitKeywords(this Material material) { bool alphaTestEnable = material.HasProperty(kAlphaCutoffEnabled) && material.GetFloat(kAlphaCutoffEnabled) > 0.0f; CoreUtils.SetKeyword(material, "_ALPHATEST_ON", alphaTestEnable); // Setup alpha to mask using the _AlphaToMaskInspectorValue that we configure in the material UI float alphaToMaskEnabled = material.HasProperty("_AlphaToMaskInspectorValue") && material.GetFloat("_AlphaToMaskInspectorValue") > 0.0 ? 1 : 0; material.SetFloat(kAlphaToMask, alphaTestEnable ? alphaToMaskEnabled : 0); bool alphaToMaskEnable = alphaTestEnable && material.HasProperty(kAlphaToMask) && material.GetFloat(kAlphaToMask) > 0.0f; CoreUtils.SetKeyword(material, "_ALPHATOMASK_ON", alphaToMaskEnable); SurfaceType surfaceType = material.GetSurfaceType(); CoreUtils.SetKeyword(material, "_SURFACE_TYPE_TRANSPARENT", surfaceType == SurfaceType.Transparent); bool enableBlendModePreserveSpecularLighting = (surfaceType == SurfaceType.Transparent) && material.HasProperty(kEnableBlendModePreserveSpecularLighting) && material.GetFloat(kEnableBlendModePreserveSpecularLighting) > 0.0f; CoreUtils.SetKeyword(material, "_BLENDMODE_PRESERVE_SPECULAR_LIGHTING", enableBlendModePreserveSpecularLighting); bool transparentWritesMotionVec = (surfaceType == SurfaceType.Transparent) && material.HasProperty(kTransparentWritingMotionVec) && material.GetInt(kTransparentWritingMotionVec) > 0; CoreUtils.SetKeyword(material, "_TRANSPARENT_WRITES_MOTION_VEC", transparentWritesMotionVec); // These need to always been set either with opaque or transparent! So a users can switch to opaque and remove the keyword correctly CoreUtils.SetKeyword(material, "_BLENDMODE_ALPHA", false); CoreUtils.SetKeyword(material, "_BLENDMODE_ADD", false); CoreUtils.SetKeyword(material, "_BLENDMODE_PRE_MULTIPLY", false); HDRenderQueue.RenderQueueType renderQueueType = HDRenderQueue.GetTypeByRenderQueueValue(material.renderQueue); bool needOffScreenBlendFactor = renderQueueType == HDRenderQueue.RenderQueueType.AfterPostprocessTransparent || renderQueueType == HDRenderQueue.RenderQueueType.LowTransparent; // Alpha tested materials always have a prepass where we perform the clip. // Then during Gbuffer pass we don't perform the clip test, so we need to use depth equal in this case. if (alphaTestEnable) { material.SetInt(kZTestGBuffer, (int)UnityEngine.Rendering.CompareFunction.Equal); } else { material.SetInt(kZTestGBuffer, (int)UnityEngine.Rendering.CompareFunction.LessEqual); } // If the material use the kZTestDepthEqualForOpaque it mean it require depth equal test for opaque but transparent are not affected if (material.HasProperty(kZTestDepthEqualForOpaque)) { if (surfaceType == SurfaceType.Opaque) { // When the material is after post process, we need to use LEssEqual because there is no depth prepass for unlit opaque if (HDRenderQueue.k_RenderQueue_AfterPostProcessOpaque.Contains(material.renderQueue)) { material.SetInt(kZTestDepthEqualForOpaque, (int)UnityEngine.Rendering.CompareFunction.LessEqual); } else { material.SetInt(kZTestDepthEqualForOpaque, (int)UnityEngine.Rendering.CompareFunction.Equal); } } else { material.SetInt(kZTestDepthEqualForOpaque, (int)material.GetTransparentZTest()); } } if (surfaceType == SurfaceType.Opaque) { material.SetOverrideTag("RenderType", alphaTestEnable ? "TransparentCutout" : ""); material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); // Caution: we need to setup One for src and Zero for Dst for all element as users could switch from transparent to Opaque and keep remaining value. // Unity will disable Blending based on these default value. // Note that for after postprocess we setup 0 in opacity inside the shaders, so we correctly end with 0 in opacity for the compositing pass material.SetInt("_AlphaSrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_AlphaDstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt(kZWrite, 1); } else { material.SetOverrideTag("RenderType", "Transparent"); material.SetInt(kZWrite, material.GetTransparentZWrite() ? 1 : 0); if (material.HasProperty(kBlendMode)) { BlendMode blendMode = material.GetBlendMode(); CoreUtils.SetKeyword(material, "_BLENDMODE_ALPHA", BlendMode.Alpha == blendMode); CoreUtils.SetKeyword(material, "_BLENDMODE_ADD", BlendMode.Additive == blendMode); CoreUtils.SetKeyword(material, "_BLENDMODE_PRE_MULTIPLY", BlendMode.Premultiply == blendMode); // When doing off-screen transparency accumulation, we change blend factors as described here: https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch23.html switch (blendMode) { // Alpha // color: src * src_a + dst * (1 - src_a) // src * src_a is done in the shader as it allow to reduce precision issue when using _BLENDMODE_PRESERVE_SPECULAR_LIGHTING (See Material.hlsl) case BlendMode.Alpha: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); if (needOffScreenBlendFactor) { material.SetInt("_AlphaSrcBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_AlphaDstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); } else { material.SetInt("_AlphaSrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_AlphaDstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); } break; // Additive // color: src * src_a + dst // src * src_a is done in the shader case BlendMode.Additive: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One); if (needOffScreenBlendFactor) { material.SetInt("_AlphaSrcBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_AlphaDstBlend", (int)UnityEngine.Rendering.BlendMode.One); } else { material.SetInt("_AlphaSrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_AlphaDstBlend", (int)UnityEngine.Rendering.BlendMode.One); } break; // PremultipliedAlpha // color: src * src_a + dst * (1 - src_a) // src is supposed to have been multiplied by alpha in the texture on artists side. case BlendMode.Premultiply: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); if (needOffScreenBlendFactor) { material.SetInt("_AlphaSrcBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_AlphaDstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); } else { material.SetInt("_AlphaSrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_AlphaDstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); } break; } } } bool fogEnabled = material.HasProperty(kEnableFogOnTransparent) && material.GetFloat(kEnableFogOnTransparent) > 0.0f && surfaceType == SurfaceType.Transparent; CoreUtils.SetKeyword(material, "_ENABLE_FOG_ON_TRANSPARENT", fogEnabled); if (material.HasProperty(kDistortionEnable) && material.HasProperty(kDistortionBlendMode)) { bool distortionDepthTest = material.GetFloat(kDistortionDepthTest) > 0.0f; if (material.HasProperty(kZTestModeDistortion)) { if (distortionDepthTest) { material.SetInt(kZTestModeDistortion, (int)UnityEngine.Rendering.CompareFunction.LessEqual); } else { material.SetInt(kZTestModeDistortion, (int)UnityEngine.Rendering.CompareFunction.Always); } } var distortionBlendMode = material.GetInt(kDistortionBlendMode); switch (distortionBlendMode) { default: case 0: // Add material.SetInt("_DistortionSrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DistortionDstBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DistortionBlurSrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DistortionBlurDstBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DistortionBlurBlendOp", (int)UnityEngine.Rendering.BlendOp.Add); break; case 1: // Multiply material.SetInt("_DistortionSrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor); material.SetInt("_DistortionDstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_DistortionBlurSrcBlend", (int)UnityEngine.Rendering.BlendMode.DstAlpha); material.SetInt("_DistortionBlurDstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_DistortionBlurBlendOp", (int)UnityEngine.Rendering.BlendOp.Add); break; case 2: // Replace material.SetInt("_DistortionSrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DistortionDstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_DistortionBlurSrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DistortionBlurDstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_DistortionBlurBlendOp", (int)UnityEngine.Rendering.BlendOp.Add); break; } } CullMode doubleSidedOffMode = (surfaceType == SurfaceType.Transparent) ? material.GetTransparentCullMode() : material.GetOpaqueCullMode(); bool isBackFaceEnable = material.HasProperty(kTransparentBackfaceEnable) && material.GetFloat(kTransparentBackfaceEnable) > 0.0f && surfaceType == SurfaceType.Transparent; bool doubleSidedEnable = material.HasProperty(kDoubleSidedEnable) && material.GetFloat(kDoubleSidedEnable) > 0.0f; // Disable culling if double sided material.SetInt("_CullMode", doubleSidedEnable ? (int)UnityEngine.Rendering.CullMode.Off : (int)doubleSidedOffMode); // We have a separate cullmode (_CullModeForward) for Forward in case we use backface then frontface rendering, need to configure it if (isBackFaceEnable) { material.SetInt("_CullModeForward", (int)UnityEngine.Rendering.CullMode.Back); } else { material.SetInt("_CullModeForward", (int)(doubleSidedEnable ? UnityEngine.Rendering.CullMode.Off : doubleSidedOffMode)); } CoreUtils.SetKeyword(material, "_DOUBLESIDED_ON", doubleSidedEnable); // A material's GI flag internally keeps track of whether emission is enabled at all, it's enabled but has no effect // or is enabled and may be modified at runtime. This state depends on the values of the current flag and emissive color. // The fixup routine makes sure that the material is in the correct state if/when changes are made to the mode or color. if (material.HasProperty(kEmissionColor)) { material.SetColor(kEmissionColor, Color.white); // kEmissionColor must always be white to allow our own material to control the GI (this allow to fallback from builtin unity to our system). // as it happen with old material that it isn't the case, we force it. MaterialEditor.FixupEmissiveFlag(material); } // Commented out for now because unfortunately we used the hard coded property names used by the GI system for our own parameters // So we need a way to work around that before we activate this. material.SetupMainTexForAlphaTestGI("_EmissiveColorMap", "_EmissiveColor"); // depth offset for ShaderGraphs (they don't have the displacement mode property) if (!material.HasProperty(kDisplacementMode) && material.HasProperty(kDepthOffsetEnable)) { // Depth offset is only enabled if per pixel displacement is bool depthOffsetEnable = (material.GetFloat(kDepthOffsetEnable) > 0.0f); CoreUtils.SetKeyword(material, "_DEPTHOFFSET_ON", depthOffsetEnable); } // DoubleSidedGI has to be synced with our double sided toggle var serializedObject = new SerializedObject(material); var doubleSidedGIppt = serializedObject.FindProperty("m_DoubleSidedGI"); doubleSidedGIppt.boolValue = doubleSidedEnable; serializedObject.ApplyModifiedProperties(); }
/// <summary> /// Initializzation that happens the first time the window is created /// </summary> /// <param name="materialEditor">Material editor provided by the custom inspector</param> /// <param name="properties">Array of materialProperties provided by the custom inspector</param> public void Start(MaterialEditor materialEditor, MaterialProperty[] properties) { //Temporary code for transitioning between 2017 to 2018 if (FindProperty("_NeedsFix", properties).floatValue == 0.5) { #if UNITY_2018_1_OR_NEWER FindProperty("_NeedsFix", properties).floatValue = 0; #else FindProperty("_NeedsFix", properties).floatValue = 1; #endif } EditorGUIUtility.labelWidth = 0f; //material = materialEditor.target as Material; //Initialize properties FindProperties(properties); //Initializes the ramp section based on the inspector level inspectorLevel = (InspectorLevel)EditorPrefs.GetInt("TSInspectorLevel"); switch (inspectorLevel) { case InspectorLevel.Basic: basicMain = new BasicMainSection(properties); break; case InspectorLevel.Normal: packer = new TexturePacker(TexturePacker.Resolution.M_512x512, new string[] { "Metallic", "Smoothness", "Ambient occlusion", "Thickness map" }, GetTextureDestinationPath((Material)_RampOn.targets[0], "MSOT.png")); main = new MainSection(properties, inspectorLevel, packer, this); Selection.selectionChanged += SetMSOT; break; case InspectorLevel.Expert: packer = new TexturePacker(TexturePacker.Resolution.M_512x512, new string[] { "Metallic", "Smoothness", "Ambient occlusion", "Thickness map" }, GetTextureDestinationPath((Material)_RampOn.targets[0], "MSOT.png")); main = new MainSection(properties, inspectorLevel, packer, this); break; } foreach (Material mat in FindProperty("_Mode", properties).targets) { //remove keywords not used in Toony Standard RemoveUnwantedKeywords(mat); // Setup various keyword based settings SetupMaterialWithBlendMode(mat, (BlendMode)mat.GetFloat("_Mode"), mat.GetFloat("_OutlineOn") > 0); // Setup emission MaterialEditor.FixupEmissiveFlag(mat); bool shouldEmissionBeEnabled = (mat.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0; TSFunctions.SetKeyword(mat, "_EMISSION", shouldEmissionBeEnabled); if (shouldEmissionBeEnabled) { mat.SetOverrideTag("IsEmissive", "true"); } else { mat.SetOverrideTag("IsEmissive", "false"); } } GenerateRampMinMax(properties); // Add sections based on the inspector level group = new OrderedSectionGroup(); if (inspectorLevel == InspectorLevel.Basic) { group.addSection(new BasicSpecularSection(properties, TSFunctions.BooleanFloat(_SpecularBox.floatValue), TSFunctions.BooleanFloat(_SpecularOn.floatValue))); group.addSection(new OutlineSection(properties, TSFunctions.BooleanFloat(_OutlineBox.floatValue), TSFunctions.BooleanFloat(_OutlineOn.floatValue))); } else { group.addSection(new RampSection(this, properties, TSFunctions.BooleanFloat(_ToonRampBox.floatValue), TSFunctions.BooleanFloat(_RampOn.floatValue))); group.addSection(new RimLightSection(properties, TSFunctions.BooleanFloat(_RimLightBox.floatValue), TSFunctions.BooleanFloat(_RimLightOn.floatValue))); group.addSection(new SpecularSection(properties, inspectorLevel, this, TSFunctions.BooleanFloat(_SpecularBox.floatValue), TSFunctions.BooleanFloat(_SpecularOn.floatValue))); group.addSection(new DetailSection(properties, TSFunctions.BooleanFloat(_DetailBox.floatValue), TSFunctions.BooleanFloat(_DetailMapOn.floatValue))); group.addSection(new SubsurfaceSection(properties, inspectorLevel, this, TSFunctions.BooleanFloat(_SSSBox.floatValue), TSFunctions.BooleanFloat(_SSSOn.floatValue))); group.addSection(new OutlineSection(properties, TSFunctions.BooleanFloat(_OutlineBox.floatValue), TSFunctions.BooleanFloat(_OutlineOn.floatValue))); } if (inspectorLevel == InspectorLevel.Expert) { group.addSection(new StencilSection(properties, TSFunctions.BooleanFloat(_StencilBox.floatValue), TSFunctions.BooleanFloat(_StencilOn.floatValue))); } else { FindProperty("_StencilID", properties).floatValue = 0; FindProperty("_StencilComp", properties).floatValue = 0; FindProperty("_StencilOp", properties).floatValue = 0; } }
private static void TextureAssignmentTool() { string[] projectTextures = AssetDatabase.FindAssets("t:Texture2D", new [] { "Assets" }); var selected = Selection.objects; GetEWScriptableObject(); foreach (var o in selected) { if (o.GetType() == typeof(Material)) { Material material = (Material)o; string shaderName = material.shader.name; EWScriptableObject.AssignmentProfile matchedProfile = new EWScriptableObject.AssignmentProfile(); foreach (EWScriptableObject.AssignmentProfile assignmentProfile in eWSettings.assignmentProfilesList) { if (assignmentProfile.shaderName == shaderName) { matchedProfile = assignmentProfile; } } if (matchedProfile.profileName != null) { //Filter Textures contain/start with Material Name string materialName = material.name; List <string> matMatchedTextures = new List <string>(); foreach (string projectTexture in projectTextures) { if ((GetFileName(projectTexture).StartsWith(materialName) && eWSettings.assignmentMethod == 0) || (GetFileName(projectTexture).Contains(materialName) && eWSettings.assignmentMethod == 1)) { matMatchedTextures.Add(projectTexture); } } //If was found textures with material name, Try assign it to Material Slots if (matMatchedTextures.Count > 0) { foreach (EWScriptableObject.AssignmentProfile.AssignmentProfileItem profileItem in matchedProfile.assignmentProfileItems) { string[] searchingTextureSuf = profileItem.textureName.Split(','); string slotMatchedTexture = ""; foreach (var matMatchedTexture in matMatchedTextures) { string textureName = GetFileName(matMatchedTexture); foreach (var textureSuf in searchingTextureSuf) { if (textureSuf.Trim(' ').Length > 0) { if (textureName.EndsWith(textureSuf.Trim(' '))) { slotMatchedTexture = matMatchedTexture; } } } } if (slotMatchedTexture.Length > 0) { Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(slotMatchedTexture), typeof(Texture2D)); material.SetTexture(profileItem.materialSlot, texture); string renderPipeline = GetRenderPipeline(); if (renderPipeline == "Legacy") { if (profileItem.materialSlot == "_BumpMap") { material.EnableKeyword("_NORMALMAP"); } if (profileItem.materialSlot == "_MetallicGlossMap") { material.EnableKeyword("_METALLICGLOSSMAP"); } if (profileItem.materialSlot == "_SpecGlossMap") { material.EnableKeyword("_SPECGLOSSMAP"); } if (profileItem.materialSlot == "_EmissionMap") { MaterialEditor.FixupEmissiveFlag(material); if (material.GetColor("_EmissionColor") == Color.black) { material.SetColor("_EmissionColor", Color.white); } material.EnableKeyword("_EMISSION"); material.globalIlluminationFlags = 0; } } if (renderPipeline == "URP") { if (profileItem.materialSlot == "_BumpMap") { material.EnableKeyword("_NORMALMAP"); } if (profileItem.materialSlot == "_MetallicGlossMap") { material.DisableKeyword("_SPECULAR_SETUP"); material.EnableKeyword("_METALLICSPECGLOSSMAP"); material.SetFloat("_WorkflowMode", 1); material.SetFloat("_Smoothness", 1); } if (profileItem.materialSlot == "_SpecGlossMap") { material.EnableKeyword("_SPECULAR_SETUP"); material.SetFloat("_WorkflowMode", 0); material.SetFloat("_Smoothness", 1); material.EnableKeyword("_METALLICSPECGLOSSMAP"); } if (profileItem.materialSlot == "_EmissionMap") { MaterialEditor.FixupEmissiveFlag(material); if (material.GetColor("_EmissionColor") == Color.black) { material.SetColor("_EmissionColor", Color.white); } material.EnableKeyword("_EMISSION"); material.globalIlluminationFlags = 0; } } if (renderPipeline == "HDRP") { if (profileItem.materialSlot == "_NormalMap") { material.EnableKeyword("_NORMALMAP"); } if (profileItem.materialSlot == "_MaskMap") { material.EnableKeyword("_MASKMAP"); } if (profileItem.materialSlot == "_SpecularColorMap") { material.EnableKeyword("_MATERIAL_FEATURE_SPECULAR_COLOR"); material.SetFloat("_MaterialID", 4f); } if (profileItem.materialSlot == "_EmissiveColorMap") { if (material.GetColor("_EmissiveColor") == Color.black) { material.SetColor("_EmissiveColor", Color.white); } material.EnableKeyword("_EMISSIVE_COLOR_MAP"); } } } } string materialPath = AssetDatabase.GetAssetPath(material); AssetDatabase.Refresh(); AssetDatabase.ImportAsset(materialPath, ImportAssetOptions.ForceUpdate); AssetDatabase.Refresh(); } } else { Debug.Log("Profile for Material " + material.name + " not found"); } } } }
// All Setup Keyword functions must be static. It allow to create script to automatically update the shaders with a script if ocde change static public void SetupBaseUnlitKeywords(Material material) { bool alphaTestEnable = material.HasProperty(kAlphaCutoffEnabled) && material.GetFloat(kAlphaCutoffEnabled) > 0.0f; CoreUtils.SetKeyword(material, "_ALPHATEST_ON", alphaTestEnable); SurfaceType surfaceType = (SurfaceType)material.GetFloat(kSurfaceType); CoreUtils.SetKeyword(material, "_SURFACE_TYPE_TRANSPARENT", surfaceType == SurfaceType.Transparent); bool enableBlendModePreserveSpecularLighting = material.HasProperty(kEnableBlendModePreserveSpecularLighting) && material.GetFloat(kEnableBlendModePreserveSpecularLighting) > 0.0f; CoreUtils.SetKeyword(material, "_BLENDMODE_PRESERVE_SPECULAR_LIGHTING", enableBlendModePreserveSpecularLighting); // These need to always been set either with opaque or transparent! So a users can switch to opaque and remove the keyword correctly CoreUtils.SetKeyword(material, "_BLENDMODE_ALPHA", false); CoreUtils.SetKeyword(material, "_BLENDMODE_ADD", false); CoreUtils.SetKeyword(material, "_BLENDMODE_PRE_MULTIPLY", false); if (surfaceType == SurfaceType.Opaque) { material.SetOverrideTag("RenderType", alphaTestEnable ? "TransparentCutout" : ""); material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_ZWrite", 1); material.renderQueue = alphaTestEnable ? (int)HDRenderQueue.AlphaTest : -1; } else { material.SetOverrideTag("RenderType", "Transparent"); material.SetInt("_ZWrite", 0); var isPrePass = material.HasProperty(kPreRefractionPass) && material.GetFloat(kPreRefractionPass) > 0.0f; material.renderQueue = (int)(isPrePass ? HDRenderQueue.PreRefraction : HDRenderQueue.Transparent); if (material.HasProperty(kBlendMode)) { BlendMode blendMode = (BlendMode)material.GetFloat(kBlendMode); CoreUtils.SetKeyword(material, "_BLENDMODE_ALPHA", BlendMode.Alpha == blendMode); CoreUtils.SetKeyword(material, "_BLENDMODE_ADD", BlendMode.Additive == blendMode); CoreUtils.SetKeyword(material, "_BLENDMODE_PRE_MULTIPLY", BlendMode.PremultipliedAlpha == blendMode); switch (blendMode) { // Alpha // color: src * src_a + dst * (1 - src_a) // src * src_a is done in the shader as it allow to reduce precision issue when using _BLENDMODE_PRESERVE_SPECULAR_LIGHTING (See Material.hlsl) case BlendMode.Alpha: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); break; // Additive // color: src * src_a + dst // src * src_a is done in the shader case BlendMode.Additive: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One); break; // PremultipliedAlpha // color: src * src_a + dst * (1 - src_a) // src is supposed to have been multiplied by alpha in the texture on artists side. case BlendMode.PremultipliedAlpha: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); break; } } } bool fogEnabled = material.HasProperty(kEnableFogOnTransparent) && material.GetFloat(kEnableFogOnTransparent) > 0.0f && surfaceType == SurfaceType.Transparent; CoreUtils.SetKeyword(material, "_ENABLE_FOG_ON_TRANSPARENT", fogEnabled); if (material.HasProperty(kDistortionEnable)) { bool distortionDepthTest = material.GetFloat(kDistortionDepthTest) > 0.0f; if (distortionDepthTest) { material.SetInt("_ZTestMode", (int)UnityEngine.Rendering.CompareFunction.LessEqual); } else { material.SetInt("_ZTestMode", (int)UnityEngine.Rendering.CompareFunction.Always); } var distortionBlendMode = material.GetInt(kDistortionBlendMode); switch (distortionBlendMode) { default: case 0: // Add material.SetInt("_DistortionSrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DistortionDstBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DistortionBlurSrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DistortionBlurDstBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DistortionBlurBlendOp", (int)UnityEngine.Rendering.BlendOp.Max); break; case 1: // Multiply material.SetInt("_DistortionSrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor); material.SetInt("_DistortionDstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_DistortionBlurSrcBlend", (int)UnityEngine.Rendering.BlendMode.DstAlpha); material.SetInt("_DistortionBlurDstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_DistortionBlurBlendOp", (int)UnityEngine.Rendering.BlendOp.Add); break; } } bool isBackFaceEnable = material.HasProperty(kTransparentBackfaceEnable) && material.GetFloat(kTransparentBackfaceEnable) > 0.0f && surfaceType == SurfaceType.Transparent; bool doubleSidedEnable = material.HasProperty(kDoubleSidedEnable) && material.GetFloat(kDoubleSidedEnable) > 0.0f; // Disable culling if double sided material.SetInt("_CullMode", doubleSidedEnable ? (int)UnityEngine.Rendering.CullMode.Off : (int)UnityEngine.Rendering.CullMode.Back); // We have a separate cullmode (_CullModeForward) for Forward in case we use backface then frontface rendering, need to configure it if (isBackFaceEnable) { material.SetInt("_CullModeForward", (int)UnityEngine.Rendering.CullMode.Back); } else { material.SetInt("_CullModeForward", doubleSidedEnable ? (int)UnityEngine.Rendering.CullMode.Off : (int)UnityEngine.Rendering.CullMode.Back); } CoreUtils.SetKeyword(material, "_DOUBLESIDED_ON", doubleSidedEnable); // A material's GI flag internally keeps track of whether emission is enabled at all, it's enabled but has no effect // or is enabled and may be modified at runtime. This state depends on the values of the current flag and emissive color. // The fixup routine makes sure that the material is in the correct state if/when changes are made to the mode or color. MaterialEditor.FixupEmissiveFlag(material); // Commented out for now because unfortunately we used the hard coded property names used by the GI system for our own parameters // So we need a way to work around that before we activate this. SetupMainTexForAlphaTestGI("_EmissiveColorMap", "_EmissiveColor", material); // DoubleSidedGI has to be synced with our double sided toggle var serializedObject = new SerializedObject(material); var doubleSidedGIppt = serializedObject.FindProperty("m_DoubleSidedGI"); doubleSidedGIppt.boolValue = doubleSidedEnable; serializedObject.ApplyModifiedProperties(); }
static void SetMaterialKeywords(Material material) { // Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation // (MaterialProperty value might come from renderer material property block) bool isSpecularWorkFlow = (WorkflowMode)material.GetFloat("_WorkflowMode") == WorkflowMode.Specular; bool hasGlossMap = false; if (isSpecularWorkFlow) { hasGlossMap = material.GetTexture("_SpecGlossMap"); } else { hasGlossMap = material.GetTexture("_MetallicGlossMap"); } bool doubleSidedEnable = material.GetFloat(kDoubleSidedEnable) == 1.0f; if (doubleSidedEnable) { DoubleSidedNormalMode doubleSidedNormalMode = (DoubleSidedNormalMode)material.GetFloat(kDoubleSidedNormalMode); switch (doubleSidedNormalMode) { case DoubleSidedNormalMode.Mirror: // Mirror mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, -1.0f, 0.0f)); break; case DoubleSidedNormalMode.Flip: // Flip mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(-1.0f, -1.0f, -1.0f, 0.0f)); break; case DoubleSidedNormalMode.None: // None mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, 1.0f, 0.0f)); break; } } //#if defined(_ENABLE_WIND_SINGLE) || defined(_ENABLE_WIND_HIERARCHY) || defined(_ENABLE_WIND_PROCEDURAL) VertexAnimationMode vertAnimMode = (VertexAnimationMode)material.GetFloat("_VertexAnimation"); switch (vertAnimMode) { case VertexAnimationMode.None: CoreUtils.SetKeyword(material, "_ENABLE_WIND_SINGLE", false); CoreUtils.SetKeyword(material, "_ENABLE_WIND_HIERARCHY", false); CoreUtils.SetKeyword(material, "_ENABLE_WIND_PROCEDURAL", false); break; case VertexAnimationMode.Hierarchy: CoreUtils.SetKeyword(material, "_ENABLE_WIND_SINGLE", false); CoreUtils.SetKeyword(material, "_ENABLE_WIND_HIERARCHY", true); CoreUtils.SetKeyword(material, "_ENABLE_WIND_PROCEDURAL", false); break; case VertexAnimationMode.Single: CoreUtils.SetKeyword(material, "_ENABLE_WIND_SINGLE", true); CoreUtils.SetKeyword(material, "_ENABLE_WIND_HIERARCHY", false); CoreUtils.SetKeyword(material, "_ENABLE_WIND_PROCEDURAL", false); break; case VertexAnimationMode.Procedural: CoreUtils.SetKeyword(material, "_ENABLE_WIND_SINGLE", false); CoreUtils.SetKeyword(material, "_ENABLE_WIND_HIERARCHY", false); CoreUtils.SetKeyword(material, "_ENABLE_WIND_PROCEDURAL", true); break; } CoreUtils.SetKeyword(material, "_DOUBLESIDED_ON", doubleSidedEnable); bool isAnisotropic = (BRDFMode)material.GetFloat("_BRDFMode") == BRDFMode.Anisotropic && material.GetTexture("_TangentMap"); CoreUtils.SetKeyword(material, "_BRDF_ANISO", isAnisotropic); CoreUtils.SetKeyword(material, "_BRDF_STANDARD", !isAnisotropic); CoreUtils.SetKeyword(material, "_SPECULAR_SETUP", isSpecularWorkFlow); CoreUtils.SetKeyword(material, "_METALLICSPECGLOSSMAP", hasGlossMap); CoreUtils.SetKeyword(material, "_SPECGLOSSMAP", hasGlossMap && isSpecularWorkFlow); CoreUtils.SetKeyword(material, "_METALLICGLOSSMAP", hasGlossMap && !isSpecularWorkFlow); CoreUtils.SetKeyword(material, "_NORMALMAP", material.GetTexture("_BumpMap") || material.GetTexture("_DetailNormalMap")); CoreUtils.SetKeyword(material, "_SPECULARHIGHLIGHTS_OFF", material.GetFloat("_SpecularHighlights") == 0.0f); CoreUtils.SetKeyword(material, "_GLOSSYREFLECTIONS_OFF", material.GetFloat("_GlossyReflections") == 0.0f); CoreUtils.SetKeyword(material, "_OCCLUSIONMAP", material.GetTexture("_OcclusionMap")); CoreUtils.SetKeyword(material, "_PARALLAXMAP", material.GetTexture("_ParallaxMap")); CoreUtils.SetKeyword(material, "_DETAIL_MASK", material.GetTexture("_DetailMask")); CoreUtils.SetKeyword(material, "_DETAIL", material.GetTexture("_DetailAlbedoMap") || material.GetTexture("_DetailNormalMap")); CoreUtils.SetKeyword(material, "_DETAIL_MULX2", material.GetTexture("_DetailAlbedoMap") || material.GetTexture("_DetailNormalMap")); // A material's GI flag internally keeps track of whether emission is enabled at all, it's enabled but has no effect // or is enabled and may be modified at runtime. This state depends on the values of the current flag and emissive color. // The fixup routine makes sure that the material is in the correct state if/when changes are made to the mode or color. MaterialEditor.FixupEmissiveFlag(material); bool shouldEmissionBeEnabled = (material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0; CoreUtils.SetKeyword(material, "_EMISSION", shouldEmissionBeEnabled); if (material.HasProperty("_SmoothnessTextureChannel")) { CoreUtils.SetKeyword(material, "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A", GetSmoothnessMapChannel(material) == SmoothnessMapChannel.AlbedoAlpha); } }