public override Dictionary <string, string> OutputResources(PSB psb, FreeMountContext context, string name, string dirPath, PsbExtractOption extractOption = PsbExtractOption.Original) { //Extra Extract if (extractOption == PsbExtractOption.Extract) { if (psb.Type == PsbType.Tachie) { var bitmaps = TextureCombiner.CombineTachie(psb); foreach (var kv in bitmaps) { kv.Value.Save(Path.Combine(dirPath, $"{kv.Key}{context.ImageFormat.DefaultExtension()}"), context.ImageFormat.ToImageFormat()); } } } return(base.OutputResources(psb, context, name, dirPath, extractOption)); }
public void CombineMaterial() { for (var i = 0; i < cellItemGroups.Count; i++) { var interalCombineSetting = cellItemGroups[i].groupCombineSetting; var combineSetting = interalCombineSetting.maxAtlasWidth != 0 ? interalCombineSetting : this.combineSetting; var combineData = new TextureCombinePipelineData(); combineData.CombinedMaterialInfoPath = combineAssetFolder + "/Cell" + CurrentCellID + "_Group" + i + ".asset"; combineData.DoMultiMaterial = combineSetting.DoMultiMaterial; TextureCombiner.CombineMaterial(cellItemGroups[i].groupGameObjects, combineSetting, combineData); //创建 TextureCombineResult //Texuture //Material } }
/// <summary> /// Save (most user friendly) images /// </summary> /// <param name="inputPath"></param> /// <param name="format"></param> public static void ExtractImageFiles(string inputPath, PsbImageFormat format = PsbImageFormat.png) { if (!File.Exists(inputPath)) { return; } var name = Path.GetFileNameWithoutExtension(inputPath); var dirPath = Path.Combine(Path.GetDirectoryName(inputPath), name); if (File.Exists(dirPath)) { name += "-resources"; dirPath += "-resources"; } if (!Directory.Exists(dirPath)) //ensure there is no file with same name! { Directory.CreateDirectory(dirPath); } var texExt = format == PsbImageFormat.bmp ? ".bmp" : ".png"; var texFormat = format.ToImageFormat(); var psb = new PSB(inputPath); if (psb.Type == PsbType.Tachie) { var bitmaps = TextureCombiner.CombineTachie(psb); foreach (var kv in bitmaps) { kv.Value.Save(Path.Combine(dirPath, $"{kv.Key}{texExt}"), texFormat); } return; } var texs = PsbResHelper.UnlinkImages(psb); foreach (var tex in texs) { tex.Save(Path.Combine(dirPath, tex.Tag + texExt), texFormat); } }
/// <summary> /// Creates the atlases. /// </summary> /// <returns> /// The atlases. /// </returns> public AtlasesAndRects[] CreateAtlases() { AtlasesAndRects[] mAndAs = null; try { //mAndAs = _CreateAtlases(progressInfo, saveAtlasesAsAssets, editorMethods); CreateAtlasesCoroutineResult result = new CreateAtlasesCoroutineResult(); TextureCombiner.RunCorutineWithoutPause(CreateAtlasesCoroutine(), 0); if (result.success && textureBakeResults != null) { mAndAs = this.OnCombinedTexturesCoroutineAtlasesAndRects; } } catch (Exception e) { Debug.LogError(e); } return(mAndAs); }
void Start() { textureCombiner = new TextureCombiner(); }
public override void Convert(Material srcMaterial, Material dstMaterial) { dstMaterial.hideFlags = HideFlags.DontUnloadUnusedAsset; base.Convert(srcMaterial, dstMaterial); // ---------- Mask Map ---------- // Metallic bool hasMetallic = false; Texture metallicMap = TextureCombiner.TextureFromColor(Color.black); if ((srcMaterial.shader.name == Standard) || (srcMaterial.shader.name == Standard_Rough)) { hasMetallic = srcMaterial.GetTexture("_MetallicGlossMap") != null; if (hasMetallic) { metallicMap = TextureCombiner.GetTextureSafe(srcMaterial, "_MetallicGlossMap", Color.white); } else { metallicMap = TextureCombiner.TextureFromColor(Color.white); } // Convert _Metallic value from Gamma to Linear, or set to 1 if a map is used float metallicValue = Mathf.Pow(srcMaterial.GetFloat("_Metallic"), 2.2f); dstMaterial.SetFloat("_Metallic", hasMetallic? 1f : metallicValue); } // Occlusion bool hasOcclusion = srcMaterial.GetTexture("_OcclusionMap") != null; Texture occlusionMap = Texture2D.whiteTexture; if (hasOcclusion) { occlusionMap = TextureCombiner.GetTextureSafe(srcMaterial, "_OcclusionMap", Color.white); } dstMaterial.SetFloat("_AORemapMin", 1f - srcMaterial.GetFloat("_OcclusionStrength")); // Detail Mask bool hasDetailMask = srcMaterial.GetTexture("_DetailMask") != null; Texture detailMaskMap = Texture2D.whiteTexture; if (hasDetailMask) { detailMaskMap = TextureCombiner.GetTextureSafe(srcMaterial, "_DetailMask", Color.white); } // Smoothness bool hasSmoothness = false; Texture2D smoothnessMap = TextureCombiner.TextureFromColor(Color.white); dstMaterial.SetFloat("_SmoothnessRemapMax", srcMaterial.GetFloat("_Glossiness")); if (srcMaterial.shader.name == Standard_Rough) { hasSmoothness = srcMaterial.GetTexture("_SpecGlossMap") != null; if (hasSmoothness) { smoothnessMap = (Texture2D)TextureCombiner.GetTextureSafe(srcMaterial, "_SpecGlossMap", Color.grey); } } else { string smoothnessTextureChannel = "_MainTex"; if (srcMaterial.GetFloat("_SmoothnessTextureChannel") == 0) { if (srcMaterial.shader.name == Standard) { smoothnessTextureChannel = "_MetallicGlossMap"; } if (srcMaterial.shader.name == Standard_Spec) { smoothnessTextureChannel = "_SpecGlossMap"; } } smoothnessMap = (Texture2D)srcMaterial.GetTexture(smoothnessTextureChannel); if (smoothnessMap != null) { hasSmoothness = true; dstMaterial.SetFloat("_SmoothnessRemapMax", srcMaterial.GetFloat("_GlossMapScale")); if (!TextureCombiner.TextureHasAlpha(smoothnessMap)) { smoothnessMap = TextureCombiner.TextureFromColor(Color.white); } } else { smoothnessMap = TextureCombiner.TextureFromColor(Color.white); } } // Build the mask map if (hasMetallic || hasOcclusion || hasDetailMask || hasSmoothness) { Texture2D maskMap; TextureCombiner maskMapCombiner = new TextureCombiner( metallicMap, 0, // R: Metallic from red occlusionMap, 1, // G: Occlusion from green detailMaskMap, 3, // B: Detail Mask from alpha smoothnessMap, (srcMaterial.shader.name == Standard_Rough) ? -4 : 3 // A: Smoothness Texture from inverse greyscale for roughness setup, or alpha ); string maskMapPath = AssetDatabase.GetAssetPath(srcMaterial); maskMapPath = maskMapPath.Remove(maskMapPath.Length - 4) + "_MaskMap.png"; maskMap = maskMapCombiner.Combine(maskMapPath); dstMaterial.SetTexture("_MaskMap", maskMap); } // Specular Setup Specific if (srcMaterial.shader.name == Standard_Spec) { // if there is a specular map, change the specular color to white if (srcMaterial.GetTexture("_SpecGlossMap") != null) { dstMaterial.SetColor("_SpecularColor", Color.white); } } // ---------- Height Map ---------- bool hasHeightMap = srcMaterial.GetTexture("_ParallaxMap") != null; if (hasHeightMap) // Enable Parallax Occlusion Mapping { dstMaterial.SetFloat("_DisplacementMode", 2); dstMaterial.SetFloat("_HeightPoMAmplitude", srcMaterial.GetFloat("_Parallax") * 2f); } // ---------- Detail Map ---------- bool hasDetailAlbedo = srcMaterial.GetTexture("_DetailAlbedoMap") != null; bool hasDetailNormal = srcMaterial.GetTexture("_DetailNormalMap") != null; if (hasDetailAlbedo || hasDetailNormal) { Texture2D detailMap; TextureCombiner detailCombiner = new TextureCombiner( TextureCombiner.GetTextureSafe(srcMaterial, "_DetailAlbedoMap", Color.grey), 4, // Albedo (overlay) TextureCombiner.GetTextureSafe(srcMaterial, "_DetailNormalMap", Color.grey), 1, // Normal Y TextureCombiner.midGrey, 1, // Smoothness TextureCombiner.GetTextureSafe(srcMaterial, "_DetailNormalMap", Color.grey), 0 // Normal X ); string detailMapPath = AssetDatabase.GetAssetPath(srcMaterial); detailMapPath = detailMapPath.Remove(detailMapPath.Length - 4) + "_DetailMap.png"; detailMap = detailCombiner.Combine(detailMapPath); dstMaterial.SetTexture("_DetailMap", detailMap); } // Blend Mode int previousBlendMode = srcMaterial.GetInt("_Mode"); switch (previousBlendMode) { case 0: // Opaque dstMaterial.SetFloat("_SurfaceType", 0); dstMaterial.SetFloat("_BlendMode", 0); dstMaterial.SetFloat("_AlphaCutoffEnable", 0); dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 1); break; case 1: // Cutout dstMaterial.SetFloat("_SurfaceType", 0); dstMaterial.SetFloat("_BlendMode", 0); dstMaterial.SetFloat("_AlphaCutoffEnable", 1); dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 1); break; case 2: // Fade -> Alpha + Disable preserve specular dstMaterial.SetFloat("_SurfaceType", 1); dstMaterial.SetFloat("_BlendMode", 0); dstMaterial.SetFloat("_AlphaCutoffEnable", 0); dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 0); break; case 3: // Transparent -> Alpha dstMaterial.SetFloat("_SurfaceType", 1); dstMaterial.SetFloat("_BlendMode", 0); dstMaterial.SetFloat("_AlphaCutoffEnable", 0); dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 1); break; } Color hdrEmission = srcMaterial.GetColor("_EmissionColor"); // Get the _EMISSION keyword of the Standard shader if (!srcMaterial.IsKeywordEnabled("_EMISSION")) { hdrEmission = Color.black; } // Emission toggle of Particle Standard Surface if (srcMaterial.HasProperty("_EmissionEnabled")) { if (srcMaterial.GetFloat("_EmissionEnabled") == 0) { hdrEmission = Color.black; } } dstMaterial.SetColor("_EmissiveColor", hdrEmission); HDEditorUtils.ResetMaterialKeywords(dstMaterial); }
private static void CreateWizard() { TextureCombiner window = (TextureCombiner)GetWindow(typeof(TextureCombiner)); window.Show(); }
public IEnumerator CreateAtlasesCoroutine() { this.OnCombinedTexturesCoroutineAtlasesAndRects = null; MBValidationLevel vl = MBValidationLevel.quick; if (!DoCombinedValidate(this, MB_ObjsToCombineTypes.dontCare, vl)) { yield break; } if (_doMultiMaterial && !_ValidateResultMaterials()) { yield break; } else if (!_doMultiMaterial) { if (_resultMaterial == null) { Debug.LogError("Combined Material is null please create and assign a result material."); yield break; } Shader targShader = _resultMaterial.shader; for (int i = 0; i < objsToMesh.Count; i++) { Material[] ms = MeshBakerUtility.GetGOMaterials(objsToMesh[i]); for (int j = 0; j < ms.Length; j++) { Material m = ms[j]; if (m != null && m.shader != targShader) { Debug.LogWarning("Game object " + objsToMesh[i] + " does not use shader " + targShader + " it may not have the required textures. If not small solid color textures will be generated."); } } } } for (int i = 0; i < objsToMesh.Count; i++) { Material[] ms = MeshBakerUtility.GetGOMaterials(objsToMesh[i]); for (int j = 0; j < ms.Length; j++) { Material m = ms[j]; if (m == null) { Debug.LogError("Game object " + objsToMesh[i] + " has a null material. Can't build atlases"); yield break; } } } TextureCombiner combiner = new TextureCombiner(); combiner.LOG_LEVEL = LOG_LEVEL; combiner.atlasPadding = _atlasPadding; combiner.maxAtlasSize = _maxAtlasSize; combiner.customShaderPropNames = _customShaderProperties; combiner.fixOutOfBoundsUVs = _fixOutOfBoundsUVs; combiner.maxTilingBakeSize = _maxTilingBakeSize; //initialize structure to store results int numResults = 1; if (_doMultiMaterial) { numResults = resultMaterials.Length; } OnCombinedTexturesCoroutineAtlasesAndRects = new AtlasesAndRects[numResults]; for (int i = 0; i < OnCombinedTexturesCoroutineAtlasesAndRects.Length; i++) { OnCombinedTexturesCoroutineAtlasesAndRects[i] = new AtlasesAndRects(); } //Do the material combining. for (int i = 0; i < OnCombinedTexturesCoroutineAtlasesAndRects.Length; i++) { Material resMatToPass = null; List <Material> sourceMats = null; if (_doMultiMaterial) { sourceMats = resultMaterials[i].sourceMaterials; resMatToPass = resultMaterials[i].combinedMaterial; } else { resMatToPass = _resultMaterial; } Debug.Log(string.Format("Creating atlases for result material {0} using shader {1}", resMatToPass, resMatToPass.shader)); TextureCombiner.CombineTexturesIntoAtlasesResult result2 = new TextureCombiner.CombineTexturesIntoAtlasesResult(); yield return(combiner.CombineTexturesIntoAtlases(OnCombinedTexturesCoroutineAtlasesAndRects[i], resMatToPass, objsToMesh, sourceMats, result2)); if (!result2.success) { yield break; } } //Save the results textureBakeResults.doMultiMaterial = _doMultiMaterial; textureBakeResults.resultMaterial = _resultMaterial; textureBakeResults.resultMaterials = resultMaterials; textureBakeResults.fixOutOfBoundsUVs = combiner.fixOutOfBoundsUVs; unpackMat2RectMap(textureBakeResults); //set the texture bake resultAtlasesAndRects on the Mesh Baker component if it exists MeshBakerCommon[] mb = bakerCommons.ToArray(); for (int i = 0; i < mb.Length; i++) { mb[i].textureBakeResults = textureBakeResults; mb[i].TexBaker = this; } if (LOG_LEVEL >= MBLogLevel.info) { Debug.Log("Created Atlases"); } if (onBuiltAtlasesSuccess != null) { onBuiltAtlasesSuccess(this); } }