// All Setup Keyword functions must be static. It allow to create script to automatically update the shaders with a script if code change static public void SetupMaterialKeywordsAndPass(Material material) { Decal.MaskBlendFlags blendMode = (Decal.MaskBlendFlags)material.GetFloat(kMaskBlendMode); CoreUtils.SetKeyword(material, "_ALBEDOCONTRIBUTION", material.GetFloat(kAlbedoMode) == 1.0f); CoreUtils.SetKeyword(material, "_COLORMAP", material.GetTexture(kBaseColorMap)); CoreUtils.SetKeyword(material, "_NORMALMAP", material.GetTexture(kNormalMap)); CoreUtils.SetKeyword(material, "_MASKMAP", material.GetTexture(kMaskMap)); CoreUtils.SetKeyword(material, "_EMISSIVEMAP", material.GetTexture(kEmissiveColorMap)); material.SetInt(kDecalStencilWriteMask, (int)StencilUsage.Decals); material.SetInt(kDecalStencilRef, (int)StencilUsage.Decals); material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMStr, false); material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsAOStr, false); material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMAOStr, false); material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsSStr, false); material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMSStr, false); material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsAOSStr, false); material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMAOSStr, false); material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecals3RTStr, true); material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsForwardEmissive, material.GetFloat("_Emissive") == 1.0f); switch (blendMode) { case Decal.MaskBlendFlags.Metal: material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMStr, true); break; case Decal.MaskBlendFlags.AO: material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsAOStr, true); break; case Decal.MaskBlendFlags.Metal | Decal.MaskBlendFlags.AO: material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMAOStr, true); break; case Decal.MaskBlendFlags.Smoothness: material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsSStr, true); break; case Decal.MaskBlendFlags.Metal | Decal.MaskBlendFlags.Smoothness: material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMSStr, true); break; case Decal.MaskBlendFlags.AO | Decal.MaskBlendFlags.Smoothness: material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsAOSStr, true); break; case Decal.MaskBlendFlags.Metal | Decal.MaskBlendFlags.AO | Decal.MaskBlendFlags.Smoothness: material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMAOSStr, true); break; } }
// All Setup Keyword functions must be static. It allow to create script to automatically update the shaders with a script if code change static public void SetupMaterialKeywordsAndPass(Material material) { Decal.MaskBlendFlags blendMode = (Decal.MaskBlendFlags)material.GetFloat(kMaskBlendMode); CoreUtils.SetKeyword(material, "_ALBEDOCONTRIBUTION", material.GetFloat(kAlbedoMode) == 1.0f); CoreUtils.SetKeyword(material, "_COLORMAP", material.GetTexture(kBaseColorMap)); CoreUtils.SetKeyword(material, "_NORMALMAP", material.GetTexture(kNormalMap)); CoreUtils.SetKeyword(material, "_MASKMAP", material.GetTexture(kMaskMap)); CoreUtils.SetKeyword(material, "_NORMAL_BLEND_SRC_B", material.GetFloat(kNormalBlendSrc) == 1.0f); CoreUtils.SetKeyword(material, "_MASK_BLEND_SRC_B", material.GetFloat(kMaskBlendSrc) == 1.0f); material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMStr, false); material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsAOStr, false); material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMAOStr, false); material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsSStr, false); material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMSStr, false); material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsAOSStr, false); material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMAOSStr, false); material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecals3RTStr, true); switch (blendMode) { case Decal.MaskBlendFlags.Metal: material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMStr, true); break; case Decal.MaskBlendFlags.AO: material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsAOStr, true); break; case Decal.MaskBlendFlags.Metal | Decal.MaskBlendFlags.AO: material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMAOStr, true); break; case Decal.MaskBlendFlags.Smoothness: material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsSStr, true); break; case Decal.MaskBlendFlags.Metal | Decal.MaskBlendFlags.Smoothness: material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMSStr, true); break; case Decal.MaskBlendFlags.AO | Decal.MaskBlendFlags.Smoothness: material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsAOSStr, true); break; case Decal.MaskBlendFlags.Metal | Decal.MaskBlendFlags.AO | Decal.MaskBlendFlags.Smoothness: material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMAOSStr, true); break; } }
void DrawDecalGUI() { normalBlendSrcValue = normalBlendSrc.floatValue; maskBlendSrcValue = maskBlendSrc.floatValue; smoothnessRemapMinValue = smoothnessRemapMin.floatValue; smoothnessRemapMaxValue = smoothnessRemapMax.floatValue; AORemapMinValue = AORemapMin.floatValue; AORemapMaxValue = AORemapMax.floatValue; maskBlendFlags = (Decal.MaskBlendFlags)maskBlendMode.floatValue; HDRenderPipelineAsset hdrp = HDRenderPipeline.currentAsset; bool perChannelMask = hdrp.currentPlatformRenderPipelineSettings.decalSettings.perChannelMask; // Detect any changes to the material EditorGUI.BeginChangeCheck(); { materialEditor.TexturePropertySingleLine((materials[0].GetFloat(kAlbedoMode) == 1.0f) ? Styles.baseColorText : Styles.baseColorText2, baseColorMap, baseColor); // Currently always display Albedo contribution as we have an albedo tint that apply EditorGUI.indentLevel++; materialEditor.ShaderProperty(albedoMode, Styles.albedoModeText); EditorGUI.indentLevel--; materialEditor.TexturePropertySingleLine(Styles.normalMapText, normalMap); if (materials.All(m => m.GetTexture(kNormalMap))) { EditorGUI.indentLevel++; normalBlendSrcValue = EditorGUILayout.Popup(Styles.normalOpacityChannelText, (int)normalBlendSrcValue, blendSourceNames); EditorGUI.indentLevel--; } materialEditor.TexturePropertySingleLine(Styles.maskMapText[(int)maskBlendFlags], maskMap); if (materials.All(m => m.GetTexture(kMaskMap))) { EditorGUI.indentLevel++; EditorGUILayout.MinMaxSlider(Styles.smoothnessRemappingText, ref smoothnessRemapMinValue, ref smoothnessRemapMaxValue, 0.0f, 1.0f); if (perChannelMask) { materialEditor.ShaderProperty(metallicScale, Styles.metallicText); EditorGUILayout.MinMaxSlider(Styles.aoRemappingText, ref AORemapMinValue, ref AORemapMaxValue, 0.0f, 1.0f); } maskBlendSrcValue = EditorGUILayout.Popup(Styles.maskOpacityChannelText, (int)maskBlendSrcValue, blendSourceNames); if (perChannelMask) { bool mustDisableScope = false; if (maskmapMetal.floatValue + maskmapAO.floatValue + maskmapSmoothness.floatValue == 1.0f) { mustDisableScope = true; } using (new EditorGUI.DisabledScope(mustDisableScope && maskmapMetal.floatValue == 1.0f)) { materialEditor.ShaderProperty(maskmapMetal, Styles.affectMetalText); } using (new EditorGUI.DisabledScope(mustDisableScope && maskmapAO.floatValue == 1.0f)) { materialEditor.ShaderProperty(maskmapAO, Styles.affectAmbientOcclusionText); } using (new EditorGUI.DisabledScope(mustDisableScope && maskmapSmoothness.floatValue == 1.0f)) { materialEditor.ShaderProperty(maskmapSmoothness, Styles.affectSmoothnessText); } // Sanity condition in case for whatever reasons all value are 0.0 but it should never happen if ((maskmapMetal.floatValue == 0.0f) && (maskmapAO.floatValue == 0.0f) && (maskmapSmoothness.floatValue == 0.0f)) { maskmapSmoothness.floatValue = 1.0f; } maskBlendFlags = 0; // Re-init the mask if (maskmapMetal.floatValue == 1.0f) { maskBlendFlags |= Decal.MaskBlendFlags.Metal; } if (maskmapAO.floatValue == 1.0f) { maskBlendFlags |= Decal.MaskBlendFlags.AO; } if (maskmapSmoothness.floatValue == 1.0f) { maskBlendFlags |= Decal.MaskBlendFlags.Smoothness; } } else // if perChannelMask is not enabled, force to have smoothness { maskBlendFlags = Decal.MaskBlendFlags.Smoothness; } EditorGUI.indentLevel--; } materialEditor.ShaderProperty(maskMapBlueScale, Styles.maskMapBlueScaleText); materialEditor.ShaderProperty(decalBlend, Styles.decalBlendText); materialEditor.ShaderProperty(emissive, Styles.emissiveText); if (emissive.floatValue == 1.0f) { materialEditor.ShaderProperty(useEmissiveIntensity, Styles.useEmissionIntensityText); if (useEmissiveIntensity.floatValue == 1.0f) { materialEditor.TexturePropertySingleLine(Styles.emissionMapText, emissiveColorMap, emissiveColorLDR); using (new EditorGUILayout.HorizontalScope()) { EmissiveIntensityUnit unit = (EmissiveIntensityUnit)emissiveIntensityUnit.floatValue; if (unit == EmissiveIntensityUnit.Nits) { materialEditor.ShaderProperty(emissiveIntensity, Styles.emissiveIntensityText); } else { float evValue = LightUtils.ConvertLuminanceToEv(emissiveIntensity.floatValue); evValue = EditorGUILayout.FloatField(Styles.emissiveIntensityText, evValue); emissiveIntensity.floatValue = LightUtils.ConvertEvToLuminance(evValue); } emissiveIntensityUnit.floatValue = (float)(EmissiveIntensityUnit)EditorGUILayout.EnumPopup(unit); } } else { materialEditor.TexturePropertySingleLine(Styles.emissionMapText, emissiveColorMap, emissiveColorHDR); } materialEditor.ShaderProperty(emissiveExposureWeight, Styles.emissiveExposureWeightText); } if (!perChannelMask) { EditorGUILayout.HelpBox("Enable 'Metal and AO properties' in your HDRP Asset if you want to control the Metal and AO properties of decals.\nThere is a performance cost of enabling this option.", MessageType.Info); } } }
public void ShaderPropertiesGUI(Material material) { // Use default labelWidth EditorGUIUtility.labelWidth = 0f; float normalBlendSrcValue = normalBlendSrc.floatValue; float maskBlendSrcValue = maskBlendSrc.floatValue; Decal.MaskBlendFlags maskBlendFlags = (Decal.MaskBlendFlags)maskBlendMode.floatValue; HDRenderPipelineAsset hdrp = GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset; bool perChannelMask = hdrp.renderPipelineSettings.decalSettings.perChannelMask; using (var header = new HeaderScope(Styles.InputsText, (uint)Expendable.Input, this)) { if (header.expended) { // Detect any changes to the material EditorGUI.BeginChangeCheck(); { m_MaterialEditor.TexturePropertySingleLine((material.GetFloat(kAlbedoMode) == 1.0f) ? Styles.baseColorText : Styles.baseColorText2, baseColorMap, baseColor); // Currently always display Albedo contribution as we have an albedo tint that apply EditorGUI.indentLevel++; m_MaterialEditor.ShaderProperty(albedoMode, Styles.AlbedoModeText); EditorGUI.indentLevel--; m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, normalMap); if (material.GetTexture(kNormalMap)) { EditorGUI.indentLevel++; normalBlendSrcValue = EditorGUILayout.Popup("Normal Opacity channel", (int)normalBlendSrcValue, blendSourceNames); EditorGUI.indentLevel--; } m_MaterialEditor.TexturePropertySingleLine(Styles.maskMapText[(int)maskBlendFlags], maskMap); if (material.GetTexture(kMaskMap)) { EditorGUI.indentLevel++; maskBlendSrcValue = EditorGUILayout.Popup("Mask Opacity channel", (int)maskBlendSrcValue, blendSourceNames); if (perChannelMask) { // Following condition force users to always have at least one attribute enabled m_MaterialEditor.ShaderProperty(maskmapMetal, "Affect Metal"); if ((maskmapMetal.floatValue == 0.0f) && (maskmapAO.floatValue == 0.0f) && (maskmapSmoothness.floatValue == 0.0f)) { maskmapMetal.floatValue = 1.0f; } m_MaterialEditor.ShaderProperty(maskmapAO, "Affect AO"); if ((maskmapMetal.floatValue == 0.0f) && (maskmapAO.floatValue == 0.0f) && (maskmapSmoothness.floatValue == 0.0f)) { maskmapAO.floatValue = 1.0f; } m_MaterialEditor.ShaderProperty(maskmapSmoothness, "Affect Smoothness"); if ((maskmapMetal.floatValue == 0.0f) && (maskmapAO.floatValue == 0.0f) && (maskmapSmoothness.floatValue == 0.0f)) { maskmapSmoothness.floatValue = 1.0f; } maskBlendFlags = 0; // Re-init the mask if (maskmapMetal.floatValue == 1.0f) { maskBlendFlags |= Decal.MaskBlendFlags.Metal; } if (maskmapAO.floatValue == 1.0f) { maskBlendFlags |= Decal.MaskBlendFlags.AO; } if (maskmapSmoothness.floatValue == 1.0f) { maskBlendFlags |= Decal.MaskBlendFlags.Smoothness; } } else // if perChannelMask is not enabled, force to have smoothness { maskBlendFlags = Decal.MaskBlendFlags.Smoothness; } EditorGUI.indentLevel--; } m_MaterialEditor.ShaderProperty(drawOrder, Styles.DrawOrderText); m_MaterialEditor.ShaderProperty(decalMeshDepthBias, Styles.MeshDecalDepthBiasText); m_MaterialEditor.ShaderProperty(decalBlend, Styles.decalBlendText); EditorGUI.indentLevel--; EditorGUILayout.HelpBox( "Control of AO and Metal is based on option 'Enable Metal and AO properties' in HDRP Asset.\nThere is a performance cost of enabling this option.", MessageType.Info); } if (EditorGUI.EndChangeCheck()) { normalBlendSrc.floatValue = normalBlendSrcValue; maskBlendSrc.floatValue = maskBlendSrcValue; maskBlendMode.floatValue = (float)maskBlendFlags; foreach (var obj in m_MaterialEditor.targets) { SetupMaterialKeywordsAndPassInternal((Material)obj); } } } } }
public void ShaderPropertiesGUI(Material material) { // Use default labelWidth EditorGUIUtility.labelWidth = 0f; float normalBlendSrcValue = normalBlendSrc.floatValue; float maskBlendSrcValue = maskBlendSrc.floatValue; float smoothnessRemapMinValue = smoothnessRemapMin.floatValue; float smoothnessRemapMaxValue = smoothnessRemapMax.floatValue; float AORemapMinValue = AORemapMin.floatValue; float AORemapMaxValue = AORemapMax.floatValue; Decal.MaskBlendFlags maskBlendFlags = (Decal.MaskBlendFlags)maskBlendMode.floatValue; HDRenderPipelineAsset hdrp = GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset; bool perChannelMask = hdrp.currentPlatformRenderPipelineSettings.decalSettings.perChannelMask; using (var header = new HeaderScope(Styles.InputsText, (uint)Expandable.Input, this)) { if (header.expanded) { // Detect any changes to the material EditorGUI.BeginChangeCheck(); { m_MaterialEditor.TexturePropertySingleLine((material.GetFloat(kAlbedoMode) == 1.0f) ? Styles.baseColorText : Styles.baseColorText2, baseColorMap, baseColor); // Currently always display Albedo contribution as we have an albedo tint that apply EditorGUI.indentLevel++; m_MaterialEditor.ShaderProperty(albedoMode, Styles.albedoModeText); EditorGUI.indentLevel--; m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, normalMap); if (material.GetTexture(kNormalMap)) { EditorGUI.indentLevel++; normalBlendSrcValue = EditorGUILayout.Popup("Normal Opacity channel", (int)normalBlendSrcValue, blendSourceNames); EditorGUI.indentLevel--; } m_MaterialEditor.TexturePropertySingleLine(Styles.maskMapText[(int)maskBlendFlags], maskMap); if (material.GetTexture(kMaskMap)) { EditorGUI.indentLevel++; EditorGUILayout.MinMaxSlider(Styles.smoothnessRemappingText, ref smoothnessRemapMinValue, ref smoothnessRemapMaxValue, 0.0f, 1.0f); if (perChannelMask) { m_MaterialEditor.ShaderProperty(metallicScale, Styles.metallicText); EditorGUILayout.MinMaxSlider(Styles.aoRemappingText, ref AORemapMinValue, ref AORemapMaxValue, 0.0f, 1.0f); } maskBlendSrcValue = EditorGUILayout.Popup("Mask Opacity channel", (int)maskBlendSrcValue, blendSourceNames); if (perChannelMask) { bool mustDisableScope = false; if (maskmapMetal.floatValue + maskmapAO.floatValue + maskmapSmoothness.floatValue == 1.0f) { mustDisableScope = true; } using (new EditorGUI.DisabledScope(mustDisableScope && maskmapMetal.floatValue == 1.0f)) { m_MaterialEditor.ShaderProperty(maskmapMetal, "Affect Metal"); } using (new EditorGUI.DisabledScope(mustDisableScope && maskmapAO.floatValue == 1.0f)) { m_MaterialEditor.ShaderProperty(maskmapAO, "Affect AO"); } using (new EditorGUI.DisabledScope(mustDisableScope && maskmapSmoothness.floatValue == 1.0f)) { m_MaterialEditor.ShaderProperty(maskmapSmoothness, "Affect Smoothness"); } // Sanity condition in case for whatever reasons all value are 0.0 but it should never happen if ((maskmapMetal.floatValue == 0.0f) && (maskmapAO.floatValue == 0.0f) && (maskmapSmoothness.floatValue == 0.0f)) { maskmapSmoothness.floatValue = 1.0f; } maskBlendFlags = 0; // Re-init the mask if (maskmapMetal.floatValue == 1.0f) { maskBlendFlags |= Decal.MaskBlendFlags.Metal; } if (maskmapAO.floatValue == 1.0f) { maskBlendFlags |= Decal.MaskBlendFlags.AO; } if (maskmapSmoothness.floatValue == 1.0f) { maskBlendFlags |= Decal.MaskBlendFlags.Smoothness; } } else // if perChannelMask is not enabled, force to have smoothness { maskBlendFlags = Decal.MaskBlendFlags.Smoothness; } EditorGUI.indentLevel--; } m_MaterialEditor.ShaderProperty(maskMapBlueScale, Styles.maskMapBlueScaleText); m_MaterialEditor.ShaderProperty(decalBlend, Styles.decalBlendText); m_MaterialEditor.ShaderProperty(emissive, "Emissive"); if (emissive.floatValue == 1.0f) { m_MaterialEditor.ShaderProperty(useEmissiveIntensity, "Use Emission Intensity"); if (useEmissiveIntensity.floatValue == 1.0f) { m_MaterialEditor.TexturePropertySingleLine(Styles.emissiveText, emissiveColorMap, emissiveColorLDR); using (new EditorGUILayout.HorizontalScope()) { EmissiveIntensityUnit unit = (EmissiveIntensityUnit)emissiveIntensityUnit.floatValue; if (unit == EmissiveIntensityUnit.Luminance) { m_MaterialEditor.ShaderProperty(emissiveIntensity, Styles.emissiveIntensityText); } else { float evValue = LightUtils.ConvertLuminanceToEv(emissiveIntensity.floatValue); evValue = EditorGUILayout.FloatField(Styles.emissiveIntensityText, evValue); emissiveIntensity.floatValue = LightUtils.ConvertEvToLuminance(evValue); } emissiveIntensityUnit.floatValue = (float)(EmissiveIntensityUnit)EditorGUILayout.EnumPopup(unit); } } else { m_MaterialEditor.TexturePropertySingleLine(Styles.emissiveText, emissiveColorMap, emissiveColorHDR); } } EditorGUI.indentLevel--; EditorGUILayout.HelpBox( "Control of AO and Metal is based on option 'Enable Metal and AO properties' in HDRP Asset.\nThere is a performance cost of enabling this option.", MessageType.Info); } if (EditorGUI.EndChangeCheck()) { normalBlendSrc.floatValue = normalBlendSrcValue; maskBlendSrc.floatValue = maskBlendSrcValue; maskBlendMode.floatValue = (float)maskBlendFlags; smoothnessRemapMin.floatValue = smoothnessRemapMinValue; smoothnessRemapMax.floatValue = smoothnessRemapMaxValue; AORemapMin.floatValue = AORemapMinValue; AORemapMax.floatValue = AORemapMaxValue; if (useEmissiveIntensity.floatValue == 1.0f) { emissiveColor.colorValue = emissiveColorLDR.colorValue * emissiveIntensity.floatValue; } else { emissiveColor.colorValue = emissiveColorHDR.colorValue; } foreach (var obj in m_MaterialEditor.targets) { SetupMaterialKeywordsAndPassInternal((Material)obj); } } } } EditorGUI.indentLevel++; using (var header = new HeaderScope(Styles.SortingText, (uint)Expandable.Sorting, this)) { if (header.expanded) { m_MaterialEditor.ShaderProperty(drawOrder, Styles.drawOrderText); m_MaterialEditor.ShaderProperty(decalMeshDepthBias, Styles.meshDecalDepthBiasText); } } EditorGUI.indentLevel--; }