/// <summary> /// Gets Unity Material from Daggerfall texture with more options. /// </summary> /// <param name="archive">Archive index.</param> /// <param name="record">Record index.</param> /// <param name="frame">Frame index.</param> /// <param name="rectOut">Receives UV rect for texture inside border.</param> /// <param name="borderSize">Number of pixels internal border around each texture.</param> /// <param name="dilate">Blend texture into surrounding empty pixels.</param> /// <param name="isBillboard">Set true when creating atlas material for simple billboards.</param> /// <returns>Material or null.</returns> public Material GetMaterial( int archive, int record, int frame, int alphaIndex, out Rect rectOut, int borderSize = 0, bool dilate = false, bool isBillboard = false) { // Ready check if (!IsReady) { rectOut = new Rect(); return(null); } // Try to retrieve from cache int key = MakeTextureKey((short)archive, (byte)record, (byte)frame); if (materialDict.ContainsKey(key)) { CachedMaterial cm = GetMaterialFromCache(key); rectOut = cm.singleRect; return(cm.material); } Material material; GetTextureResults results; // Try to import a material from mods, otherwise create a standard material // and import textures from Daggerfall files and loose files. if (!TextureReplacement.TextureExistsAmongLooseFiles(archive, record, frame) && TextureReplacement.TryImportMaterial(archive, record, frame, out material)) { results = TextureReplacement.MakeResults(material, archive, record); TextureReplacement.AssignFiltermode(material); } else { // Create new texture settings GetTextureSettings settings = TextureReader.CreateTextureSettings(archive, record, frame, alphaIndex, borderSize, dilate); settings.autoEmissionForWindows = true; settings.sharpen = Sharpen; if (GenerateNormals) { settings.createNormalMap = true; settings.normalStrength = NormalTextureStrength; } // Set emissive for self-illuminated textures if (textureReader.IsEmissive(archive, record)) { settings.createEmissionMap = true; settings.emissionIndex = -1; } // Get texture results = textureReader.GetTexture2D(settings, AlphaTextureFormat, TextureImport.LooseFiles); // Create material if (isBillboard) { material = CreateStandardMaterial(CustomBlendMode.Cutout); } else { material = CreateStandardMaterial(); } // Setup material material.name = FormatName(archive, record); material.mainTexture = results.albedoMap; material.mainTexture.filterMode = MainFilterMode; // Setup normal map bool importedNormals = TextureReplacement.TextureExistsAmongLooseFiles(settings.archive, settings.record, settings.frame, TextureMap.Normal); if ((GenerateNormals || importedNormals) && results.normalMap != null) { results.normalMap.filterMode = MainFilterMode; material.SetTexture(Uniforms.BumpMap, results.normalMap); material.EnableKeyword(KeyWords.NormalMap); } // Setup emission map if (results.isEmissive && !results.isWindow && results.emissionMap != null) { results.emissionMap.filterMode = MainFilterMode; material.SetTexture(Uniforms.EmissionMap, results.emissionMap); material.SetColor(Uniforms.EmissionColor, Color.white); material.EnableKeyword(KeyWords.Emission); } else if (results.isEmissive && results.isWindow && results.emissionMap != null) { results.emissionMap.filterMode = MainFilterMode; material.SetTexture(Uniforms.EmissionMap, results.emissionMap); material.SetColor(Uniforms.EmissionColor, DayWindowColor * DayWindowIntensity); material.EnableKeyword(KeyWords.Emission); } // Import additional custom components of material TextureReplacement.CustomizeMaterial(archive, record, frame, material); } // Setup cached material DFSize size = results.textureFile.GetSize(record); DFSize scale = results.textureFile.GetScale(record); DFPosition offset = results.textureFile.GetOffset(record); Vector2[] recordSizes = new Vector2[1] { new Vector2(size.Width, size.Height) }; Vector2[] recordScales = new Vector2[1] { new Vector2(scale.Width, scale.Height) }; Vector2[] recordOffsets = new Vector2[1] { new Vector2(offset.X, offset.Y) }; CachedMaterial newcm = new CachedMaterial() { key = key, keyGroup = 0, albedoMap = results.albedoMap, normalMap = results.normalMap, emissionMap = results.emissionMap, singleRect = rectOut = results.singleRect, material = material, filterMode = MainFilterMode, isWindow = results.isWindow, recordSizes = recordSizes, recordScales = recordScales, recordOffsets = recordOffsets, singleFrameCount = results.textureFile.GetFrameCount(record), framesPerSecond = archive == FireWallsArchive ? 5 : 0, // Slow down fire walls }; materialDict.Add(key, newcm); return(material); }
/// <summary> /// Gets Unity Material from Daggerfall texture with more options. /// </summary> /// <param name="archive">Archive index.</param> /// <param name="record">Record index.</param> /// <param name="frame">Frame index.</param> /// <param name="rectOut">Receives UV rect for texture inside border.</param> /// <param name="borderSize">Number of pixels internal border around each texture.</param> /// <param name="dilate">Blend texture into surrounding empty pixels.</param> /// <returns>Material or null.</returns> public Material GetMaterial( int archive, int record, int frame, int alphaIndex, out Rect rectOut, int borderSize = 0, bool dilate = false) { // Ready check if (!IsReady) { rectOut = new Rect(); return(null); } // Try to retrieve from cache int key = MakeTextureKey((short)archive, (byte)record, (byte)frame); if (materialDict.ContainsKey(key)) { CachedMaterial cm = materialDict[key]; rectOut = cm.singleRect; return(cm.material); } // Create new texture settings GetTextureSettings settings = TextureReader.CreateTextureSettings(archive, record, frame, alphaIndex, borderSize, dilate); settings.autoEmissionForWindows = true; settings.sharpen = Sharpen; if (GenerateNormals) { settings.createNormalMap = true; settings.normalStrength = NormalTextureStrength; } // Set emissive for self-illuminated textures if (textureReader.IsEmissive(archive, record)) { settings.createEmissionMap = true; settings.emissionIndex = -1; } // Get texture GetTextureResults results = textureReader.GetTexture2D(settings, AlphaTextureFormat, NonAlphaTextureFormat); rectOut = results.singleRect; // Setup material Material material = CreateStandardMaterial(); material.name = FormatName(archive, record); material.mainTexture = results.albedoMap; material.mainTexture.filterMode = MainFilterMode; // Setup normal map if (GenerateNormals && results.normalMap != null) { results.normalMap.filterMode = MainFilterMode; material.SetTexture("_BumpMap", results.normalMap); material.EnableKeyword("_NORMALMAP"); } // Setup emission map if (results.isEmissive && !results.isWindow && results.emissionMap != null) { results.emissionMap.filterMode = MainFilterMode; material.SetTexture("_EmissionMap", results.emissionMap); material.SetColor("_EmissionColor", Color.white); material.EnableKeyword("_EMISSION"); } else if (results.isEmissive && results.isWindow && results.emissionMap != null) { results.emissionMap.filterMode = MainFilterMode; material.SetTexture("_EmissionMap", results.emissionMap); material.SetColor("_EmissionColor", DayWindowColor * DayWindowIntensity); material.EnableKeyword("_EMISSION"); } // Setup cached material DFSize size = results.textureFile.GetSize(record); DFSize scale = results.textureFile.GetScale(record); DFPosition offset = results.textureFile.GetOffset(record); Vector2[] recordSizes = new Vector2[1] { new Vector2(size.Width, size.Height) }; Vector2[] recordScales = new Vector2[1] { new Vector2(scale.Width, scale.Height) }; Vector2[] recordOffsets = new Vector2[1] { new Vector2(offset.X, offset.Y) }; CachedMaterial newcm = new CachedMaterial() { key = key, keyGroup = 0, albedoMap = results.albedoMap, normalMap = results.normalMap, emissionMap = results.emissionMap, singleRect = rectOut, material = material, filterMode = MainFilterMode, isWindow = results.isWindow, recordSizes = recordSizes, recordScales = recordScales, recordOffsets = recordOffsets, singleFrameCount = results.textureFile.GetFrameCount(record), }; materialDict.Add(key, newcm); return(material); }