/// <summary> /// Gets terrain albedo texture array containing each terrain tile in a seperate array slice. /// </summary> /// <param name="archive">Archive index.</param> /// <param name="stayReadable">Texture should stay readable.</param> /// <param name="nonAlphaFormat">Non-alpha TextureFormat.</param> /// <returns>Texture2DArray or null</returns> public Texture2DArray GetTerrainAlbedoTextureArray( int archive, bool stayReadable = false, SupportedNonAlphaTextureFormats nonAlphaFormat = SupportedNonAlphaTextureFormats.RGB24) { // Load texture file and check count matches terrain tiles TextureFile textureFile = new TextureFile(Path.Combine(Arena2Path, TextureFile.IndexToFileName(archive)), FileUsage.UseMemory, true); int numSlices = 0; if (textureFile.RecordCount == 56) { numSlices = textureFile.RecordCount; } else { return(null); } Texture2DArray textureArray; if (TextureReplacement.CustomTextureExist(archive, 0, 0)) { GetTextureResults results = new GetTextureResults(); TextureReplacement.LoadCustomTextureResults(archive, 0, 0, ref results, ref DaggerfallUnity.Instance.MaterialReader.GenerateNormals); textureArray = new Texture2DArray(results.albedoMap.width, results.albedoMap.height, numSlices, ParseTextureFormat(nonAlphaFormat), MipMaps); } else { textureArray = new Texture2DArray(textureFile.GetWidth(0), textureFile.GetWidth(1), numSlices, ParseTextureFormat(nonAlphaFormat), MipMaps); } // Rollout tiles into texture array for (int record = 0; record < textureFile.RecordCount; record++) { // Create base image with gutter DFSize sz; Color32[] albedo = textureFile.GetColor32(record, 0, -1, 0, out sz); // Import custom texture(s) GetTextureResults resultsTile = new GetTextureResults(); if (TextureReplacement.CustomTextureExist(archive, record, 0)) { TextureReplacement.LoadCustomTextureResults(archive, record, 0, ref resultsTile, ref DaggerfallUnity.Instance.MaterialReader.GenerateNormals); albedo = resultsTile.albedoMap.GetPixels32(); } // Insert into texture array textureArray.SetPixels32(albedo, record, 0); } textureArray.Apply(true, !stayReadable); // Change settings for these textures textureArray.wrapMode = TextureWrapMode.Clamp; textureArray.anisoLevel = 8; return(textureArray); }
/// <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 = 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); // Import custom textures TextureReplacement.LoadCustomTextureResults(archive, record, frame, ref results, ref GenerateNormals); rectOut = results.singleRect; // Create material Material 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 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"); } // 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, material = material, filterMode = MainFilterMode, isWindow = results.isWindow, recordSizes = recordSizes, recordScales = recordScales, recordOffsets = recordOffsets, singleFrameCount = results.textureFile.GetFrameCount(record), }; materialDict.Add(key, newcm); return(material); }