/// <summary> /// Gets Unity Material atlas from Daggerfall texture archive. /// </summary> /// <param name="archive">Archive index to create atlas from.</param> /// <param name="alphaIndex">Index to receive transparent alpha.</param> /// <param name="padding">Number of pixels each sub-texture.</param> /// <param name="maxAtlasSize">Max size of atlas.</param> /// <param name="rectsOut">Array of rects, one for each record sub-texture and frame.</param> /// <param name="indicesOut">Array of record indices into rect array, accounting for animation frames.</param> /// <param name="border">Number of pixels internal border around each texture.</param> /// <param name="dilate">Blend texture into surrounding empty pixels.</param> /// <param name="shrinkUVs">Number of pixels to shrink UV rect.</param> /// <param name="copyToOppositeBorder">Copy texture edges to opposite border. Requires border, will overwrite dilate.</param> /// <param name="isBillboard">Set true when creating atlas material for simple billboards.</param> /// <returns>Material or null.</returns> public Material GetMaterialAtlas( int archive, int alphaIndex, int padding, int maxAtlasSize, out Rect[] rectsOut, out RecordIndex[] indicesOut, int border = 0, bool dilate = false, int shrinkUVs = 0, bool copyToOppositeBorder = false, bool isBillboard = false) { // Ready check if (!IsReady) { rectsOut = null; indicesOut = null; return(null); } int key = MakeTextureKey((short)archive, (byte)0, (byte)0, AtlasKeyGroup); if (materialDict.ContainsKey(key)) { CachedMaterial cm = GetMaterialFromCache(key); if (cm.filterMode == MainFilterMode) { // Properties are the same rectsOut = cm.atlasRects; indicesOut = cm.atlasIndices; return(cm.material); } else { // Properties don't match, remove material and reload materialDict.Remove(key); } } // Create material Material material; if (isBillboard) { material = CreateStandardMaterial(CustomBlendMode.Cutout); } else { material = CreateStandardMaterial(); } // Create settings GetTextureSettings settings = TextureReader.CreateTextureSettings(archive, 0, 0, alphaIndex, border, dilate); settings.createNormalMap = GenerateNormals; settings.autoEmission = true; settings.atlasShrinkUVs = shrinkUVs; settings.atlasPadding = padding; settings.atlasMaxSize = maxAtlasSize; settings.copyToOppositeBorder = copyToOppositeBorder; // Setup material material.name = string.Format("TEXTURE.{0:000} [Atlas]", archive); GetTextureResults results = textureReader.GetTexture2DAtlas(settings, AlphaTextureFormat); material.mainTexture = results.albedoMap; material.mainTexture.filterMode = MainFilterMode; // Setup normal map if (GenerateNormals && results.normalMap != null) { results.normalMap.filterMode = MainFilterMode; material.SetTexture(Uniforms.BumpMap, results.normalMap); material.EnableKeyword(KeyWords.NormalMap); } // Setup emission map if (results.isEmissive && results.emissionMap != null) { results.emissionMap.filterMode = MainFilterMode; material.SetTexture(Uniforms.EmissionMap, results.emissionMap); material.SetColor(Uniforms.EmissionColor, Color.white); material.EnableKeyword(KeyWords.Emission); } // TEMP: Bridging between legacy material out params and GetTextureResults for now Vector2[] sizesOut, scalesOut, offsetsOut; sizesOut = results.atlasSizes.ToArray(); scalesOut = results.atlasScales.ToArray(); offsetsOut = results.atlasOffsets.ToArray(); rectsOut = results.atlasRects.ToArray(); indicesOut = results.atlasIndices.ToArray(); // Setup cached material CachedMaterial newcm = new CachedMaterial(); newcm.key = key; newcm.keyGroup = AtlasKeyGroup; newcm.atlasRects = rectsOut; newcm.atlasIndices = indicesOut; newcm.material = material; newcm.filterMode = MainFilterMode; newcm.recordSizes = sizesOut; newcm.recordScales = scalesOut; newcm.recordOffsets = offsetsOut; newcm.atlasFrameCounts = results.atlasFrameCounts.ToArray(); materialDict.Add(key, newcm); return(material); }
/// <summary> /// Gets Unity Material atlas from Daggerfall texture archive. /// </summary> /// <param name="archive">Archive index to create atlas from.</param> /// <param name="alphaIndex">Index to receive transparent alpha.</param> /// <param name="rectsOut">Array of rects, one for each record sub-texture and frame.</param> /// <param name="padding">Number of pixels each sub-texture.</param> /// <param name="maxAtlasSize">Max size of atlas.</param> /// <param name="rectsOut">Array of rects, one for each record sub-texture and frame.</param> /// <param name="indicesOut">Array of record indices into rect array, accounting for animation frames.</param> /// <param name="border">Number of pixels internal border around each texture.</param> /// <param name="dilate">Blend texture into surrounding empty pixels.</param> /// <param name="shrinkUVs">Number of pixels to shrink UV rect.</param> /// <param name="copyToOppositeBorder">Copy texture edges to opposite border. Requires border, will overwrite dilate.</param> /// <param name="shader">Shader for material. If null, DefaultShaderName will be applied.</param> /// <returns>Material or null.</returns> public Material GetMaterialAtlas( int archive, int alphaIndex, int padding, int maxAtlasSize, out Rect[] rectsOut, out RecordIndex[] indicesOut, int border = 0, bool dilate = false, int shrinkUVs = 0, bool copyToOppositeBorder = false, Shader shader = null) { // Ready check if (!IsReady) { rectsOut = null; indicesOut = null; return(null); } int key = MakeTextureKey((short)archive, (byte)0, (byte)0, AtlasKeyGroup); if (materialDict.ContainsKey(key)) { CachedMaterial cm = materialDict[key]; if (cm.filterMode == MainFilterMode) { // Properties are the same rectsOut = cm.atlasRects; indicesOut = cm.indices; return(cm.material); } else { // Properties don't match, remove material and reload materialDict.Remove(key); } } if (shader == null) { shader = Shader.Find(DefaultShaderName); } Vector2[] sizesOut, scalesOut, offsetsOut; Material material = new Material(shader); material.name = string.Format("TEXTURE.{0:000} [Atlas]", archive); Texture2D texture = textureReader.GetTexture2DAtlas( archive, alphaIndex, padding, maxAtlasSize, out rectsOut, out indicesOut, out sizesOut, out scalesOut, out offsetsOut, border, dilate, shrinkUVs, copyToOppositeBorder); material.mainTexture = texture; material.mainTexture.filterMode = MainFilterMode; CachedMaterial newcm = new CachedMaterial(); newcm.key = key; newcm.keyGroup = AtlasKeyGroup; newcm.atlasRects = rectsOut; newcm.indices = indicesOut; newcm.material = material; newcm.filterMode = MainFilterMode; newcm.recordSizes = sizesOut; newcm.recordScales = scalesOut; newcm.recordOffsets = offsetsOut; materialDict.Add(key, newcm); return(material); }