bool checkSpecUsage(Material mat, string label) { if ((label.IndexOf("layer Spec+Gloss")<0) && (label.IndexOf("gloss mask")<0) && (label.IndexOf("Spec (RGB)")<0)) return true; if (!mat.HasProperty("_DirectSpec")) return true; if (!mat.HasProperty("_IBLSpec")) return true; if (mat.GetFloat("_DirectSpec")==0 && mat.GetFloat("_IBLSpec")==0) return false; return true; }
void Update() { terrain = GetComponent<Terrain>(); tData = terrain ? terrain.terrainData : null; tMaterial = terrain ? terrain.materialTemplate : null; if (!terrain || !tData || !tMaterial) return; if(disableBasemap && !Application.isPlaying && GetComponent<Terrain>().basemapDistance != 1000000) // only reset on update in edit mode GetComponent<Terrain>().basemapDistance = 1000000; if (cutoutMode) { if (tMaterial.HasProperty("_CutoutModeHideAlpha") && tMaterial.GetFloat("_CutoutModeHideAlpha") != cutoutModeHideAlpha) tMaterial.SetFloat("_CutoutModeHideAlpha", cutoutModeHideAlpha); } else if (tMaterial.HasProperty("_CutoutModeHideAlpha") && tMaterial.GetFloat("_CutoutModeHideAlpha") != -1) tMaterial.SetFloat("_CutoutModeHideAlpha", -1); if (!Application.isPlaying) ApplyTransparencyMap(); else if (!transparencyMap && autoUpdateTransparencyMap) { UpdateTransparencyMap(); ApplyTransparencyMap(); } else ApplyTransparencyMap(); }
public 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 && material.HasProperty("_SpecGlossMap")) SetKeyword(material, "_SPECGLOSSMAP", material.GetTexture("_SpecGlossMap")); else if (workflowMode == WorkflowMode.Metallic && material.HasProperty("_MetallicGlossMap")) SetKeyword(material, "_METALLICGLOSSMAP", material.GetTexture("_MetallicGlossMap")); SetKeyword(material, "_PARALLAXMAP", material.GetTexture("_ParallaxMap")); SetKeyword(material, "_DETAIL_MULX2", material.GetTexture("_DetailAlbedoMap") || material.GetTexture("_DetailNormalMap")); bool shouldEmissionBeEnabled = ShouldEmissionBeEnabled(material.GetColor("_EmissionColor")); SetKeyword(material, "_EMISSION", shouldEmissionBeEnabled); // Setup lightmap emissive flags MaterialGlobalIlluminationFlags flags = material.globalIlluminationFlags; if ((flags & (MaterialGlobalIlluminationFlags.BakedEmissive | MaterialGlobalIlluminationFlags.RealtimeEmissive)) != 0) { flags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack; if (!shouldEmissionBeEnabled) flags |= MaterialGlobalIlluminationFlags.EmissiveIsBlack; material.globalIlluminationFlags = flags; } SetKeyword(material, "_VERTEXCOLOR", material.GetFloat("_IntensityVC") > 0f); }
public static string CheckMaterial(Material mat, BuildTarget buildTarget) { if (mat == null || mat.shader == null) { return null; } string shaderName = mat.shader.name; int lOD = ShaderUtil.GetLOD(mat.shader); bool flag = Array.Exists<string>(PerformanceChecks.kShadersWithMobileVariants, (string s) => s == shaderName); bool flag2 = PerformanceChecks.IsMobileBuildTarget(buildTarget); if (buildTarget == BuildTarget.Android && ShaderUtil.HasClip(mat.shader)) { return PerformanceChecks.FormattedTextContent("PerformanceChecks.ShaderWithClipAndroid", new object[0]); } if (!(mat.GetTag("PerformanceChecks", true).ToLower() == "false")) { if (flag) { if (flag2 && mat.HasProperty("_Color") && mat.GetColor("_Color") == new Color(1f, 1f, 1f, 1f)) { return PerformanceChecks.FormattedTextContent("PerformanceChecks.ShaderUsesWhiteColor", new object[] { "Mobile/" + shaderName }); } if (flag2 && shaderName.StartsWith("Particles/")) { return PerformanceChecks.FormattedTextContent("PerformanceChecks.ShaderHasMobileVariant", new object[] { "Mobile/" + shaderName }); } if (shaderName == "RenderFX/Skybox" && mat.HasProperty("_Tint") && mat.GetColor("_Tint") == new Color(0.5f, 0.5f, 0.5f, 0.5f)) { return PerformanceChecks.FormattedTextContent("PerformanceChecks.ShaderMobileSkybox", new object[] { "Mobile/Skybox" }); } } if (lOD >= 300 && flag2 && !shaderName.StartsWith("Mobile/")) { return PerformanceChecks.FormattedTextContent("PerformanceChecks.ShaderExpensive", new object[0]); } if (shaderName.Contains("VertexLit") && mat.HasProperty("_Emission")) { Color color = mat.GetColor("_Emission"); if (color.r >= 0.5f && color.g >= 0.5f && color.b >= 0.5f) { return PerformanceChecks.FormattedTextContent("PerformanceChecks.ShaderUseUnlit", new object[0]); } } if (mat.HasProperty("_BumpMap") && mat.GetTexture("_BumpMap") == null) { return PerformanceChecks.FormattedTextContent("PerformanceChecks.ShaderNoNormalMap", new object[0]); } } return null; }
public static void CheckTexture (string n, Material m, List<string> l) { Debug.Log( "Has property " + n + " " + m.HasProperty (n) ); Debug.Log( "Get texture " + n + " " + m.GetTexture(n) ); if (m.HasProperty (n) && m.GetTexture(n) != null) { l.Add (n); } }
//-------------------------------------- // INITIALIZE //-------------------------------------- //-------------------------------------- // PUBLIC METHODS //-------------------------------------- public static void ApplayColor(Material m, Color c) { if(m.HasProperty("_Color")) { m.color = c; } else { if(m.HasProperty ("_TintColor")) { m.SetColor ("_TintColor", c); } } }
public static IEnumerator CurveDissolve(Material mat, AnimationCurve dissolveCurve, float time, float curveStartPercentage, float speed) { float elapsedTime = curveStartPercentage; while (elapsedTime <= 1f && elapsedTime >= 0f) { if (mat.HasProperty(dissolveAmountID)) { mat.SetFloat(dissolveAmountID, Mathf.Clamp01(dissolveCurve.Evaluate(elapsedTime))); } elapsedTime += Time.deltaTime/time * speed; yield return null; } if (mat.HasProperty(dissolveAmountID)) { mat.SetFloat(dissolveAmountID, Mathf.Clamp01(dissolveCurve.Evaluate(Mathf.Clamp01(elapsedTime)))); } }
public static IEnumerator LinearDissolve(Material mat, float from, float to, float time) { float elapsedTime = 0f; while (elapsedTime < time) { if (mat.HasProperty(dissolveAmountID)) { mat.SetFloat(dissolveAmountID, Mathf.Lerp(from, to, elapsedTime/time)); } elapsedTime += Time.deltaTime; yield return null; } if (mat.HasProperty(dissolveAmountID)) { mat.SetFloat (dissolveAmountID, to); } }
/// <summary> /// Copy Shader properties from source to destination material. /// </summary> /// <param name="source"></param> /// <returns></returns> public static void CopyMaterialProperties(Material source, Material destination) { MaterialProperty[] source_prop = MaterialEditor.GetMaterialProperties(new Material[] { source }); for (int i = 0; i < source_prop.Length; i++) { int property_ID = Shader.PropertyToID(source_prop[i].name); if (destination.HasProperty(property_ID)) { //Debug.Log(source_prop[i].name + " Type:" + ShaderUtil.GetPropertyType(source.shader, i)); switch (ShaderUtil.GetPropertyType(source.shader, i)) { case ShaderUtil.ShaderPropertyType.Color: destination.SetColor(property_ID, source.GetColor(property_ID)); break; case ShaderUtil.ShaderPropertyType.Float: destination.SetFloat(property_ID, source.GetFloat(property_ID)); break; case ShaderUtil.ShaderPropertyType.Range: destination.SetFloat(property_ID, source.GetFloat(property_ID)); break; case ShaderUtil.ShaderPropertyType.TexEnv: destination.SetTexture(property_ID, source.GetTexture(property_ID)); break; case ShaderUtil.ShaderPropertyType.Vector: destination.SetVector(property_ID, source.GetVector(property_ID)); break; } } } }
public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader) { if (material.HasProperty("_Emission")) { material.SetColor("_EmissionColor", material.GetColor("_Emission")); } base.AssignNewShaderToMaterial(material, oldShader, newShader); if ((oldShader == null) || !oldShader.name.Contains("Legacy Shaders/")) { SetupMaterialWithBlendMode(material, (BlendMode) ((int) material.GetFloat("_Mode"))); } else { BlendMode opaque = BlendMode.Opaque; if (oldShader.name.Contains("/Transparent/Cutout/")) { opaque = BlendMode.Cutout; } else if (oldShader.name.Contains("/Transparent/")) { opaque = BlendMode.Fade; } material.SetFloat("_Mode", (float) opaque); Material[] mats = new Material[] { material }; this.DetermineWorkflow(MaterialEditor.GetMaterialProperties(mats)); MaterialChanged(material, this.m_WorkflowMode); } }
private Vector2[] GetPlaneHullVertices(Material mat) { if (mat == null) { return null; } if (!mat.HasProperty("_MainTex")) { return null; } Texture mainTexture = mat.mainTexture; if (mainTexture == null) { return null; } if ((s_TextureHulls == null) || s_TextureHullsDirty) { s_TextureHulls = new Dictionary<Texture, Vector2[]>(); s_TextureHullsDirty = false; } if (s_TextureHulls.ContainsKey(mainTexture)) { return s_TextureHulls[mainTexture]; } Vector2[] vectorArray2 = MeshUtility.ComputeTextureBoundingHull(mainTexture, 4); Vector2 vector = vectorArray2[1]; vectorArray2[1] = vectorArray2[3]; vectorArray2[3] = vector; s_TextureHulls.Add(mainTexture, vectorArray2); return vectorArray2; }
static public int HasProperty(IntPtr l) { try { int argc = LuaDLL.lua_gettop(l); if (matchType(l, argc, 2, typeof(int))) { UnityEngine.Material self = (UnityEngine.Material)checkSelf(l); System.Int32 a1; checkType(l, 2, out a1); var ret = self.HasProperty(a1); pushValue(l, true); pushValue(l, ret); return(2); } else if (matchType(l, argc, 2, typeof(string))) { UnityEngine.Material self = (UnityEngine.Material)checkSelf(l); System.String a1; checkType(l, 2, out a1); var ret = self.HasProperty(a1); pushValue(l, true); pushValue(l, ret); return(2); } pushValue(l, false); LuaDLL.lua_pushstring(l, "No matched override function to call"); return(2); } catch (Exception e) { return(error(l, e)); } }
static int HasProperty(IntPtr L) { try { int count = LuaDLL.lua_gettop(L); if (count == 2 && TypeChecker.CheckTypes <int>(L, 2)) { UnityEngine.Material obj = (UnityEngine.Material)ToLua.CheckObject <UnityEngine.Material>(L, 1); int arg0 = (int)LuaDLL.lua_tonumber(L, 2); bool o = obj.HasProperty(arg0); LuaDLL.lua_pushboolean(L, o); return(1); } else if (count == 2 && TypeChecker.CheckTypes <string>(L, 2)) { UnityEngine.Material obj = (UnityEngine.Material)ToLua.CheckObject <UnityEngine.Material>(L, 1); string arg0 = ToLua.ToString(L, 2); bool o = obj.HasProperty(arg0); LuaDLL.lua_pushboolean(L, o); return(1); } else { return(LuaDLL.luaL_throw(L, "invalid arguments to method: UnityEngine.Material.HasProperty")); } } catch (Exception e) { return(LuaDLL.toluaL_exception(L, e)); } }
public static string CheckMaterial(Material mat, BuildTarget buildTarget) { // ISSUE: object of a compiler-generated type is created // ISSUE: variable of a compiler-generated type PerformanceChecks.\u003CCheckMaterial\u003Ec__AnonStoreyBE materialCAnonStoreyBe = new PerformanceChecks.\u003CCheckMaterial\u003Ec__AnonStoreyBE(); if ((UnityEngine.Object) mat == (UnityEngine.Object) null || (UnityEngine.Object) mat.shader == (UnityEngine.Object) null) return (string) null; // ISSUE: reference to a compiler-generated field materialCAnonStoreyBe.shaderName = mat.shader.name; int lod = ShaderUtil.GetLOD(mat.shader); // ISSUE: reference to a compiler-generated method bool flag1 = Array.Exists<string>(PerformanceChecks.kShadersWithMobileVariants, new Predicate<string>(materialCAnonStoreyBe.\u003C\u003Em__22D)); bool flag2 = PerformanceChecks.IsMobileBuildTarget(buildTarget); if (!(mat.GetTag("PerformanceChecks", true).ToLower() == "false")) { if (flag1) { if (flag2 && mat.HasProperty("_Color") && mat.GetColor("_Color") == new Color(1f, 1f, 1f, 1f)) { // ISSUE: reference to a compiler-generated field return PerformanceChecks.FormattedTextContent("Shader is using white color which does nothing; Consider using {0} shader for performance.", (object) ("Mobile/" + materialCAnonStoreyBe.shaderName)); } // ISSUE: reference to a compiler-generated field if (flag2 && materialCAnonStoreyBe.shaderName.StartsWith("Particles/")) { // ISSUE: reference to a compiler-generated field return PerformanceChecks.FormattedTextContent("Consider using {0} shader on this platform for performance.", (object) ("Mobile/" + materialCAnonStoreyBe.shaderName)); } // ISSUE: reference to a compiler-generated field if (materialCAnonStoreyBe.shaderName == "RenderFX/Skybox" && mat.HasProperty("_Tint") && mat.GetColor("_Tint") == new Color(0.5f, 0.5f, 0.5f, 0.5f)) return PerformanceChecks.FormattedTextContent("Skybox shader is using gray color which does nothing; Consider using {0} shader for performance.", (object) "Mobile/Skybox"); } // ISSUE: reference to a compiler-generated field if (lod >= 300 && flag2 && !materialCAnonStoreyBe.shaderName.StartsWith("Mobile/")) return PerformanceChecks.FormattedTextContent("Shader might be expensive on this platform. Consider switching to a simpler shader; look under Mobile shaders."); // ISSUE: reference to a compiler-generated field if (materialCAnonStoreyBe.shaderName.Contains("VertexLit") && mat.HasProperty("_Emission")) { Color color = mat.GetColor("_Emission"); if ((double) color.r >= 0.5 && (double) color.g >= 0.5 && (double) color.b >= 0.5) return PerformanceChecks.FormattedTextContent("Looks like you're using VertexLit shader to simulate an unlit object (white emissive). Use one of Unlit shaders instead for performance."); } if (mat.HasProperty("_BumpMap") && (UnityEngine.Object) mat.GetTexture("_BumpMap") == (UnityEngine.Object) null) return PerformanceChecks.FormattedTextContent("Normal mapped shader without a normal map. Consider using a non-normal mapped shader for performance."); } return (string) null; }
public static void SetMaterialColor(Material mat, Color color) { string[] propertyNames = { "_Color", "_TintColor", "_EmisColor" }; if (mat != null) foreach (string name in propertyNames) if (mat.HasProperty(name)) mat.SetColor(name, color); }
// ------------------------------------------------------------------ public static bool IsMaterialColor(Material mat) { string[] propertyNames = { "_Color", "_TintColor", "_EmisColor" }; if (mat != null) foreach (string name in propertyNames) if (mat.HasProperty(name)) return true; return false; }
public static string GetMaterialColorName(Material mat) { string[] propertyNames = { "_Color", "_TintColor", "_EmisColor" }; if (mat != null) foreach (string name in propertyNames) if (mat.HasProperty(name)) return name; return null; }
public static Color GetMaterialColor(Material mat, Color defaultColor) { string[] propertyNames = { "_Color", "_TintColor", "_EmisColor" }; if (mat != null) foreach (string name in propertyNames) if (mat.HasProperty(name)) return mat.GetColor(name); return defaultColor; }
private void Start() { var mats = GetComponent<Renderer>().materials; if (MaterialID >= mats.Length) Debug.Log("ShaderColorGradient: Material ID more than shader materials count."); matInstance = mats[MaterialID]; if (!matInstance.HasProperty(ShaderProperty)) Debug.Log("ShaderColorGradient: Shader not have \"" + ShaderProperty + "\" property"); propertyID = Shader.PropertyToID(ShaderProperty); }
protected static bool TryGetTintColor(Material material, out Color color) { if (material.HasProperty("_TintColor")) { color = material.GetColor("_TintColor"); return true; } color = new Color(); return false; }
public MaterialProperty(Material material, string propertyName, float floatVal) { this.material = material; this.propertyName = propertyName; type = typeof (float); if (material.HasProperty(propertyName)) { value = material.GetFloat(propertyName); material.SetFloat(propertyName, floatVal); } }
/// <summary> /// Create a Masking Material Instance for the given ID /// </summary> /// <param name="baseMaterial"></param> /// <param name="stencilID"></param> /// <returns></returns> public static Material GetStencilMaterial(Material baseMaterial, int stencilID) { // Check if Material supports masking if (!baseMaterial.HasProperty(ShaderUtilities.ID_StencilID)) { Debug.LogWarning("Selected Shader does not support Stencil Masking. Please select the Distance Field or Mobile Distance Field Shader."); return baseMaterial; } Material stencilMaterial = null; // Check if baseMaterial already has a masking material associated with it. int index = m_materialList.FindIndex(item => item.baseMaterial == baseMaterial && item.stencilID == stencilID); if (index == -1) { //Create new Masking Material Instance for this Base Material stencilMaterial = new Material(baseMaterial); stencilMaterial.hideFlags = HideFlags.HideAndDontSave; stencilMaterial.name += " Masking ID:" + stencilID; stencilMaterial.shaderKeywords = baseMaterial.shaderKeywords; // Set Stencil Properties ShaderUtilities.GetShaderPropertyIDs(); stencilMaterial.SetFloat(ShaderUtilities.ID_StencilID, stencilID); stencilMaterial.SetFloat(ShaderUtilities.ID_StencilComp, 4); MaskingMaterial temp = new MaskingMaterial(); temp.baseMaterial = baseMaterial; temp.stencilMaterial = stencilMaterial; temp.stencilID = stencilID; temp.count = 1; m_materialList.Add(temp); //Debug.Log("Masking material for " + baseMaterial.name + " DOES NOT exists. Creating new " + maskingMaterial.name + " with ID " + maskingMaterial.GetInstanceID() + " which is used " + temp.count + " time(s)."); } else { stencilMaterial = m_materialList[index].stencilMaterial; m_materialList[index].count += 1; //Debug.Log("Masking material for " + baseMaterial.name + " already exists. Passing reference to " + maskingMaterial.name + " with ID " + maskingMaterial.GetInstanceID() + " which is used " + m_materialList[index].count + " time(s)."); } // Used for Debug ListMaterials(); return stencilMaterial; }
// Function to calculate padding required for Outline Width & Dilation for proper text alignment public static Vector4 GetFontExtent(Material material) { if (!material.HasProperty(ShaderUtilities.ID_GradientScale)) return Vector4.zero; // We are using an non SDF Shader. float scaleRatioA = material.GetFloat(ID_ScaleRatio_A); float faceDilate = material.GetFloat(ID_FaceDilate) * scaleRatioA; float outlineThickness = material.GetFloat(ID_OutlineWidth) * scaleRatioA; float extent = Mathf.Min(1, faceDilate + outlineThickness); extent *= material.GetFloat(ID_GradientScale); return new Vector4(extent, extent, extent, extent); }
static int HasProperty(IntPtr L) { int count = LuaDLL.lua_gettop(L); if (count == 2 && ToLua.CheckTypes(L, 1, typeof(UnityEngine.Material), typeof(int))) { UnityEngine.Material obj = (UnityEngine.Material)ToLua.ToObject(L, 1); int arg0 = (int)LuaDLL.lua_tonumber(L, 2); bool o; try { o = obj.HasProperty(arg0); } catch (Exception e) { return(LuaDLL.toluaL_exception(L, e)); } LuaDLL.lua_pushboolean(L, o); return(1); } else if (count == 2 && ToLua.CheckTypes(L, 1, typeof(UnityEngine.Material), typeof(string))) { UnityEngine.Material obj = (UnityEngine.Material)ToLua.ToObject(L, 1); string arg0 = ToLua.ToString(L, 2); bool o; try { o = obj.HasProperty(arg0); } catch (Exception e) { return(LuaDLL.toluaL_exception(L, e)); } LuaDLL.lua_pushboolean(L, o); return(1); } else { LuaDLL.luaL_error(L, "invalid arguments to method: UnityEngine.Material.HasProperty"); } return(0); }
void OnEnable() { if (mat == null) { mat = GetComponent<Renderer>().material; hasShader = mat.HasProperty("_FlashAmount"); } if (!hasShader) { Debug.Log("Assign ColorFlash Shader to " + transform.name); this.enabled = false; return; } count = 1; Flash(); }
/// <summary> /// Retrieves whether material is double-sided. /// </summary> /// <param name="uMaterial">Material to analyze.</param> /// <returns>True if material is double-sided, false otherwise.</returns> protected static bool IsDoubleSided(UnityEngine.Material uMaterial) { return(uMaterial.HasProperty(k_Cull) && uMaterial.GetInt(k_Cull) == (int)CullMode.Off); }
// Scale Ratios to ensure property ranges are optimum in Material Editor public static void UpdateShaderRatios(Material mat, bool isBold) { //Debug.Log("UpdateShaderRatios() called."); float ratio_A = 1; float ratio_B = 1; float ratio_C = 1; bool isRatioEnabled = !mat.shaderKeywords.Contains(Keyword_Ratios); // Compute Ratio A float scale = mat.GetFloat(ID_GradientScale); float faceDilate = mat.GetFloat(ID_FaceDilate); float outlineThickness = mat.GetFloat(ID_OutlineWidth); float outlineSoftness = mat.GetFloat(ID_OutlineSoftness); float weight = !isBold ? mat.GetFloat(ID_WeightNormal) * 2 / scale : mat.GetFloat(ID_WeightBold) * 2 / scale; float t = Mathf.Max(1, weight + faceDilate + outlineThickness + outlineSoftness); ratio_A = isRatioEnabled ? (scale - m_clamp) / (scale * t) : 1; mat.SetFloat(ID_ScaleRatio_A, ratio_A); // Compute Ratio B if (mat.HasProperty(ID_GlowOffset)) { float glowOffset = mat.GetFloat(ID_GlowOffset); float glowOuter = mat.GetFloat(ID_GlowOuter); float range = (weight + faceDilate) * (scale - m_clamp); t = Mathf.Max(1, glowOffset + glowOuter); ratio_B = isRatioEnabled ? Mathf.Max(0, scale - m_clamp - range) / (scale * t) : 1; mat.SetFloat(ID_ScaleRatio_B, ratio_B); } // Compute Ratio C if (mat.HasProperty(ID_UnderlayOffsetX)) { float underlayOffsetX = mat.GetFloat(ID_UnderlayOffsetX); float underlayOffsetY = mat.GetFloat(ID_UnderlayOffsetY); float underlayDilate = mat.GetFloat(ID_UnderlayDilate); float underlaySoftness = mat.GetFloat(ID_UnderlaySoftness); float range = (weight + faceDilate) * (scale - m_clamp); t = Mathf.Max(1, Mathf.Max(Mathf.Abs(underlayOffsetX), Mathf.Abs(underlayOffsetY)) + underlayDilate + underlaySoftness); ratio_C = isRatioEnabled ? Mathf.Max(0, scale - m_clamp - range) / (scale * t) : 1; mat.SetFloat(ID_ScaleRatio_C, ratio_C); } }
public VrmLib.TextureInfo GetOrCreateTexture(UnityEngine.Material material, UnityEngine.Texture srcTexture, VrmLib.Texture.ColorSpaceTypes colorSpace, VrmLib.Texture.TextureTypes textureType) { var texture = srcTexture as Texture2D; if (texture is null) { return(null); } if (!Textures.TryGetValue(texture, out VrmLib.TextureInfo info)) { UnityEngine.Material converter = null; if (textureType == VrmLib.Texture.TextureTypes.NormalMap) { converter = TextureConvertMaterial.GetNormalMapConvertUnityToGltf(); } else if (textureType == VrmLib.Texture.TextureTypes.MetallicRoughness) { float smoothness = 0.0f; if (material.HasProperty("_GlossMapScale")) { smoothness = material.GetFloat("_GlossMapScale"); } converter = TextureConvertMaterial.GetMetallicRoughnessUnityToGltf(smoothness); } else if (textureType == VrmLib.Texture.TextureTypes.Occlusion) { converter = TextureConvertMaterial.GetOcclusionUnityToGltf(); } var(bytes, mime) = GetImageEncodedBytes( texture, (colorSpace == VrmLib.Texture.ColorSpaceTypes.Linear) ? RenderTextureReadWrite.Linear : RenderTextureReadWrite.sRGB, converter ); if (converter != null) { UnityEngine.Object.DestroyImmediate(converter); } var sampler = new VrmLib.TextureSampler { MagFilter = texture.filterMode.ToVrmLibMagFilter(), MinFilter = texture.filterMode.ToVrmLibMinFilter(), WrapS = texture.wrapMode.ToVrmLib(), WrapT = texture.wrapMode.ToVrmLib(), }; var image = new VrmLib.Image(texture.name, mime, VrmLib.ImageUsage.None, new ArraySegment <byte>(bytes)); info = new VrmLib.TextureInfo(new VrmLib.ImageTexture(texture.name, sampler, image, colorSpace, textureType)); Textures.Add(texture, info); if (Model != null) { Model.Images.Add(image); Model.Textures.Add(info.Texture); } } return(info); }
static VrmLib.PBRMaterial ExportStandard(UnityEngine.Material src, GetOrCreateTextureDelegate map) { var material = new VrmLib.PBRMaterial(src.name) { }; switch (src.GetTag("RenderType", true)) { case "Transparent": material.AlphaMode = VrmLib.AlphaModeType.BLEND; break; case "TransparentCutout": material.AlphaMode = VrmLib.AlphaModeType.MASK; material.AlphaCutoff = src.GetFloat("_Cutoff"); break; default: material.AlphaMode = VrmLib.AlphaModeType.OPAQUE; break; } if (src.HasProperty("_Color")) { material.BaseColorFactor = src.color.linear.FromUnitySrgbToLinear(); } if (src.HasProperty("_MainTex")) { material.BaseColorTexture = map(src, src.GetTexture("_MainTex"), VrmLib.Texture.ColorSpaceTypes.Srgb, VrmLib.Texture.TextureTypes.Default); } if (src.HasProperty("_MetallicGlossMap")) { // float smoothness = 0.0f; // if (m.HasProperty("_GlossMapScale")) // { // smoothness = m.GetFloat("_GlossMapScale"); // } material.MetallicRoughnessTexture = map( src, src.GetTexture("_MetallicGlossMap"), VrmLib.Texture.ColorSpaceTypes.Linear, VrmLib.Texture.TextureTypes.MetallicRoughness)?.Texture; if (material.MetallicRoughnessTexture != null) { material.MetallicFactor = 1.0f; // Set 1.0f as hard-coded. See: https://github.com/vrm-c/UniVRM/issues/212. material.RoughnessFactor = 1.0f; } } if (material.MetallicRoughnessTexture == null) { if (src.HasProperty("_Metallic")) { material.MetallicFactor = src.GetFloat("_Metallic"); } if (src.HasProperty("_Glossiness")) { material.RoughnessFactor = 1.0f - src.GetFloat("_Glossiness"); } } if (src.HasProperty("_BumpMap")) { material.NormalTexture = map(src, src.GetTexture("_BumpMap"), VrmLib.Texture.ColorSpaceTypes.Linear, VrmLib.Texture.TextureTypes.NormalMap)?.Texture; if (src.HasProperty("_BumpScale")) { material.NormalTextureScale = src.GetFloat("_BumpScale"); } } if (src.HasProperty("_OcclusionMap")) { material.OcclusionTexture = map(src, src.GetTexture("_OcclusionMap"), VrmLib.Texture.ColorSpaceTypes.Linear, VrmLib.Texture.TextureTypes.Occlusion)?.Texture; if (src.HasProperty("_OcclusionStrength")) { material.OcclusionTextureStrength = src.GetFloat("_OcclusionStrength"); } } if (src.IsKeywordEnabled("_EMISSION")) { if (src.HasProperty("_EmissionColor")) { var color = src.GetColor("_EmissionColor"); if (color.maxColorComponent > 1) { color /= color.maxColorComponent; } material.EmissiveFactor = new System.Numerics.Vector3(color.r, color.g, color.b); } if (src.HasProperty("_EmissionMap")) { material.EmissiveTexture = map(src, src.GetTexture("_EmissionMap"), VrmLib.Texture.ColorSpaceTypes.Srgb, VrmLib.Texture.TextureTypes.Emissive)?.Texture; } } return(material); }
static bool IsPbrMetallicRoughness(UnityEngine.Material material) { return(material.HasProperty("_Metallic") && (material.HasProperty("_MetallicGlossMap") || material.HasProperty(k_Glossiness))); }
public void EqualSource() { Assert.AreEqual(material.Name, originMaterial.name); Assert.AreEqual(material.Shader, originMaterial.shader.name); for (int i = 0; i < material.PropertiesLength; i++) { Schema.ShaderProperty p = material.GetProperties(i); Assert.IsTrue(originMaterial.HasProperty(p.Names)); switch (p.Type) { case ShaderPropertyType.Float: case ShaderPropertyType.Range: { Assert.AreEqual(p.ValueType, ShaderPropertyValue.ShaderPropertyFloat); float originValue = originMaterial.GetFloat(p.Names); ShaderPropertyFloat f = p.GetValue <ShaderPropertyFloat>(new ShaderPropertyFloat()); Assert.AreEqual(f.Value, originValue); } break; case ShaderPropertyType.Color: { Assert.AreEqual(p.ValueType, ShaderPropertyValue.ShaderPropertyColor); UnityEngine.Color originValue = originMaterial.GetColor(p.Names); ShaderPropertyColor c = p.GetValue <ShaderPropertyColor>(new ShaderPropertyColor()); Assert.AreEqual(originValue.a, c.Color.A); Assert.AreEqual(originValue.g, c.Color.G); Assert.AreEqual(originValue.b, c.Color.B); Assert.AreEqual(originValue.r, c.Color.R); } break; case ShaderPropertyType.Vector: { Assert.AreEqual(p.ValueType, ShaderPropertyValue.ShaderPropertyVector); UnityEngine.Vector4 originValue = originMaterial.GetVector(p.Names); ShaderPropertyVector v = p.GetValue <ShaderPropertyVector>(new ShaderPropertyVector()); Assert.AreEqual(originValue.x, v.Vector.X); Assert.AreEqual(originValue.y, v.Vector.Y); Assert.AreEqual(originValue.z, v.Vector.Z); Assert.AreEqual(originValue.w, v.Vector.W); } break; case ShaderPropertyType.TexEnv: { Assert.AreEqual(p.ValueType, ShaderPropertyValue.ShaderPropertyTexture); UnityEngine.Texture texture = originMaterial.GetTexture(p.Names); Vector2 offset = originMaterial.GetTextureOffset(p.Names); Vector2 scale = originMaterial.GetTextureScale(p.Names); Assert.IsFalse(texture == null); ShaderPropertyTexture t = p.GetValue <ShaderPropertyTexture>(new ShaderPropertyTexture()); Assert.AreEqual(texture.name, t.Name); Assert.AreEqual(offset.x, t.Offset.X); Assert.AreEqual(offset.y, t.Offset.Y); Assert.AreEqual(scale.x, t.Scale.X); Assert.AreEqual(scale.y, t.Scale.Y); } break; } } }
static bool ExportPbrMetallicRoughness(UnityEngine.Material material, out PbrMetallicRoughness pbr, IGltfWritable gltf, ICodeLogger logger) { var success = true; pbr = new PbrMetallicRoughness { metallicFactor = 0, roughnessFactor = 1.0f }; if (material.HasProperty(k_BaseColor)) { pbr.baseColor = material.GetColor(k_BaseColor); } else if (material.HasProperty(k_Color)) { pbr.baseColor = material.GetColor(k_Color); } if (material.HasProperty(k_TintColor)) { //particles use _TintColor instead of _Color float white = 1; if (material.HasProperty(k_Color)) { var c = material.GetColor(k_Color); white = (c.r + c.g + c.b) / 3.0f; //multiply alpha by overall whiteness of TintColor } pbr.baseColor = material.GetColor(k_TintColor) * white; } if (material.HasProperty(k_MainTex) || material.HasProperty("_BaseMap")) { // TODO if additive particle, render black into alpha // TODO use private Material.GetFirstPropertyNameIdByAttribute here, supported from 2020.1+ var mainTexProperty = material.HasProperty(k_BaseMap) ? k_BaseMap : k_MainTex; var mainTex = material.GetTexture(mainTexProperty); if (mainTex) { if (mainTex is Texture2D) { pbr.baseColorTexture = ExportTextureInfo(mainTex, TextureMapType.Main, gltf); ExportTextureTransform(pbr.baseColorTexture, material, mainTexProperty, gltf); } else { logger?.Error(LogCode.TextureInvalidType, "main", material.name); success = false; } } } if (material.HasProperty(k_Metallic) && !material.IsKeywordEnabled("_METALLICGLOSSMAP")) { pbr.metallicFactor = material.GetFloat(k_Metallic); } if (material.HasProperty(k_Glossiness) || material.HasProperty(k_Smoothness)) { var smoothnessPropertyName = material.HasProperty(k_Smoothness) ? k_Smoothness : k_Glossiness; var metallicGlossMap = material.GetTexture(k_MetallicGlossMap); float smoothness = material.GetFloat(smoothnessPropertyName); // legacy workaround: the UnityGLTF shaders misuse k_Glossiness as roughness but don't have a keyword for it. if (material.shader.name.Equals("GLTF/PbrMetallicRoughness", StringComparison.Ordinal)) { smoothness = 1 - smoothness; } pbr.roughnessFactor = (metallicGlossMap != null && material.HasProperty(k_GlossMapScale)) ? material.GetFloat(k_GlossMapScale) : 1f - smoothness; } if (material.HasProperty(k_MetallicGlossMap)) { var mrTex = material.GetTexture(k_MetallicGlossMap); if (mrTex != null) { if (mrTex is Texture2D) { // pbr.metallicRoughnessTexture = ExportTextureInfo(mrTex, TextureMapType.MetallicGloss); // if (material.IsKeywordEnabled("_METALLICGLOSSMAP")) // pbr.metallicFactor = 1.0f; // ExportTextureTransform(pbr.MetallicRoughnessTexture, material, k_MetallicGlossMap); } else { logger?.Error(LogCode.TextureInvalidType, "metallic/gloss", material.name); success = false; } } } return(success); }
static bool IsPbrSpecularGlossiness(UnityEngine.Material material) { return(material.HasProperty("_SpecColor") && material.HasProperty("_SpecGlossMap")); }
/// <summary> /// Converts a Unity material to a glTF material. /// </summary> /// <param name="uMaterial">Source material</param> /// <param name="material">Resulting material</param> /// <param name="gltf">Associated IGltfWriter. Is used for adding images and textures.</param> /// <param name="logger">Logger used for reporting</param> /// <returns>True if no errors occured, false otherwise</returns> internal static bool ConvertMaterial(UnityEngine.Material uMaterial, out Material material, IGltfWritable gltf, ICodeLogger logger) { var success = true; material = new Material { name = uMaterial.name, pbrMetallicRoughness = new PbrMetallicRoughness { metallicFactor = 0, roughnessFactor = 1.0f } }; switch (uMaterial.GetTag("RenderType", false, "")) { case "TransparentCutout": if (uMaterial.HasProperty(k_Cutoff)) { material.alphaCutoff = uMaterial.GetFloat(k_Cutoff); } material.alphaModeEnum = Material.AlphaMode.MASK; break; case "Transparent": case "Fade": material.alphaModeEnum = Material.AlphaMode.BLEND; break; default: material.alphaModeEnum = Material.AlphaMode.OPAQUE; break; } material.doubleSided = uMaterial.HasProperty(k_Cull) && uMaterial.GetInt(k_Cull) == (int)CullMode.Off; if (uMaterial.IsKeywordEnabled("_EMISSION")) { if (uMaterial.HasProperty(k_EmissionColor)) { material.emissive = uMaterial.GetColor(k_EmissionColor); } if (uMaterial.HasProperty(k_EmissionMap)) { // var emissionTex = uMaterial.GetTexture(k_EmissionMap); // // if (emissionTex != null) { // if(emissionTex is Texture2D) { // material.emissiveTexture = ExportTextureInfo(emissionTex, TextureMapType.Emission); // ExportTextureTransform(material.EmissiveTexture, uMaterial, "_EmissionMap"); // } else { // logger?.Error(LogCode.TextureInvalidType, "emission", material.name ); // success = false; // } // } } } if ( uMaterial.HasProperty(k_BumpMap) && (uMaterial.IsKeywordEnabled(Materials.Constants.kwNormalMap) || uMaterial.IsKeywordEnabled(k_KeywordBumpMap)) ) { var normalTex = uMaterial.GetTexture(k_BumpMap); if (normalTex != null) { if (normalTex is Texture2D) { material.normalTexture = ExportNormalTextureInfo(normalTex, TextureMapType.Bump, uMaterial, gltf); ExportTextureTransform(material.normalTexture, uMaterial, k_BumpMap, gltf); } else { logger?.Error(LogCode.TextureInvalidType, "normal", uMaterial.name); success = false; } } } if (uMaterial.HasProperty(k_OcclusionMap)) { var occTex = uMaterial.GetTexture(k_OcclusionMap); if (occTex != null) { // if(occTex is Texture2D) { // material.occlusionTexture = ExportOcclusionTextureInfo(occTex, TextureMapType.Occlusion, uMaterial); // ExportTextureTransform(material.OcclusionTexture, uMaterial, "_OcclusionMap"); // } else { // logger?.Error(LogCode.TextureInvalidType, "occlusion", material.name ); // success = false; // } } } if (IsUnlit(uMaterial)) { ExportUnlit(material, uMaterial, gltf, logger); } else if (IsPbrMetallicRoughness(uMaterial)) { success &= ExportPbrMetallicRoughness(uMaterial, out material.pbrMetallicRoughness, gltf, logger); } else if (IsPbrSpecularGlossiness(uMaterial)) { // ExportPBRSpecularGlossiness(material, uMaterial); } else if (uMaterial.HasProperty(k_BaseMap)) { var mainTex = uMaterial.GetTexture(k_BaseMap); material.pbrMetallicRoughness = new PbrMetallicRoughness { baseColor = uMaterial.HasProperty(k_BaseColor) ? uMaterial.GetColor(k_BaseColor) : Color.white, baseColorTexture = mainTex == null ? null : ExportTextureInfo(mainTex, TextureMapType.Main, gltf) }; } else if (uMaterial.HasProperty(k_ColorTexture)) { var mainTex = uMaterial.GetTexture(k_ColorTexture); material.pbrMetallicRoughness = new PbrMetallicRoughness { baseColor = uMaterial.HasProperty(k_BaseColor) ? uMaterial.GetColor(k_BaseColor) : Color.white, baseColorTexture = mainTex == null ? null : ExportTextureInfo(mainTex, TextureMapType.Main, gltf) }; } else if (uMaterial.HasProperty(k_MainTex)) //else export main texture { var mainTex = uMaterial.GetTexture(k_MainTex); if (mainTex != null) { material.pbrMetallicRoughness = new PbrMetallicRoughness { metallicFactor = 0, roughnessFactor = 1.0f, baseColorTexture = ExportTextureInfo(mainTex, TextureMapType.Main, gltf) }; // ExportTextureTransform(material.pbrMetallicRoughness.baseColorTexture, uMaterial, "_MainTex"); } if (uMaterial.HasProperty(k_TintColor)) { //particles use _TintColor instead of _Color material.pbrMetallicRoughness = material.pbrMetallicRoughness ?? new PbrMetallicRoughness { metallicFactor = 0, roughnessFactor = 1.0f }; material.pbrMetallicRoughness.baseColor = uMaterial.GetColor(k_TintColor); } material.doubleSided = true; } return(success); }
/// <summary> /// Converts a Unity material to a glTF material. /// </summary> /// <param name="uMaterial">Source material</param> /// <param name="material">Resulting material</param> /// <param name="gltf">Associated IGltfWriter. Is used for adding images and textures.</param> /// <param name="logger">Logger used for reporting</param> /// <returns>True if no errors occured, false otherwise</returns> public override bool ConvertMaterial(UnityEngine.Material uMaterial, out Material material, IGltfWritable gltf, ICodeLogger logger) { var success = true; material = new Material { name = uMaterial.name, pbrMetallicRoughness = new PbrMetallicRoughness { metallicFactor = 0, roughnessFactor = 1.0f } }; SetAlphaModeAndCutoff(uMaterial, material); material.doubleSided = IsDoubleSided(uMaterial); if (uMaterial.IsKeywordEnabled(k_KeywordEmission)) { if (uMaterial.HasProperty(k_EmissionColor)) { var emissionColor = uMaterial.GetColor(k_EmissionColor); // Clamp emissionColor to 0..1 var maxFactor = math.max(emissionColor.r, math.max(emissionColor.g, emissionColor.b)); if (maxFactor > 1f) { emissionColor.r /= maxFactor; emissionColor.g /= maxFactor; emissionColor.b /= maxFactor; // TODO: use maxFactor as emissiveStrength (KHR_materials_emissive_strength) } material.emissive = emissionColor; } if (uMaterial.HasProperty(k_EmissionMap)) { var emissionTex = uMaterial.GetTexture(k_EmissionMap); if (emissionTex != null) { if (emissionTex is Texture2D) { material.emissiveTexture = ExportTextureInfo(emissionTex, gltf); if (material.emissiveTexture != null) { ExportTextureTransform(material.emissiveTexture, uMaterial, k_EmissionMap, gltf); } } else { logger?.Error(LogCode.TextureInvalidType, "emission", material.name); success = false; } } } } if ( uMaterial.HasProperty(k_BumpMap) && (uMaterial.IsKeywordEnabled(Materials.Constants.kwNormalMap) || uMaterial.IsKeywordEnabled(k_KeywordBumpMap)) ) { var normalTex = uMaterial.GetTexture(k_BumpMap); if (normalTex != null) { if (normalTex is Texture2D) { material.normalTexture = ExportNormalTextureInfo(normalTex, uMaterial, gltf); if (material.normalTexture != null) { ExportTextureTransform(material.normalTexture, uMaterial, k_BumpMap, gltf); } } else { logger?.Error(LogCode.TextureInvalidType, "normal", uMaterial.name); success = false; } } } var isPbrMetallicRoughness = IsPbrMetallicRoughness(uMaterial); var needsMetalRoughTexture = isPbrMetallicRoughness && ( HasMetallicGlossMap(uMaterial) || uMaterial.IsKeywordEnabled(k_KeywordSmoothnessTextureAlbedoChannelA) ); OrmImageExport ormImageExport = null; var mainTexProperty = k_MainTex; if (uMaterial.HasProperty(k_BaseMap)) { mainTexProperty = k_BaseMap; } else if (uMaterial.HasProperty(k_ColorTexture)) { mainTexProperty = k_ColorTexture; } if (needsMetalRoughTexture) { ormImageExport = new OrmImageExport(); } if (IsUnlit(uMaterial)) { ExportUnlit(material, uMaterial, mainTexProperty, gltf, logger); } else if (isPbrMetallicRoughness) { success &= ExportPbrMetallicRoughness( uMaterial, material, mainTexProperty, ormImageExport, gltf, logger ); } else if (uMaterial.HasProperty(mainTexProperty)) { var mainTex = uMaterial.GetTexture(mainTexProperty); material.pbrMetallicRoughness = new PbrMetallicRoughness { metallicFactor = 0, roughnessFactor = 1.0f, baseColor = uMaterial.HasProperty(k_BaseColor) ? uMaterial.GetColor(k_BaseColor) : Color.white }; if (mainTex != null) { material.pbrMetallicRoughness.baseColorTexture = ExportTextureInfo(mainTex, gltf); if (material.pbrMetallicRoughness.baseColorTexture != null) { ExportTextureTransform(material.pbrMetallicRoughness.baseColorTexture, uMaterial, mainTexProperty, gltf); } } if (uMaterial.HasProperty(k_TintColor)) { //particles use _TintColor instead of _Color material.pbrMetallicRoughness.baseColor = uMaterial.GetColor(k_TintColor); } } if (uMaterial.HasProperty(k_OcclusionMap)) { var occTex = uMaterial.GetTexture(k_OcclusionMap); if (occTex != null) { if (occTex is Texture2D occTex2d) { if (ormImageExport == null) { material.occlusionTexture = ExportOcclusionTextureInfo(occTex2d, uMaterial, gltf); } else { material.occlusionTexture = new OcclusionTextureInfo(); ormImageExport.SetOcclusionTexture(occTex2d); } if (material.occlusionTexture != null) { ExportTextureTransform( material.occlusionTexture, uMaterial, mainTexProperty, // Standard and Lit re-use main texture transform gltf ); } } else { logger?.Error(LogCode.TextureInvalidType, "occlusion", material.name); success = false; } } } if (ormImageExport != null && material.pbrMetallicRoughness != null) { if (AddImageExport(gltf, ormImageExport, out var ormTextureId)) { if (material.pbrMetallicRoughness.metallicRoughnessTexture != null) { material.pbrMetallicRoughness.metallicRoughnessTexture.index = ormTextureId; ExportTextureTransform(material.pbrMetallicRoughness.metallicRoughnessTexture, uMaterial, k_MetallicGlossMap, gltf); } if (ormImageExport.hasOcclusion) { material.occlusionTexture.index = ormTextureId; } } #if UNITY_IMAGECONVERSION else { logger?.Error(LogCode.ExportImageFailed); } #endif } if (material.occlusionTexture != null) { if (uMaterial.HasProperty(MaterialGenerator.occlusionStrengthPropId)) { material.occlusionTexture.strength = uMaterial.GetFloat(MaterialGenerator.occlusionStrengthPropId); } } return(success); }
private bool IsPBRMetallicRoughness(UnityEngine.Material material) { return(material.HasProperty("_Metallic") && material.HasProperty("_MetallicGlossMap")); }
private bool IsCommonConstant(UnityEngine.Material material) { return(material.HasProperty("_AmbientFactor") && material.HasProperty("_LightMap") && material.HasProperty("_LightFactor")); }
// Enable Masking in the Shader void EnableMasking() { if (m_fontMaterial == null) { m_fontMaterial = CreateMaterialInstance(m_sharedMaterial); m_uiRenderer.SetMaterial(m_fontMaterial, m_sharedMaterial.mainTexture); } m_sharedMaterial = m_fontMaterial; if (m_sharedMaterial.HasProperty(ShaderUtilities.ID_ClipRect)) { m_sharedMaterial.EnableKeyword(ShaderUtilities.Keyword_MASK_SOFT); m_sharedMaterial.DisableKeyword(ShaderUtilities.Keyword_MASK_HARD); m_sharedMaterial.DisableKeyword(ShaderUtilities.Keyword_MASK_TEX); UpdateMask(); // Update Masking Coordinates } m_isMaskingEnabled = true; //m_uiRenderer.SetMaterial(m_sharedMaterial, null); //m_padding = ShaderUtilities.GetPadding(m_sharedMaterial, m_enableExtraPadding, m_isUsingBold); //m_alignmentPadding = ShaderUtilities.GetFontExtent(m_sharedMaterial); /* Material mat = m_uiRenderer.GetMaterial(); if (mat.HasProperty(ShaderUtilities.ID_MaskCoord)) { mat.EnableKeyword("MASK_SOFT"); mat.DisableKeyword("MASK_HARD"); mat.DisableKeyword("MASK_OFF"); m_isMaskingEnabled = true; UpdateMask(); } */ }
private BabylonTexture DumpTextureFromMaterial(Material material, string name) { if (!material.HasProperty(name)) { return null; } var texture = material.GetTexture(name); return DumpTexture(texture, material, name); }
// Function to determine how much extra padding is required as a result of material properties like dilate, outline thickness, softness, glow, etc... public static float GetPadding(Material material, bool enableExtraPadding, bool isBold) { //Debug.Log("GetPadding() called."); if (isInitialized == false) GetShaderPropertyIDs(); // Return if Material is null if (material == null) return 0; int extraPadding = enableExtraPadding ? 4 : 0; if (!material.HasProperty(ID_GradientScale)) return extraPadding; // We are using an non SDF Shader. Vector4 padding = Vector4.zero; Vector4 maxPadding = Vector4.zero; float faceDilate = 0; float faceSoftness = 0; float outlineThickness = 0; float scaleRatio_A = 0; float scaleRatio_B = 0; float scaleRatio_C = 0; float glowOffset = 0; float glowOuter = 0; float uniformPadding = 0; // Iterate through each of the assigned materials to find the max values to set the padding. // Update Shader Ratios prior to computing padding UpdateShaderRatios(material, isBold); string[] shaderKeywords = material.shaderKeywords; if (material.HasProperty(ID_ScaleRatio_A)) scaleRatio_A = material.GetFloat(ID_ScaleRatio_A); if (material.HasProperty(ID_FaceDilate)) faceDilate = material.GetFloat(ID_FaceDilate) * scaleRatio_A; if (material.HasProperty(ID_OutlineSoftness)) faceSoftness = material.GetFloat(ID_OutlineSoftness) * scaleRatio_A; if (material.HasProperty(ID_OutlineWidth)) outlineThickness = material.GetFloat(ID_OutlineWidth) * scaleRatio_A; uniformPadding = outlineThickness + faceSoftness + faceDilate; // Glow padding contribution if (material.HasProperty(ID_GlowOffset) && shaderKeywords.Contains(Keyword_Glow)) // Generates GC { if (material.HasProperty(ID_ScaleRatio_B)) scaleRatio_B = material.GetFloat(ID_ScaleRatio_B); glowOffset = material.GetFloat(ID_GlowOffset) * scaleRatio_B; glowOuter = material.GetFloat(ID_GlowOuter) * scaleRatio_B; } uniformPadding = Mathf.Max(uniformPadding, faceDilate + glowOffset + glowOuter); // Underlay padding contribution if (material.HasProperty(ID_UnderlaySoftness) && shaderKeywords.Contains(Keyword_Underlay)) // Generates GC { if (material.HasProperty(ID_ScaleRatio_C)) scaleRatio_C = material.GetFloat(ID_ScaleRatio_C); float offsetX = material.GetFloat(ID_UnderlayOffsetX) * scaleRatio_C; float offsetY = material.GetFloat(ID_UnderlayOffsetY) * scaleRatio_C; float dilate = material.GetFloat(ID_UnderlayDilate) * scaleRatio_C; float softness = material.GetFloat(ID_UnderlaySoftness) * scaleRatio_C; padding.x = Mathf.Max(padding.x, faceDilate + dilate + softness - offsetX); padding.y = Mathf.Max(padding.y, faceDilate + dilate + softness - offsetY); padding.z = Mathf.Max(padding.z, faceDilate + dilate + softness + offsetX); padding.w = Mathf.Max(padding.w, faceDilate + dilate + softness + offsetY); } padding.x = Mathf.Max(padding.x, uniformPadding); padding.y = Mathf.Max(padding.y, uniformPadding); padding.z = Mathf.Max(padding.z, uniformPadding); padding.w = Mathf.Max(padding.w, uniformPadding); padding.x += extraPadding; padding.y += extraPadding; padding.z += extraPadding; padding.w += extraPadding; padding.x = Mathf.Min(padding.x, 1); padding.y = Mathf.Min(padding.y, 1); padding.z = Mathf.Min(padding.z, 1); padding.w = Mathf.Min(padding.w, 1); maxPadding.x = maxPadding.x < padding.x ? padding.x : maxPadding.x; maxPadding.y = maxPadding.y < padding.y ? padding.y : maxPadding.y; maxPadding.z = maxPadding.z < padding.z ? padding.z : maxPadding.z; maxPadding.w = maxPadding.w < padding.w ? padding.w : maxPadding.w; float gradientScale = material.GetFloat(ID_GradientScale); padding *= gradientScale; // Set UniformPadding to the maximum value of any of its components. uniformPadding = Mathf.Max(padding.x, padding.y); uniformPadding = Mathf.Max(padding.z, uniformPadding); uniformPadding = Mathf.Max(padding.w, uniformPadding); return uniformPadding + 0.5f; }
private BabylonMaterial DumpMaterial(Material material, Renderer renderer) { if (!materialsDictionary.ContainsKey(material.name)) { var bMat = new BabylonMaterial { name = material.name, id = Guid.NewGuid().ToString(), diffuse = new float[4], specular = new float[4] }; bMat.diffuse[0] = 1.0f; bMat.diffuse[1] = 1.0f; bMat.diffuse[2] = 1.0f; bMat.diffuse[3] = 1.0f; if (material.HasProperty("_Color")) { bMat.diffuse = material.color.ToFloat(); } if (material.HasProperty("_SpecColor")) { var specColor = material.GetColor("_SpecColor"); bMat.specular = specColor.ToFloat(); } if (material.HasProperty("_Shininess")) { var specShininess = material.GetFloat("_Shininess"); bMat.specularPower = specShininess * 128; } if (material.HasProperty("_Emission")) { var emissiveColor = material.GetColor("_Emission"); bMat.emissive = emissiveColor.ToFloat(); } if (material.mainTexture) { var mainTexturePath = AssetDatabase.GetAssetPath(material.mainTexture); bMat.diffuseTexture = new BabylonTexture { uScale = material.mainTextureScale.x, vScale = material.mainTextureScale.y, uOffset = material.mainTextureOffset.x, vOffset = material.mainTextureOffset.y }; var mainTexture2D = material.mainTexture as Texture2D; CopyTexture(mainTexturePath, mainTexture2D, bMat.diffuseTexture); var alphaCuttOff = 0f; if (material.HasProperty("_Cutoff")) { alphaCuttOff = material.GetFloat("_Cutoff"); } if ((mainTexture2D && mainTexture2D.alphaIsTransparency) || alphaCuttOff > 0) { bMat.diffuseTexture.hasAlpha = true; bMat.backFaceCulling = false; } bMat.diffuse[0] = 1.0f; bMat.diffuse[1] = 1.0f; bMat.diffuse[2] = 1.0f; bMat.diffuse[3] = 1.0f; } bMat.bumpTexture = DumpTextureFromMaterial(material, "_BumpMap"); bMat.emissiveTexture = DumpTextureFromMaterial(material, "_Illum"); bMat.ambientTexture = DumpTextureFromMaterial(material, "_LightMap"); bMat.reflectionTexture = DumpTextureFromMaterial(material, "_Cube"); //if (bMat.ambientTexture == null && renderer.lightmapIndex >= 0 && renderer.lightmapIndex != 255 && LightmapSettings.lightmaps.Length > renderer.lightmapIndex) //{ // var lightmap = LightmapSettings.lightmaps[renderer.lightmapIndex].lightmapFar; // bMat.ambientTexture = DumpTexture(lightmap); // bMat.ambientTexture.coordinatesIndex = 1; // bMat.ambientTexture.uScale = renderer.lightmapTilingOffset.x; // bMat.ambientTexture.vScale = renderer.lightmapTilingOffset.y; // bMat.ambientTexture.uOffset = renderer.lightmapTilingOffset.z; // bMat.ambientTexture.vOffset = renderer.lightmapTilingOffset.w; //} materialsDictionary.Add(bMat.name, bMat); return bMat; } return materialsDictionary[material.name]; }
private MaterialId ExportMaterial(UnityEngine.Material materialObj) { MaterialId id = GetMaterialId(_root, materialObj); if (id != null) { return(id); } var material = new GLTF.Schema.Material(); if (ExportNames) { material.Name = materialObj.name; } if (materialObj.HasProperty("_Cutoff")) { material.AlphaCutoff = materialObj.GetFloat("_Cutoff"); } switch (materialObj.GetTag("RenderType", false, "")) { case "TransparentCutout": material.AlphaMode = AlphaMode.MASK; break; case "Transparent": material.AlphaMode = AlphaMode.BLEND; break; default: material.AlphaMode = AlphaMode.OPAQUE; break; } material.DoubleSided = materialObj.HasProperty("_Cull") && materialObj.GetInt("_Cull") == (float)UnityEngine.Rendering.CullMode.Off; if (materialObj.HasProperty("_EmissionColor")) { material.EmissiveFactor = materialObj.GetColor("_EmissionColor").ToNumericsColor(); } if (materialObj.HasProperty("_EmissionMap")) { var emissionTex = materialObj.GetTexture("_EmissionMap"); if (emissionTex != null) { material.EmissiveTexture = ExportTextureInfo(emissionTex); ExportTextureTransform(material.EmissiveTexture, materialObj, "_EmissionMap"); } } if (materialObj.HasProperty("_BumpMap")) { var normalTex = materialObj.GetTexture("_BumpMap"); if (normalTex != null) { material.NormalTexture = ExportNormalTextureInfo(normalTex, materialObj); ExportTextureTransform(material.NormalTexture, materialObj, "_BumpMap"); } } if (materialObj.HasProperty("_OcclusionMap")) { var occTex = materialObj.GetTexture("_OcclusionMap"); if (occTex != null) { material.OcclusionTexture = ExportOcclusionTextureInfo(occTex, materialObj); ExportTextureTransform(material.OcclusionTexture, materialObj, "_OcclusionMap"); } } switch (materialObj.shader.name) { case "Standard": case "GLTF/GLTFStandard": material.PbrMetallicRoughness = ExportPBRMetallicRoughness(materialObj); break; case "GLTF/GLTFConstant": material.CommonConstant = ExportCommonConstant(materialObj); break; } _materials.Add(materialObj); id = new MaterialId { Id = _root.Materials.Count, Root = _root }; _root.Materials.Add(material); return(id); }
public static void SetEndCap (string name, EndCap capType, Material material, float offset, params Texture2D[] textures) { if (capDictionary == null) { capDictionary = new Dictionary<string, CapInfo>(); } if (name == null || name == "") { Debug.LogError ("VectorLine: must supply a name for SetEndCap"); return; } if (capDictionary.ContainsKey (name) && capType != EndCap.None) { Debug.LogError ("VectorLine: end cap \"" + name + "\" has already been set up"); return; } if (capType == EndCap.Both) { if (textures.Length < 2) { Debug.LogError ("VectorLine: must supply two textures when using SetEndCap with EndCap.Both"); return; } if (textures[0].width != textures[1].width || textures[0].height != textures[1].height) { Debug.LogError ("VectorLine: when using SetEndCap with EndCap.Both, both textures must have the same width and height"); return; } } if ( (capType == EndCap.Front || capType == EndCap.Back || capType == EndCap.Mirror) && textures.Length < 1) { Debug.LogError ("VectorLine: must supply a texture when using SetEndCap with EndCap.Front, EndCap.Back, or EndCap.Mirror"); return; } if (capType == EndCap.None) { if (!capDictionary.ContainsKey (name)) { return; } RemoveEndCap (name); return; } if (material == null) { Debug.LogError ("VectorLine: must supply a material when using SetEndCap with any EndCap type except EndCap.None"); return; } if (!material.HasProperty ("_MainTex")) { Debug.LogError ("VectorLine: the material supplied when using SetEndCap must contain a shader that has a \"_MainTex\" property"); return; } int width = textures[0].width; int height = textures[0].height; float ratio1 = 0.0f, ratio2 = 0.0f; Color[] cols1 = null, cols2 = null; if (capType == EndCap.Front) { cols1 = textures[0].GetPixels(); cols2 = new Color[width * height]; ratio1 = textures[0].width / (float)textures[0].height; } else if (capType == EndCap.Back) { cols1 = new Color[width * height]; cols2 = textures[0].GetPixels(); ratio2 = textures[0].width / (float)textures[0].height; } else if (capType == EndCap.Both) { cols1 = textures[0].GetPixels(); cols2 = textures[1].GetPixels(); ratio1 = textures[0].width / (float)textures[0].height; ratio2 = textures[1].width / (float)textures[1].height; } else if (capType == EndCap.Mirror) { cols1 = textures[0].GetPixels(); cols2 = new Color[width * height]; ratio1 = textures[0].width / (float)textures[0].height; ratio2 = ratio1; } var tex = new Texture2D(width, height*4, TextureFormat.ARGB32, false); tex.wrapMode = TextureWrapMode.Clamp; tex.filterMode = textures[0].filterMode; tex.SetPixels (0, 0, width, height, cols1); tex.SetPixels (0, height*3, width, height, cols2); // Add space to prevent top/bottom textures from potentially bleeding into each other when using bilinear filtering tex.SetPixels (0, height, width, height*2, new Color[width * (height*2)]); tex.Apply (false, true); var capMaterial = (Material)MonoBehaviour.Instantiate(material); capMaterial.name = material.name + " EndCap"; capMaterial.mainTexture = tex; capDictionary.Add (name, new CapInfo(capType, capMaterial, tex, ratio1, ratio2, offset)); }
static bool ExportPbrMetallicRoughness( UnityEngine.Material uMaterial, Material material, IGltfWritable gltf, ICodeLogger logger ) { var success = true; var pbr = new PbrMetallicRoughness { metallicFactor = 0, roughnessFactor = 1.0f }; MaskMapImageExport ormImageExport = null; if (uMaterial.IsKeywordEnabled(k_KeywordMaskMap) && uMaterial.HasProperty(k_MaskMap)) { var maskMap = uMaterial.GetTexture(k_MaskMap) as Texture2D; if (maskMap != null) { ormImageExport = new MaskMapImageExport(maskMap); if (AddImageExport(gltf, ormImageExport, out var ormTextureId)) { // TODO: smartly detect if metallic roughness channels are used and not create the // texture info if not. pbr.metallicRoughnessTexture = new TextureInfo { index = ormTextureId }; ExportTextureTransform(pbr.metallicRoughnessTexture, uMaterial, k_MaskMap, gltf); // TODO: smartly detect if occlusion channel is used and not create the // texture info if not. material.occlusionTexture = new OcclusionTextureInfo { index = ormTextureId }; if (uMaterial.HasProperty(k_AORemapMin)) { var occMin = uMaterial.GetFloat(k_AORemapMin); material.occlusionTexture.strength = math.clamp(1 - occMin, 0, 1); var occMax = uMaterial.GetFloat(k_AORemapMax); if (occMax < 1f) { // TODO: remap texture values logger?.Warning(LogCode.RemapUnsupported, "AO"); } } } } } if (uMaterial.HasProperty(k_BaseColor)) { pbr.baseColor = uMaterial.GetColor(k_BaseColor); } else if (uMaterial.HasProperty(k_Color)) { pbr.baseColor = uMaterial.GetColor(k_Color); } if (uMaterial.HasProperty(k_BaseColorMap)) { // TODO if additive particle, render black into alpha // TODO use private Material.GetFirstPropertyNameIdByAttribute here, supported from 2020.1+ var mainTex = uMaterial.GetTexture(k_BaseColorMap); if (mainTex) { if (mainTex is Texture2D) { pbr.baseColorTexture = ExportTextureInfo(mainTex, gltf); ExportTextureTransform(pbr.baseColorTexture, uMaterial, k_BaseColorMap, gltf); } else { logger?.Error(LogCode.TextureInvalidType, "main", uMaterial.name); success = false; } } } if (uMaterial.HasProperty(k_Metallic)) { pbr.metallicFactor = uMaterial.GetFloat(k_Metallic); } if (ormImageExport != null && uMaterial.HasProperty(k_SmoothnessRemapMax)) { pbr.roughnessFactor = uMaterial.GetFloat(k_SmoothnessRemapMax); if (uMaterial.HasProperty(k_SmoothnessRemapMin) && uMaterial.GetFloat(k_SmoothnessRemapMin) > 0) { logger?.Warning(LogCode.RemapUnsupported, "Smoothness"); } } else if (uMaterial.HasProperty(k_Smoothness)) { pbr.roughnessFactor = 1f - uMaterial.GetFloat(k_Smoothness); } material.pbrMetallicRoughness = pbr; return(success); }
// Function to check if Masking is enabled public static bool IsMaskingEnabled(Material material) { if (material == null || !material.HasProperty(ShaderUtilities.ID_ClipRect)) return false; if (material.shaderKeywords.Contains(ShaderUtilities.Keyword_MASK_SOFT) || material.shaderKeywords.Contains(ShaderUtilities.Keyword_MASK_HARD) || material.shaderKeywords.Contains(ShaderUtilities.Keyword_MASK_TEX)) return true; return false; }
/// <summary> /// Converts a Unity material to a glTF material. /// </summary> /// <param name="uMaterial">Source material</param> /// <param name="material">Resulting material</param> /// <param name="gltf">Associated IGltfWriter. Is used for adding images and textures.</param> /// <param name="logger">Logger used for reporting</param> /// <returns>True if no errors occured, false otherwise</returns> public override bool ConvertMaterial(UnityEngine.Material uMaterial, out Material material, IGltfWritable gltf, ICodeLogger logger) { var success = true; material = new Material { name = uMaterial.name, pbrMetallicRoughness = new PbrMetallicRoughness { metallicFactor = 0, roughnessFactor = 1.0f } }; SetAlphaModeAndCutoff(uMaterial, material); material.doubleSided = IsDoubleSided(uMaterial); // // Emission // if (uMaterial.HasProperty(k_EmissiveColor)) { var emissionColor = uMaterial.GetColor(k_EmissiveColor); // Clamp emissiveColor to 0..1 var maxFactor = math.max(emissionColor.r, math.max(emissionColor.g, emissionColor.b)); if (maxFactor > 1f) { emissionColor.r /= maxFactor; emissionColor.g /= maxFactor; emissionColor.b /= maxFactor; // TODO: use maxFactor as emissiveStrength (KHR_materials_emissive_strength) } material.emissive = emissionColor; } if (uMaterial.HasProperty(k_EmissionColorMap)) { var emissionTex = uMaterial.GetTexture(k_EmissionColorMap); if (emissionTex != null) { if (emissionTex is Texture2D) { material.emissiveTexture = ExportTextureInfo(emissionTex, gltf); ExportTextureTransform(material.emissiveTexture, uMaterial, k_EmissionColorMap, gltf); } else { logger?.Error(LogCode.TextureInvalidType, "emission", material.name); success = false; } } } // // Normal Map // if ( uMaterial.HasProperty(k_NormalMap) && uMaterial.IsKeywordEnabled(k_KeywordNormalMapTangentSpace) ) { var normalTex = uMaterial.GetTexture(k_NormalMap); if (normalTex != null) { if (normalTex is Texture2D) { material.normalTexture = ExportNormalTextureInfo(normalTex, uMaterial, gltf); ExportTextureTransform(material.normalTexture, uMaterial, k_NormalMap, gltf); } else { logger?.Error(LogCode.TextureInvalidType, "normal", uMaterial.name); success = false; } } } var mainTexProperty = uMaterial.HasProperty(k_BaseColorMap) ? k_BaseColorMap : k_MainTex; if (IsUnlit(uMaterial)) { ExportUnlit(material, uMaterial, mainTexProperty, gltf, logger); } else { success &= ExportPbrMetallicRoughness( uMaterial, material, gltf, logger ); } return(success); }
private static float GetMaterialFloat(Material material, string propertyID, out bool success) { success = false; if (!material.HasProperty(propertyID)) { return 0f; } success = true; return material.GetFloat(propertyID); }
static bool ExportPbrMetallicRoughness( UnityEngine.Material uMaterial, Material material, int mainTexProperty, OrmImageExport ormImageExport, IGltfWritable gltf, ICodeLogger logger ) { var success = true; var pbr = new PbrMetallicRoughness { metallicFactor = 0, roughnessFactor = 1.0f }; var hasAlphaSmoothness = uMaterial.IsKeywordEnabled(k_KeywordSmoothnessTextureAlbedoChannelA); if (uMaterial.HasProperty(k_BaseColor)) { pbr.baseColor = uMaterial.GetColor(k_BaseColor); } else if (uMaterial.HasProperty(k_Color)) { pbr.baseColor = uMaterial.GetColor(k_Color); } if (uMaterial.HasProperty(k_TintColor)) { //particles use _TintColor instead of _Color float white = 1; if (uMaterial.HasProperty(k_Color)) { var c = uMaterial.GetColor(k_Color); white = (c.r + c.g + c.b) / 3.0f; //multiply alpha by overall whiteness of TintColor } pbr.baseColor = uMaterial.GetColor(k_TintColor) * white; } if (uMaterial.HasProperty(mainTexProperty)) { // TODO if additive particle, render black into alpha // TODO use private Material.GetFirstPropertyNameIdByAttribute here, supported from 2020.1+ var mainTex = uMaterial.GetTexture(mainTexProperty); if (mainTex) { if (mainTex is Texture2D) { pbr.baseColorTexture = ExportTextureInfo( mainTex, gltf, // Force RGB for the baseColor, so that the alpha (which is smoothness) // is not used for alpha-opacity hasAlphaSmoothness ? ImageExportBase.Format.Jpg : ImageExportBase.Format.Unknown ); if (pbr.baseColorTexture != null) { ExportTextureTransform(pbr.baseColorTexture, uMaterial, mainTexProperty, gltf); } } else { logger?.Error(LogCode.TextureInvalidType, "main", uMaterial.name); success = false; } } } if (uMaterial.HasProperty(k_Metallic) && !HasMetallicGlossMap(uMaterial)) { pbr.metallicFactor = uMaterial.GetFloat(k_Metallic); } if (uMaterial.HasProperty(k_Glossiness) || uMaterial.HasProperty(k_Smoothness)) { var smoothnessPropId = uMaterial.HasProperty(k_Smoothness) ? k_Smoothness : k_Glossiness; var metallicGlossMap = uMaterial.HasProperty(k_MetallicGlossMap) ? uMaterial.GetTexture(k_MetallicGlossMap) : null; var smoothness = uMaterial.GetFloat(smoothnessPropId); pbr.roughnessFactor = (metallicGlossMap != null || hasAlphaSmoothness) && uMaterial.HasProperty(k_GlossMapScale) ? uMaterial.GetFloat(k_GlossMapScale) : 1f - smoothness; } if (uMaterial.HasProperty(k_MetallicGlossMap)) { var mrTex = uMaterial.GetTexture(k_MetallicGlossMap); if (mrTex != null) { if (mrTex is Texture2D mrTex2d) { pbr.metallicRoughnessTexture = pbr.metallicRoughnessTexture ?? new TextureInfo(); ormImageExport.SetMetalGlossTexture(mrTex2d); if (HasMetallicGlossMap(uMaterial)) { pbr.metallicFactor = 1.0f; } ExportTextureTransform(pbr.metallicRoughnessTexture, uMaterial, k_MetallicGlossMap, gltf); } else { logger?.Error(LogCode.TextureInvalidType, "metallic/gloss", uMaterial.name); success = false; } } } if (uMaterial.IsKeywordEnabled(k_KeywordSmoothnessTextureAlbedoChannelA)) { var smoothnessTex = uMaterial.GetTexture(mainTexProperty) as Texture2D; if (smoothnessTex != null) { pbr.metallicRoughnessTexture = pbr.metallicRoughnessTexture ?? new TextureInfo(); ormImageExport.SetSmoothnessTexture(smoothnessTex); ExportTextureTransform(pbr.metallicRoughnessTexture, uMaterial, mainTexProperty, gltf); } } material.pbrMetallicRoughness = pbr; return(success); }