diff options
Diffstat (limited to '')
26 files changed, 3302 insertions, 0 deletions
diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools.meta b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools.meta new file mode 100755 index 00000000..41410bb5 --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 86107b9763a5ab3408a9884961b4191b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor.meta b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor.meta new file mode 100644 index 00000000..9ff74d2b --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 748053328138b574fb97df5308de5e24 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/BakeToVertexColorsEditor.cs b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/BakeToVertexColorsEditor.cs new file mode 100644 index 00000000..97d5f3d4 --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/BakeToVertexColorsEditor.cs @@ -0,0 +1,360 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEditor; +using UnityEngine; + + +namespace Poi +{ + public class BakeToVertexColorsEditor : EditorWindow + { + //Window + static readonly Vector2 MIN_WINDOW_SIZE = new Vector2(316, 210); + + // Version + Version version = new Version(1, 2); + string SubTitle + { + get + { + if(string.IsNullOrWhiteSpace(_subTitle)) + _subTitle = "by Pumkin - v" + version.ToString(); + return _subTitle; + } + } + + + //Strings + const string log_prefix = "<color=blue>Poi:</color> "; //color is hex or name + + const string bakedSuffix_normals = "baked_normals"; + const string bakedSuffix_position = "baked_position"; + + const string bakesFolderName = "Baked"; + const string defaultUnityAssetBakesFolder = "Default Unity Resources"; + + const string hint_bakeAverageNormals = "Use this if you want seamless outlines"; + const string hint_bakeVertexPositions = "Use this if you want scrolling emission"; + + const string button_bakeAverageNormals = "Bake Averaged Normals"; + const string button_bakeVertexPositions = "Bake Vertex Positions"; + + const string warning_noMeshesDetected = + "No meshes detected in selection. Make sure your object has a Skinned Mesh Renderer or a Mesh Renderer with a valid Mesh assigned"; + + //Properties + static GameObject Selection + { + get => _selection; + set => _selection = value; + } + + [MenuItem("Poi/Vertex Color Baker", priority = 11)] + public static void ShowWindow() + { + //Show existing window instance. If one doesn't exist, make one. + EditorWindow editorWindow = GetWindow(typeof(BakeToVertexColorsEditor)); + editorWindow.autoRepaintOnSceneChange = true; + editorWindow.minSize = MIN_WINDOW_SIZE; + + editorWindow.Show(); + editorWindow.titleContent = new GUIContent("Bake Colors"); + } + + void OnGUI() + { + EditorGUILayout.LabelField("Poi Vertex Color Baker", PoiStyles.TitleLabel); + EditorGUILayout.LabelField(SubTitle); + + PoiHelpers.DrawLine(); + + EditorGUI.BeginChangeCheck(); + GameObject obj = EditorGUILayout.ObjectField("Avatar", Selection, typeof(GameObject), true) as GameObject; + if(EditorGUI.EndChangeCheck()) + Selection = obj; + + PoiHelpers.DrawLine(); + + EditorGUI.BeginDisabledGroup(!Selection); + { + EditorGUILayout.HelpBox(hint_bakeAverageNormals, MessageType.Info); + if(GUILayout.Button(button_bakeAverageNormals)) + { + var meshes = GetAllMeshInfos(Selection); + if(meshes == null || meshes.Length == 0) + Debug.LogWarning(log_prefix + warning_noMeshesDetected); + else + BakeAveragedNormalsToColors(meshes); + } + + PoiHelpers.DrawLine(true, false); + EditorGUILayout.HelpBox(hint_bakeVertexPositions, MessageType.Info); + if(GUILayout.Button(button_bakeVertexPositions)) + { + var meshes = GetAllMeshInfos(Selection); + if(meshes == null || meshes.Length == 0) + Debug.LogWarning(log_prefix + warning_noMeshesDetected); + else + BakePositionsToColors(meshes); + } + } + EditorGUI.EndDisabledGroup(); + } + + /// <summary> + /// Saves a mesh in the same folder as the original asset + /// </summary> + /// <param name="mesh"></param> + /// <param name="newName">The new name of the mesh</param> + /// <returns>Returns the newly created mesh asset</returns> + static Mesh SaveMeshAsset(Mesh mesh, string newName) + { + string assetPath = AssetDatabase.GetAssetPath(mesh); + + if(string.IsNullOrWhiteSpace(assetPath)) + { + Debug.LogWarning(log_prefix + "Invalid asset path for " + mesh.name); + return null; + } + + //Figure out folder name + string bakesDir = $"{Path.GetDirectoryName(assetPath)}"; + + //Handle default assets + if(bakesDir.StartsWith("Library")) + bakesDir = $"Assets\\{defaultUnityAssetBakesFolder}"; + + if(!bakesDir.EndsWith(bakesFolderName)) + bakesDir += $"\\{bakesFolderName}"; + + if(!assetPath.Contains('.')) + assetPath += '\\'; + + PoiHelpers.EnsurePathExistsInAssets(bakesDir); + + //Generate path + string pathNoExt = Path.Combine(bakesDir, newName); + string newPath = AssetDatabase.GenerateUniqueAssetPath($"{pathNoExt}.mesh"); + + //Save mesh, load it back, assign to renderer + Mesh newMesh = Instantiate(mesh); + AssetDatabase.CreateAsset(newMesh, newPath); + + newMesh = AssetDatabase.LoadAssetAtPath<Mesh>(newPath); + + if(newMesh == null) + { + Debug.Log(log_prefix + "Failed to load saved mesh"); + return null; + } + + EditorGUIUtility.PingObject(newMesh); + return newMesh; + } + + /// <summary> + /// Sets the sharedMesh of a Skinned Mesh Renderer or Mesh Filter attached to a Mesh Renderer + /// </summary> + /// <param name="render"></param> + /// <param name="mesh"></param> + /// <returns></returns> + static bool SetRendererSharedMesh(Renderer render, Mesh mesh) + { + if(render is SkinnedMeshRenderer smr) + smr.sharedMesh = mesh; + else if(render is MeshRenderer mr) + { + var filter = mr.gameObject.GetComponent<MeshFilter>(); + filter.sharedMesh = mesh; + } + else + return false; + return true; + } + + static MeshInfo[] GetAllMeshInfos(GameObject obj) + { + return GetAllMeshInfos(obj?.GetComponentsInChildren<Renderer>(true)); + } + + static MeshInfo[] GetAllMeshInfos(params Renderer[] renderers) + { + var infos = renderers?.Select(ren => + { + MeshInfo info = new MeshInfo(); + if(ren is SkinnedMeshRenderer smr) + { + Mesh bakedMesh = new Mesh(); + Transform tr = smr.gameObject.transform; + Quaternion origRot = tr.localRotation; + Vector3 origScale = tr.localScale; + + tr.localRotation = Quaternion.identity; + tr.localScale = Vector3.one; + + smr.BakeMesh(bakedMesh); + + tr.localRotation = origRot; + tr.localScale = origScale; + + info.sharedMesh = smr.sharedMesh; + info.bakedVertices = bakedMesh?.vertices; + info.bakedNormals = bakedMesh?.normals; + info.ownerRenderer = smr; + if(!info.sharedMesh) + Debug.LogWarning(log_prefix + $"Skinned Mesh Renderer at <b>{info.ownerRenderer.gameObject.name}</b> doesn't have a valid mesh"); + } + else if(ren is MeshRenderer mr) + { + info.sharedMesh = mr.GetComponent<MeshFilter>()?.sharedMesh; + info.bakedVertices = info.sharedMesh?.vertices; + info.bakedNormals = info.sharedMesh?.normals; + info.ownerRenderer = mr; + if(!info.sharedMesh) + Debug.LogWarning(log_prefix + $"Mesh renderer at <b>{info.ownerRenderer.gameObject.name}</b> doesn't have a mesh filter with a valid mesh"); + } + return info; + }).ToArray(); + + return infos; + } + + static void BakePositionsToColors(MeshInfo[] meshInfos) + { + var queue = new Dictionary<MeshInfo, Mesh>(); + try + { + AssetDatabase.StartAssetEditing(); + foreach(var meshInfo in meshInfos) + { + if(!meshInfo.sharedMesh) + continue; + + Vector3[] verts = meshInfo.bakedVertices; //accessing mesh.vertices on every iteration is very slow + Color[] colors = new Color[verts.Length]; + for(int i = 0; i < verts.Length; i++) + colors[i] = new Color(verts[i].x, verts[i].y, verts[i].z); + meshInfo.sharedMesh.colors = colors; + + //Create new mesh asset and add it to queue + string name = PoiHelpers.AddSuffix(meshInfo.ownerRenderer.gameObject.name, bakedSuffix_position); + Mesh newMesh = SaveMeshAsset(meshInfo.sharedMesh, name); + if(newMesh) + queue.Add(meshInfo, newMesh); + } + } + catch(Exception ex) + { + Debug.LogException(ex); + } + finally + { + AssetDatabase.StopAssetEditing(); + } + + //After all meshes are imported assign the meshes + foreach(var kv in queue) + { + SetRendererSharedMesh(kv.Key.ownerRenderer, kv.Value); + } + } + + static void BakeAveragedNormalsToColors(params MeshInfo[] infos) + { + var queue = new Dictionary<MeshInfo, Mesh>(); + try + { + AssetDatabase.StartAssetEditing(); + foreach(var meshInfo in infos) + { + if(!meshInfo.sharedMesh) + continue; + + Vector3[] verts = meshInfo.bakedVertices; + Vector3[] normals = meshInfo.bakedNormals; + VertexInfo[] vertInfo = new VertexInfo[verts.Length]; + for(int i = 0; i < verts.Length; i++) + { + vertInfo[i] = new VertexInfo() + { + vertex = verts[i], + originalIndex = i, + normal = normals[i] + }; + } + var groups = vertInfo.GroupBy(x => x.vertex); + VertexInfo[] processedVertInfo = new VertexInfo[vertInfo.Length]; + int index = 0; + foreach(IGrouping<Vector3, VertexInfo> group in groups) + { + Vector3 avgNormal = Vector3.zero; + foreach(VertexInfo item in group) + avgNormal += item.normal; + + avgNormal /= group.Count(); + foreach(VertexInfo item in group) + { + processedVertInfo[index] = new VertexInfo() + { + vertex = item.vertex, + originalIndex = item.originalIndex, + normal = item.normal, + averagedNormal = avgNormal + }; + index++; + } + } + Color[] colors = new Color[verts.Length]; + for(int i = 0; i < processedVertInfo.Length; i++) + { + VertexInfo info = processedVertInfo[i]; + + int origIndex = info.originalIndex; + Vector3 normal = info.averagedNormal; + Color normColor = new Color(normal.x, normal.y, normal.z, 1); + colors[origIndex] = normColor; + } + meshInfo.sharedMesh.colors = colors; + + string name = PoiHelpers.AddSuffix(meshInfo.ownerRenderer.gameObject.name, bakedSuffix_normals); + Mesh newMesh = SaveMeshAsset(meshInfo.sharedMesh, name); + if(newMesh) + queue.Add(meshInfo, newMesh); + } + } + catch(Exception ex) + { + Debug.LogException(ex); + } + finally + { + AssetDatabase.StopAssetEditing(); + } + + //Assign all new meshes to their renderers + foreach(var kv in queue) + SetRendererSharedMesh(kv.Key.ownerRenderer, kv.Value); + } + + struct MeshInfo + { + public Renderer ownerRenderer; + public Mesh sharedMesh; + public Vector3[] bakedVertices; + public Vector3[] bakedNormals; + } + + struct VertexInfo + { + public Vector3 vertex; + public int originalIndex; + public Vector3 normal; + public Vector3 averagedNormal; + } + + static GameObject _selection; + private string _subTitle; + } +}
\ No newline at end of file diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/BakeToVertexColorsEditor.cs.meta b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/BakeToVertexColorsEditor.cs.meta new file mode 100644 index 00000000..d603b15a --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/BakeToVertexColorsEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3f398d68f8c01b54485d2a04a13c958b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/GradientFlood (8).cs b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/GradientFlood (8).cs new file mode 100644 index 00000000..10063a53 --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/GradientFlood (8).cs @@ -0,0 +1,567 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEditor; +using UnityEngine; + +//Made by Dreadrith#3238 +//Version v1.1.0 +//Discord: https://discord.gg/ZsPfrGn +//Github: https://github.com/Dreadrith/DreadScripts +//Gumroad: https://gumroad.com/dreadrith +//Ko-fi: https://ko-fi.com/dreadrith + +namespace DreadScripts +{ + public class GradientFlood : EditorWindow + { + + #region Automated Variables + private static Vector2 scroll; + private static float modifiedBoundRange; + private static Texture2D titleTexture; + #endregion + + #region Input + public static Texture2D pathTexture; + public static Color startPixelsColor = Color.red; + public static Color limitPixelsColor = Color.white; + public static GradientType gradientType = GradientType.DataGradient; + + public static Color tintColor = Color.white; + public static Gradient gradientColor = new Gradient(); + + public static float gradientDistribution = 1; + public static float startColorTolerance = 0.05f; + public static float limitColorTolerance = 0.05f; + public static float rangeLowerBound; + public static float rangeUpperBound = 255; + public static bool invertGradient; + public static bool loopGradient; + public static bool applyGradientAlpha; + #endregion + + + public enum GradientType + { + DataGradient, + TintedGradient, + GradientGradient + } + + public enum _FloodBehavior + { + Side, + Diagonal, + SideAndDiagonal, + Horizontal, + Vertical, + Custom + } + + public static bool foldoutFloodStep; + public static _FloodBehavior floodBehavior = _FloodBehavior.SideAndDiagonal; + public static List<FloodStep> floodSteps = new List<FloodStep>() + { + new FloodStep + ( + new Vector2Int(1, 0), + new Vector2Int(-1, 0), + new Vector2Int(0, 1), + new Vector2Int(0, -1), + new Vector2Int(1, 1), + new Vector2Int(1, -1), + new Vector2Int(-1, 1), + new Vector2Int(-1, -1) + + ) + }; + + + + [MenuItem("Poi/Gradient Flood")] + private static void showWindow() + { + EditorWindow w = GetWindow<GradientFlood>(false, "Gradient Flood", true); + if (!titleTexture) + { + titleTexture = GetColors((Texture2D)EditorGUIUtility.IconContent("Texture2D Icon").image, 16, 16, out _); + titleTexture.Apply(); + } + + w.titleContent.image = titleTexture; + w.minSize = new Vector2(423, 253); + } + + private void OnGUI() + { + scroll = EditorGUILayout.BeginScrollView(scroll); + GUIStyle centeredTitle = new GUIStyle("boldlabel") {alignment = TextAnchor.MiddleCenter, fontSize = 16}; + using (new GUILayout.VerticalScope("helpbox")) + { + GUILayout.Label("Texture", centeredTitle); + using (new GUILayout.HorizontalScope()) + { + GUILayout.FlexibleSpace(); + EditorGUIUtility.labelWidth = 1; + pathTexture = (Texture2D) EditorGUILayout.ObjectField(string.Empty, pathTexture, typeof(Texture2D), false, GUILayout.Width(80), GUILayout.Height(80)); + EditorGUIUtility.labelWidth = 0; + + GUILayout.FlexibleSpace(); + } + + DrawFloodBehaviorGUI(); + + using (new GUILayout.HorizontalScope("box")) + gradientType = (GradientType)EditorGUILayout.EnumPopup("Gradient Type", gradientType); + + + switch (gradientType) + { + case GradientType.TintedGradient: + using (new GUILayout.HorizontalScope("box")) + tintColor = EditorGUILayout.ColorField("Tint", tintColor); + break; + case GradientType.GradientGradient: + using (new GUILayout.HorizontalScope("box")) + gradientColor = EditorGUILayout.GradientField("Gradient", gradientColor); + break; + } + + + if (gradientType > 0) + { + using (new GUILayout.HorizontalScope("box")) + { + GUILayout.Label("Color Range"); + + EditorGUI.BeginChangeCheck(); + + rangeLowerBound = EditorGUILayout.DelayedIntField((int) rangeLowerBound, GUI.skin.label, GUILayout.Width(28)); + EditorGUILayout.MinMaxSlider(ref rangeLowerBound, ref rangeUpperBound, 0, 255); + + rangeUpperBound = EditorGUILayout.DelayedIntField((int) rangeUpperBound, GUI.skin.label, GUILayout.Width(28)); + + if (EditorGUI.EndChangeCheck()) + { + rangeUpperBound = Mathf.Clamp((int) rangeUpperBound, 0, 255); + rangeLowerBound = Mathf.Max(0, Mathf.Min(rangeUpperBound, rangeLowerBound)); + } + } + } + + + using (new GUILayout.HorizontalScope("box")) + { + using (new GUILayout.HorizontalScope()) + GUILayout.Label("Tolerance"); + + using (new GUILayout.HorizontalScope()) + { + EditorGUIUtility.labelWidth = 40; + startColorTolerance = EditorGUILayout.Slider("Start", startColorTolerance, 0, 1); + limitColorTolerance = EditorGUILayout.Slider("Limit", limitColorTolerance, 0, 1); + EditorGUIUtility.labelWidth = 0; + } + } + + using (new GUILayout.HorizontalScope("box")) + { + invertGradient = EditorGUILayout.Toggle("Invert Gradient", invertGradient); + + if (gradientType > 0) applyGradientAlpha = EditorGUILayout.Toggle("Apply Gradient Alpha", applyGradientAlpha); + } + + using (new GUILayout.HorizontalScope("box")) + { + loopGradient = EditorGUILayout.Toggle("Loop Gradient", loopGradient); + if (loopGradient) gradientDistribution = EditorGUILayout.FloatField("Distribution", gradientDistribution); + } + + using (new EditorGUI.DisabledScope(!pathTexture)) + if (GUILayout.Button("Fill")) + GenerateFilledTexture(pathTexture); + + } + Credit(); + + EditorGUILayout.EndScrollView(); + } + + private void DrawFloodBehaviorGUI() + { + using (var change = new EditorGUI.ChangeCheckScope()) + { + using (new GUILayout.HorizontalScope("box")) + floodBehavior = (_FloodBehavior)EditorGUILayout.EnumPopup(new GUIContent("Flood Behavior", "The path to fill in the texture starting from the start pixels"), floodBehavior); + + if (change.changed) + { + switch (floodBehavior) + { + case _FloodBehavior.Side: + floodSteps.Clear(); + floodSteps.Add(new FloodStep + ( + + new Vector2Int(1, 0), + new Vector2Int(-1, 0), + new Vector2Int(0, 1), + new Vector2Int(0, -1) + + )); + break; + case _FloodBehavior.Diagonal: + floodSteps.Clear(); + floodSteps.Add(new FloodStep + ( + new Vector2Int(1, 1), + new Vector2Int(-1, -1), + new Vector2Int(1, -1), + new Vector2Int(-1, 1) + )); + break; + case _FloodBehavior.SideAndDiagonal: + floodSteps.Clear(); + floodSteps.Add(new FloodStep + ( + + new Vector2Int(1, 0), + new Vector2Int(-1, 0), + new Vector2Int(0, 1), + new Vector2Int(0, -1), + new Vector2Int(1, 1), + new Vector2Int(1, -1), + new Vector2Int(-1, 1), + new Vector2Int(-1, -1) + + )); + break; + case _FloodBehavior.Horizontal: + floodSteps.Clear(); + floodSteps.Add(new FloodStep + ( + new Vector2Int(1, 0), + new Vector2Int(-1, 0) + )); + break; + case _FloodBehavior.Vertical: + floodSteps.Clear(); + floodSteps.Add(new FloodStep + ( + new Vector2Int(0, 1), + new Vector2Int(0, -1) + )); + break; + } + } + } + if (floodBehavior != _FloodBehavior.Custom) return; + + using (new GUILayout.VerticalScope("box")) + { + using (new GUILayout.VerticalScope("helpbox")) + { + foldoutFloodStep = EditorGUILayout.Foldout(foldoutFloodStep, "Flood Steps"); + } + + if (foldoutFloodStep) + { + EditorGUI.indentLevel++; + for (int i = 0; i < floodSteps.Count; i++) + { + DrawFloodStepGUI(floodSteps[i], i); + } + + if (GUILayout.Button("Add Step")) + floodSteps.Add(new FloodStep()); + EditorGUI.indentLevel--; + } + } + } + private void DrawFloodStepGUI(FloodStep step, int i) + { + using (new GUILayout.VerticalScope("box")) + { + using (new GUILayout.HorizontalScope("helpbox")) + { + step.foldout = EditorGUILayout.Foldout(step.foldout, $"Step {i}:"); + + using (new EditorGUI.DisabledGroupScope(floodSteps.Count == 1)) + if (GUILayout.Button("X", GUILayout.Width(20), GUILayout.Height(18))) + { + floodSteps.RemoveAt(i); + goto Skip; + } + } + + if (step.foldout) + { + EditorGUI.indentLevel++; + for (int j = 0; j < step.coordinates.Count; j++) + { + using (new GUILayout.HorizontalScope("box")) + { + step.coordinates[j] = EditorGUILayout.Vector2IntField(string.Empty, step.coordinates[j]); + if (GUILayout.Button("X", GUILayout.Width(20), GUILayout.Height(18))) + step.coordinates.RemoveAt(j); + } + + + } + if (GUILayout.Button("+", "toolbarbutton")) step.coordinates.Add(new Vector2Int()); + + EditorGUI.indentLevel--; + } + Skip:; + + } + } + + public static void GenerateFilledTexture(Texture2D texture) + { + if (!loopGradient) gradientDistribution = 1; + if (gradientType == GradientType.DataGradient) + { + rangeLowerBound = 1; + rangeUpperBound = 255; + } + + int width = texture.width; + modifiedBoundRange = rangeUpperBound / 255 - rangeLowerBound / 255; + Texture2D gradientTexture = GetColors(texture, out Color[] ogColors); + GradientFillPixel[] gradientPixels = new GradientFillPixel[ogColors.Length]; + + Queue<GradientFillPixel> pixelsToExpand = new Queue<GradientFillPixel>(); + + for (int i = 0; i < ogColors.Length; i++) + { + gradientPixels[i] = new GradientFillPixel(ogColors[i], i); + if (!gradientPixels[i].isLimit && gradientPixels[i].isFilled) pixelsToExpand.Enqueue(gradientPixels[i]); + } + + if (pixelsToExpand.Count == 0) + Debug.LogWarning("<color=red>[GPFiller]</color> No start pixels were found! If start pixels exist, try adjusting the color tolerance."); + + int floodIndex = 0; + int currentStackCount = pixelsToExpand.Count; + int nextStackCount = 0; + + bool IsValidFillIndex(int index, out GradientFillPixel pixelToFill) + { + if (index >= 0 && index < ogColors.Length) + { + pixelToFill = gradientPixels[index]; + if (!pixelToFill.isLimit && !pixelToFill.isFilled) + { + pixelsToExpand.Enqueue(pixelToFill); + nextStackCount++; + return true; + } + } + + pixelToFill = null; + return false; + } + + void FillIndex(GradientFillPixel fillerPixel, int index) + { + if (!IsValidFillIndex(index, out GradientFillPixel nextPixel)) return; + nextPixel.gradientValue = fillerPixel.gradientValue + gradientDistribution; + nextPixel.isFilled = true; + } + + + + while (pixelsToExpand.Any()) + { + FloodStep currentStep = floodSteps[floodIndex % floodSteps.Count]; + var pixel = pixelsToExpand.Dequeue(); + + foreach (var coord in currentStep.coordinates) + { + int finalX = (pixel.arrayIndex % width) + coord.x; + if (finalX < 0 || finalX >= width) continue; + + FillIndex(pixel, pixel.arrayIndex + coord.x + width * coord.y); + } + + currentStackCount--; + if (currentStackCount == 0) + { + currentStackCount = nextStackCount; + nextStackCount = 0; + floodIndex++; + } + } + + + float maxGradientValue = gradientPixels.Max(p => p.gradientValue); + if (gradientType == GradientType.DataGradient) maxGradientValue /= 4; + + for (int i = 0; i < ogColors.Length; i++) + { + var f = gradientPixels[i].GetFloatValue(maxGradientValue); + + if (f == 0) ogColors[i] = Color.clear; + else + { + + if (gradientType == GradientType.TintedGradient) + ogColors[i] = new Color(f * tintColor.r, f * tintColor.g, f * tintColor.b, gradientPixels[i].isLimit ? 1 : (applyGradientAlpha ? f : 1) * tintColor.a); + else if (gradientType == GradientType.GradientGradient) + { + Color gradColor = gradientColor.Evaluate(f); + gradColor.a = gradientPixels[i].isLimit ? 1 : (applyGradientAlpha ? f : 1) * gradColor.a; + ogColors[i] = gradColor; + } + else + { + if (f <= 1) ogColors[i] = new Color(f % 1, 0, 0, 0); + + else if (f <= 2) ogColors[i] = new Color(1, f%1, 0, 0); + + else if (f <= 3) ogColors[i] = new Color(1, 1, f % 1, 0); + + else ogColors[i] = new Color(1, 1, 1, f % 1); + + } + } + } + + gradientTexture.SetPixels(ogColors); + gradientTexture.Apply(); + + string assetPath = AssetDatabase.GetAssetPath(pathTexture); + string ext = Path.GetExtension(assetPath); + byte[] data; + switch (ext) + { + case ".jpeg" when !applyGradientAlpha && gradientType != GradientType.DataGradient: + case ".jpg" when !applyGradientAlpha && gradientType != GradientType.DataGradient: + ext = ".jpg"; + data = gradientTexture.EncodeToJPG(100); + break; + case ".tga": + data = gradientTexture.EncodeToTGA(); + break; + default: + ext = ".png"; + data = gradientTexture.EncodeToPNG(); + break; + } + + + DestroyImmediate(gradientTexture); + + string savePath = AssetDatabase.GenerateUniqueAssetPath($"{Path.GetDirectoryName(assetPath)}/{pathTexture.name}{ext}"); + SaveTexture(data, savePath); + CopyTextureSettings(assetPath, savePath); + } + + public static Texture2D GetColors(Texture2D texture, int width, int height, out Color[] Colors, bool unloadTempTexture = false) + { + //Thanks to + //https://gamedev.stackexchange.com/questions/92285/unity3d-resize-texture-without-corruption + texture.filterMode = FilterMode.Point; + RenderTexture rt = RenderTexture.GetTemporary(width, height); + + rt.filterMode = FilterMode.Point; + RenderTexture.active = rt; + Graphics.Blit(texture, rt); + Texture2D newTexture = new Texture2D(width, height); + newTexture.ReadPixels(new Rect(0, 0, width, height), 0, 0); + Color[] myColors = newTexture.GetPixels(); + RenderTexture.active = null; + ///////////////////// + Colors = myColors; + if (unloadTempTexture) + { + DestroyImmediate(newTexture); + return null; + } + return newTexture; + } + + public static Texture2D GetColors(Texture2D texture, out Color[] Colors, bool unloadTempTexture = false) + { + return GetColors(texture, texture.width, texture.height, out Colors, unloadTempTexture); + } + + private static void CopyTextureSettings(string from, string to) + { + TextureImporter source = (TextureImporter)AssetImporter.GetAtPath(from); + TextureImporterSettings sourceSettings = new TextureImporterSettings(); + source.ReadTextureSettings(sourceSettings); + + TextureImporter destination = (TextureImporter)AssetImporter.GetAtPath(to); + destination.SetTextureSettings(sourceSettings); + destination.maxTextureSize = source.maxTextureSize; + destination.textureCompression = source.textureCompression; + destination.crunchedCompression = source.crunchedCompression; + destination.SaveAndReimport(); + } + + private static void SaveTexture(byte[] textureEncoding, string path) + { + using (System.IO.FileStream stream = System.IO.File.Create(path)) + stream.Write(textureEncoding, 0, textureEncoding.Length); + AssetDatabase.Refresh(); + EditorGUIUtility.PingObject(AssetDatabase.LoadMainAssetAtPath(path)); + } + + public class GradientFillPixel + { + public readonly bool isLimit; + public bool isFilled; + public float gradientValue; + public int arrayIndex; + + public GradientFillPixel(Color pixelColor, int index) + { + isLimit = Mathf.Abs(pixelColor.r - limitPixelsColor.r) < limitColorTolerance && + Mathf.Abs(pixelColor.g - limitPixelsColor.g) < limitColorTolerance && + Mathf.Abs(pixelColor.b - limitPixelsColor.b) < limitColorTolerance; + + isFilled = Mathf.Abs(pixelColor.r - startPixelsColor.r) < startColorTolerance && + Mathf.Abs(pixelColor.g - startPixelsColor.g) < startColorTolerance && + Mathf.Abs(pixelColor.b - startPixelsColor.b) < startColorTolerance; + + gradientValue = (int)rangeLowerBound; + arrayIndex = index; + } + + public float GetFloatValue(float maxGradientValue) + { + if (isLimit || !isFilled) return 0; + float floatValue = !loopGradient ? gradientValue / maxGradientValue : (gradientValue % 255 * (gradientType == GradientType.DataGradient ? 4 : 1)) / 255f; + float adjustedValue = floatValue * modifiedBoundRange + rangeLowerBound / 255; + return invertGradient ? (gradientType == GradientType.DataGradient ? 4 : 1) - adjustedValue : adjustedValue; + } + } + + public class FloodStep + { + public List<Vector2Int> coordinates; + public bool foldout; + + public FloodStep(params Vector2Int[] coordinates) + { + this.coordinates = coordinates.ToList(); + } + } + + + private static void Credit() + { + using (new GUILayout.HorizontalScope()) + { + GUILayout.FlexibleSpace(); + if (GUILayout.Button("Made By Dreadrith#3238", "boldlabel")) + Application.OpenURL("https://linktr.ee/Dreadrith"); + } + } + } + + +} diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/GradientFlood (8).cs.meta b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/GradientFlood (8).cs.meta new file mode 100644 index 00000000..7e735a0d --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/GradientFlood (8).cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d47e3b8c6a19a8145bb62e0d933a9679 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/ModularShadersGeneratorWindow.cs b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/ModularShadersGeneratorWindow.cs new file mode 100644 index 00000000..9b72b150 --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/ModularShadersGeneratorWindow.cs @@ -0,0 +1,211 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Poiyomi.ModularShaderSystem; +using UnityEditor; +using UnityEngine; +using UnityEngine.UI; +using UnityEngine.UIElements; +using Button = UnityEngine.UIElements.Button; +using Toggle = UnityEngine.UIElements.Toggle; + +namespace PoiyomiPatreon.Scripts.poi_tools.Editor +{ + public class ModularShadersGeneratorElement : VisualElement + { + private bool _isSelected; + + public bool IsSelected + { + get => _isSelected; + set + { + if (_isErrored) return; + _isSelected = value; + _toggle.SetValueWithoutNotify(_isSelected); + } + } + + public ModularShader Shader { get; set; } + + private readonly Toggle _toggle; + private readonly bool _isErrored; + public ModularShadersGeneratorElement(ModularShader shader) + { + Shader = shader; + style.flexDirection = FlexDirection.Row; + _toggle = new Toggle(); + _toggle.RegisterValueChangedCallback(evt => IsSelected = evt.newValue); + Add(_toggle); + Add(new Label(Shader.Name)); + var issues = ShaderGenerator.CheckShaderIssues(shader); + if (issues.Count > 0) + { + _isErrored = true; + _toggle.SetEnabled(false); + VisualElement element = new VisualElement(); + element.AddToClassList("error"); + element.tooltip = "Modular shader has the following errors: \n -" + string.Join("\n -", issues); + Add(element); + } + } + } + + public class ModularShadersGeneratorWindow : EditorWindow + { + [MenuItem("Poi/Modular Shaders Generator")] + private static void ShowWindow() + { + var window = GetWindow<ModularShadersGeneratorWindow>(); + window.titleContent = new GUIContent("Modular Shaders Generator"); + window.Show(); + } + + private VisualElement _root; + private List<ModularShadersGeneratorElement> _elements; + private string _folderPath = "Assets/_poiyomiShaders/Shaders/8.1/Pro"; + + private void CreateGUI() + { + _root = rootVisualElement; + try + { + Reload(); + } + catch (Exception e) + { + Console.WriteLine(e); + } + } + + private void Reload() + { + _root.Clear(); + + var styleSheet = Resources.Load<StyleSheet>("Poi/ModularShadersGeneratorStyle"); + _root.styleSheets.Add(styleSheet); + + var view = new ScrollView(ScrollViewMode.Vertical); + + var selectButtons = new VisualElement(); + selectButtons.AddToClassList("buttons-area"); + + var selectAll = new Button(); + selectAll.text = "Select all"; + selectAll.style.flexGrow = 1; + selectAll.clicked += () => + { + foreach (var element in _elements) + element.IsSelected = true; + }; + selectButtons.Add(selectAll); + + var deselectAll = new Button(); + deselectAll.text = "Deselect all"; + deselectAll.style.flexGrow = 1; + deselectAll.clicked += () => + { + foreach (var element in _elements) + element.IsSelected = false; + }; + selectButtons.Add(deselectAll); + + var toggleSelections = new Button(); + toggleSelections.text = "Toggle selections"; + toggleSelections.style.flexGrow = 1; + toggleSelections.clicked += () => + { + foreach (var element in _elements) + element.IsSelected = !element.IsSelected; + }; + selectButtons.Add(toggleSelections); + + var reloadButton = new Button(); + reloadButton.text = "Refresh"; + reloadButton.style.flexGrow = 1; + reloadButton.clicked += () => + { + Reload(); + }; + selectButtons.Add(reloadButton); + + view.Add(selectButtons); + + // Load all modular shaders + _elements = new List<ModularShadersGeneratorElement>(); + foreach (var modularShader in FindAssetsByType<ModularShader>()) + { + var element = new ModularShadersGeneratorElement(modularShader); + _elements.Add(element); + view.Add(element); + } + + var fileSelector = new VisualElement(); + fileSelector.AddToClassList("folder-selector"); + + var folder = new TextField(); + folder.value = _folderPath; + folder.RegisterValueChangedCallback(evt => _folderPath = evt.newValue); + folder.style.flexShrink = 1; + folder.style.flexGrow = 1; + folder.SetEnabled(false); + var label = new Label("Destination "); + label.style.alignSelf = Align.Center; + fileSelector.Add(label); + fileSelector.Add(folder); + var fileButton = new Button(); + fileButton.text = "Open"; + fileButton.clicked += () => + { + string path = EditorUtility.OpenFolderPanel("Select folder to use", "Assets", ""); + if (path.Length == 0) + return; + + if (!Directory.Exists(path)) + { + EditorUtility.DisplayDialog("Error", "The folder does not exist", "Ok"); + return; + } + + folder.value = path; + }; + fileSelector.Add(fileButton); + view.Add(fileSelector); + + var button = new Button(); + button.text = "Generate Shaders"; + button.clicked += GenerateShaders; + view.Add(button); + + _root.Add(view); + } + + private void GenerateShaders() + { + if (!Directory.Exists(_folderPath)) + { + EditorUtility.DisplayDialog("Error", "The destination folder does not exist", "Ok"); + return; + } + + foreach (ModularShadersGeneratorElement element in _elements.Where(x => x.IsSelected)) + ShaderGenerator.GenerateShader(_folderPath, element.Shader); + } + + private static T[] FindAssetsByType<T>() where T : UnityEngine.Object + { + List<T> assets = new List<T>(); + AssetDatabase.Refresh(); + string[] guids = AssetDatabase.FindAssets($"t:{typeof(T).ToString().Replace("UnityEngine.", "")}"); + for (int i = 0; i < guids.Length; i++) + { + string assetPath = AssetDatabase.GUIDToAssetPath(guids[i]); + T asset = AssetDatabase.LoadAssetAtPath<T>(assetPath); + if (asset != null) + assets.Add(asset); + } + return assets.ToArray(); + } + } +}
\ No newline at end of file diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/ModularShadersGeneratorWindow.cs.meta b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/ModularShadersGeneratorWindow.cs.meta new file mode 100644 index 00000000..05c59212 --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/ModularShadersGeneratorWindow.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 628a5d8b8b9a456ca963d43c28fb86c1 +timeCreated: 1638402450
\ No newline at end of file diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/PoiData.cs b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/PoiData.cs new file mode 100644 index 00000000..7b388701 --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/PoiData.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEditor; +using UnityEngine; + +namespace Poi +{ + internal static class PoiPaths + { + public const string defaultResourcesPath = "Library/unity default resources/"; + public const string poiResourcesPath = "Poi/"; + } + + internal static class PoiStyles + { + public static GUIStyle BigButton + { + get + { + if(_bigButton == null) + _bigButton = new GUIStyle("button") + { + fixedHeight = 22 * EditorGUIUtility.pixelsPerPoint + }; + return _bigButton; + } + } + + public static GUIStyle TitleLabel + { + get + { + if(_titleLabel == null) + _titleLabel = new GUIStyle(EditorStyles.label) + { + fontSize = 15, stretchHeight = true, clipping = TextClipping.Overflow + }; + + return _titleLabel; + } + } + + static GUIStyle _bigButton; + static GUIStyle _titleLabel; + } + + internal static class PoiIcons + { + public static Texture2D LinkIcon + { + get + { + if(!_linkIcon) + { + string linkTexPath = EditorGUIUtility.isProSkin ? "icon_link_pro" : "icon_link"; + _linkIcon = Resources.Load<Texture2D>(PoiPaths.poiResourcesPath + linkTexPath); + } + + return _linkIcon; + } + } + + private static Texture2D _linkIcon; + } +} + + diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/PoiData.cs.meta b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/PoiData.cs.meta new file mode 100644 index 00000000..2fae90dc --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/PoiData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8f58036675b906e4797a5c394781b2a0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/PoiHelpers.cs b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/PoiHelpers.cs new file mode 100644 index 00000000..2d3d1485 --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/PoiHelpers.cs @@ -0,0 +1,190 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEditor; +using UnityEngine; + +namespace Poi +{ + static class PoiHelpers + { + static readonly string suffixSeparator = "_"; + + /// <summary> + /// Changes a path in Assets to an absolute windows path + /// </summary> + /// <param name="localPath"></param> + /// <returns></returns> + public static string LocalAssetsPathToAbsolutePath(string localPath) + { + localPath = NormalizePathSlashes(localPath); + const string assets = "Assets/"; + if(localPath.StartsWith(assets)) + { + localPath = localPath.Remove(0, assets.Length); + localPath = $"{Application.dataPath}/{localPath}"; + } + return localPath; + } + + /// <summary> + /// Replaces all forward slashes \ with back slashes / + /// </summary> + /// <param name="path"></param> + /// <returns></returns> + public static string NormalizePathSlashes(string path) + { + if(!string.IsNullOrEmpty(path)) + path = path.Replace('\\', '/'); + return path; + } + + /// <summary> + /// Ensures directory exists inside the assets folder + /// </summary> + /// <param name="assetPath"></param> + public static void EnsurePathExistsInAssets(string assetPath) + { + Directory.CreateDirectory(LocalAssetsPathToAbsolutePath(assetPath)); + } + + /// <summary> + /// Adds a suffix to the end of the string then returns it + /// </summary> + /// <param name="str"></param> + /// <param name="suffixes"></param> + /// <returns></returns> + public static string AddSuffix(string str, params string[] suffixes) + { + bool ignoreSeparatorOnce = string.IsNullOrWhiteSpace(str); + StringBuilder sb = new StringBuilder(str); + foreach(var suff in suffixes) + { + if(ignoreSeparatorOnce) + { + sb.Append(suff); + ignoreSeparatorOnce = false; + continue; + } + sb.Append(suffixSeparator + suff); + } + return sb.ToString(); + } + + /// <summary> + /// Draws a GUI ilne + /// </summary> + /// <param name="spaceBefore"></param> + /// <param name="spaceAfter"></param> + internal static void DrawLine(bool spaceBefore = true, bool spaceAfter = true) + { + float spaceHeight = 3f; + if(spaceBefore) + GUILayout.Space(spaceHeight); + + Rect rect = EditorGUILayout.GetControlRect(false, 1); + rect.height = 1; + EditorGUI.DrawRect(rect, new Color(0.5f, 0.5f, 0.5f, 1)); + + if(spaceAfter) + GUILayout.Space(spaceHeight); + } + + /// <summary> + /// Destroys an object with DestroyImmediate in object mode and Destroy in play mode + /// </summary> + /// <param name="obj"></param> + internal static void DestroyAppropriate(UnityEngine.Object obj) + { + if(EditorApplication.isPlaying) + UnityEngine.Object.Destroy(obj); + else + UnityEngine.Object.DestroyImmediate(obj); + } + + /// <summary> + /// Changes path from full windows path to a local path in the Assets folder + /// </summary> + /// <param name="path"></param> + /// <returns>Path starting with Assets</returns> + internal static string AbsolutePathToLocalAssetsPath(string path) + { + if(path.StartsWith(Application.dataPath)) + path = "Assets" + path.Substring(Application.dataPath.Length); + return path; + } + + /// <summary> + /// Selects and highlights the asset in your unity Project tab + /// </summary> + /// <param name="path"></param> + internal static void PingAssetAtPath(string path) + { + var inst = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(path).GetInstanceID(); + EditorGUIUtility.PingObject(inst); + } + + internal static void DrawWithLabelWidth(float width, Action action) + { + if(action == null) + return; + float old = EditorGUIUtility.labelWidth; + action.Invoke(); + EditorGUIUtility.labelWidth = old; + } + } + + internal static class PoiExtensions + { + public static Shader PackerShader => Shader.Find("Hidden/Poi/TexturePacker"); + + public static Shader UnpackerShader => Shader.Find("Hidden/Poi/TextureUnpacker"); + + /// <summary> + /// Extension method that bakes a material to <paramref name="tex"/> + /// </summary> + /// <param name="tex">Texture to bake <paramref name="materialToBake"/> to</param> + /// <param name="materialToBake">Material to bake to <paramref name="tex"/></param> + internal static void BakeMaterialToTexture(this Texture2D tex, Material materialToBake) + { + var res = new Vector2Int(tex.width, tex.height); + + RenderTexture renderTexture = RenderTexture.GetTemporary(res.x, res.y); + Graphics.Blit(null, renderTexture, materialToBake); + + //transfer image from rendertexture to texture + RenderTexture.active = renderTexture; + tex.ReadPixels(new Rect(Vector2.zero, res), 0, 0); + tex.Apply(false, false); + + //clean up variables + RenderTexture.active = null; + RenderTexture.ReleaseTemporary(renderTexture); + } + + /// <summary> + /// Rounds vector to closest power of two. Optionally, if above ceiling, square root down by one power of two + /// </summary> + /// <param name="vec"></param> + /// <param name="ceiling">Power of two ceiling. Will be rounded to power of two if not power of two already</param> + /// <returns></returns> + internal static Vector2Int ClosestPowerOfTwo(this Vector2Int vec, int? ceiling = null) + { + int x = Mathf.ClosestPowerOfTwo(vec.x); + int y = Mathf.ClosestPowerOfTwo(vec.y); + + if(ceiling != null) + { + int ceil = Mathf.ClosestPowerOfTwo((int) ceiling); + + x = Mathf.Clamp(x, x, ceil); + y = Mathf.Clamp(y, y, ceil); + } + + return new Vector2Int(x, y); + } + } +}
\ No newline at end of file diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/PoiHelpers.cs.meta b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/PoiHelpers.cs.meta new file mode 100644 index 00000000..5326296d --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/PoiHelpers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 32406f186e960c04ab7448ec0b4ca0e0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/TextureUtility.cs b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/TextureUtility.cs new file mode 100644 index 00000000..6d487a41 --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/TextureUtility.cs @@ -0,0 +1,1244 @@ +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; +using System.Linq; + +//Made by Dreadrith#3238 +//Server: https://discord.gg/ZsPfrGn +//Github: https://github.com/Dreadrith/DreadScripts +//Gumroad: https://gumroad.com/dreadrith + +namespace Poi.TextureUtility +{ + public class TextureUtility : EditorWindow + { + private readonly string[] DimensionPresets = new string[] + { + "128x128", + "256x256", + "512x512", + "1024x1024", + "2048x2048", + "4096x4096", + }; + + private static GUIContent resetIcon; + private static Texture2D titleTexture; + + private static Texture2D mainTexture; + private static Texture2D maskTexture; + + private static int jpgQuality = 75; + private static int texWidth, texHeight; + private static bool copyImport = true; + private static bool pingTexture = true; + + private static bool rotating; + private static TexRotation rotationType; + + private static bool inverting; + private static bool maskInvert=true; + private static bool invertRedS = true, invertGreenS = true, invertBlueS = true, invertAlphaS; + + private static bool unpacking=true,packing; + private static bool editingTab=true, packingTab,creatingTab; + + + private static ChannelTexture redChannel = new ChannelTexture("Red", 0); + private static ChannelTexture greenChannel = new ChannelTexture("Green", 1); + private static ChannelTexture blueChannel = new ChannelTexture("Blue", 2); + private static ChannelTexture alphaChannel = new ChannelTexture("Alpha", 0); + private static ChannelTexture[] channelTextures = new ChannelTexture[] {redChannel,greenChannel,blueChannel,alphaChannel }; + + private static bool hueShifting; + private static bool maskHueShift=true; + private static float hueShiftFloat; + + private static bool saturating; + private static bool maskSaturate=true; + private static float saturationFloat; + + private static bool colorizing; + private static bool maskColorize=true; + private static bool textureColorize; + private static bool alphaColorize; + private static float colorizeFloat=0.5f; + private static Color colorizeColor = Color.black; + private static Texture2D colorizeTexture; + + private static Color originalGUIColor; + + private static TexEncoding encoding = TexEncoding.SaveAsPNG; + public enum TexEncoding + { + SaveAsPNG, + SaveAsJPG, + SaveAsTGA + } + + public enum TexRotation + { + Clockwise90, + CClockwise90, + Rotate180, + FlipHorizontal, + FlipVertical + } + + #region Creating Tab Variables + private static bool creatingCustomSize; + private static bool creatingReverse; + private static string creatingPath; + private static Color solidColor=Color.black; + private static Gradient gradientColor = new Gradient() { colorKeys = new GradientColorKey[] { new GradientColorKey(Color.white, 0), new GradientColorKey(Color.black, 1) } }; + + private static TextureCreatingMode creatingMode = TextureCreatingMode.SolidColor; + + private enum TextureCreatingMode + { + SolidColor, + HorizontalGradient, + VerticalGradient + } + #endregion + + [MenuItem("Poi/Texture Utility")] + private static void showWindow() + { + EditorWindow w = GetWindow<TextureUtility>(false, "Texture Utility", true); + if (!titleTexture) + { + titleTexture = GetColors((Texture2D)EditorGUIUtility.IconContent("Texture2D Icon").image, 16, 16, out _); + titleTexture.Apply(); + } + + w.titleContent.image = titleTexture; + w.minSize = new Vector2(423, 253); + } + + private void OnGUI() + { + originalGUIColor = GUI.backgroundColor; + using (new GUILayout.HorizontalScope()) + { + bool c = editingTab; + + SetColorIcon(editingTab); + editingTab = GUILayout.Toggle(editingTab, "Editing", "toolbarbutton"); + if (!c && editingTab) + { + packingTab = false; + creatingTab = false; + } + + c = creatingTab; + + + SetColorIcon(creatingTab); + creatingTab = GUILayout.Toggle(creatingTab, "Creating", "toolbarbutton"); + if (!c && creatingTab) + { + packingTab = false; + editingTab = false; + } + + c = packingTab; + + SetColorIcon(packingTab); + packingTab = GUILayout.Toggle(packingTab, "Packing", "toolbarbutton"); + if (!c && packingTab) + { + editingTab = false; + creatingTab = false; + } + GUI.backgroundColor = originalGUIColor; + } + + if (editingTab) + { + DrawEditingTab(); + } + + if (creatingTab) + { + DrawCreatingTab(); + } + + if (packingTab) + { + DrawPackingTab(); + } + Credit(); + } + + + private void DrawEditingTab() + { + using (new GUILayout.HorizontalScope()) + { + using (new GUILayout.VerticalScope()) + { + using (new GUILayout.HorizontalScope("box")) + DrawDimensionsGUI(); + + using (new GUILayout.HorizontalScope("box")) + { + encoding = (TexEncoding)EditorGUILayout.EnumPopup(encoding, GUILayout.Width(95)); + + EditorGUI.BeginDisabledGroup(encoding != TexEncoding.SaveAsJPG); + EditorGUIUtility.labelWidth = 50; + jpgQuality = EditorGUILayout.IntSlider("Quality", jpgQuality, 1, 100); + EditorGUIUtility.labelWidth = 0; + EditorGUI.EndDisabledGroup(); + } + + using (new GUILayout.HorizontalScope("box")) + { + copyImport = EditorGUILayout.Toggle("Copy Import Settings", copyImport); + pingTexture = EditorGUILayout.Toggle(new GUIContent("Highlight Texture", "Highlight the newly created texture in Assets"), pingTexture); + } + + using (new GUILayout.HorizontalScope("box")) + { + if (!rotating) + { + SetColorIcon(rotating); + rotating = GUILayout.Toggle(rotating, "Rotate", "toolbarbutton"); + GUI.backgroundColor = originalGUIColor; + } + else + { + SetColorIcon(rotating); + rotating = GUILayout.Toggle(rotating, "", "toolbarbutton", GUILayout.Width(17), GUILayout.Height(17)); + GUI.backgroundColor = originalGUIColor; + + EditorGUI.BeginDisabledGroup(true); + GUILayout.Toggle(true, "M", EditorStyles.miniButton, GUILayout.Width(21), GUILayout.Height(16)); + EditorGUI.EndDisabledGroup(); + + GUILayout.Label("Rotate"); + rotationType = (TexRotation)EditorGUILayout.EnumPopup(GUIContent.none, rotationType); + } + } + + using (new GUILayout.HorizontalScope("box")) + { + if (!inverting) + { + SetColorIcon(inverting); + inverting = GUILayout.Toggle(inverting, "Invert", "toolbarbutton"); + GUI.backgroundColor = originalGUIColor; + } + else + { + SetColorIcon(inverting); + inverting = GUILayout.Toggle(inverting, "", "toolbarbutton", GUILayout.Width(17), GUILayout.Height(17)); + GUI.backgroundColor = originalGUIColor; + + maskInvert = GUILayout.Toggle(maskInvert, new GUIContent("M", "Use Mask"), EditorStyles.miniButton, GUILayout.Width(21), GUILayout.Height(16)); GUILayout.Label("Invert"); + invertRedS = EditorGUILayout.ToggleLeft("R", invertRedS, GUILayout.Width(30)); + invertGreenS = EditorGUILayout.ToggleLeft("G", invertGreenS, GUILayout.Width(30)); + invertBlueS = EditorGUILayout.ToggleLeft("B", invertBlueS, GUILayout.Width(30)); + invertAlphaS = EditorGUILayout.ToggleLeft("A", invertAlphaS, GUILayout.Width(30)); + + } + } + + using (new GUILayout.HorizontalScope("box")) + { + if (!saturating) + { + SetColorIcon(saturating); + saturating = GUILayout.Toggle(saturating, "Saturate", "toolbarbutton"); + GUI.backgroundColor = originalGUIColor; + } + else + { + SetColorIcon(saturating); + saturating = GUILayout.Toggle(saturating, "", "toolbarbutton", GUILayout.Width(17), GUILayout.Height(17)); + GUI.backgroundColor = originalGUIColor; + maskSaturate = GUILayout.Toggle(maskSaturate, new GUIContent("M", "Use Mask"), EditorStyles.miniButton, GUILayout.Width(21), GUILayout.Height(16)); + EditorGUIUtility.labelWidth = 65; + saturationFloat = EditorGUILayout.Slider("Saturate", saturationFloat, -1, 1); + EditorGUIUtility.labelWidth = 0; + } + } + using (new GUILayout.HorizontalScope("box")) + { + if (!hueShifting) + { + SetColorIcon(hueShifting); + hueShifting = GUILayout.Toggle(hueShifting, "Hue Shift", "toolbarbutton"); + GUI.backgroundColor = originalGUIColor; + } + else + { + SetColorIcon(hueShifting); + hueShifting = GUILayout.Toggle(hueShifting, "", "toolbarbutton", GUILayout.Width(17), GUILayout.Height(17)); + GUI.backgroundColor = originalGUIColor; + + maskHueShift = GUILayout.Toggle(maskHueShift, new GUIContent("M", "Use Mask"), EditorStyles.miniButton, GUILayout.Width(21), GUILayout.Height(16)); + EditorGUIUtility.labelWidth = 65; + hueShiftFloat = EditorGUILayout.Slider("Hue Shift", hueShiftFloat, 0, 1); + EditorGUIUtility.labelWidth = 0; + } + } + + using (new GUILayout.HorizontalScope("box")) + { + if (!colorizing) + { + SetColorIcon(colorizing); + colorizing = GUILayout.Toggle(colorizing, "Colorize", "toolbarbutton"); + GUI.backgroundColor = originalGUIColor; + } + else + { + SetColorIcon(colorizing); + colorizing = GUILayout.Toggle(colorizing, "", "toolbarbutton", GUILayout.Width(17), GUILayout.Height(17)); + GUI.backgroundColor = originalGUIColor; + + maskColorize = GUILayout.Toggle(maskColorize, new GUIContent("M", "Use Mask"), EditorStyles.miniButton, GUILayout.Width(21), GUILayout.Height(16)); + EditorGUIUtility.labelWidth = 65; + colorizeFloat = EditorGUILayout.Slider("Colorize", colorizeFloat, 0, 1); + EditorGUIUtility.labelWidth = 0; + if (!textureColorize) + colorizeColor = EditorGUILayout.ColorField(new GUIContent(""), colorizeColor, true, alphaColorize, false, GUILayout.Width(70), GUILayout.Height(17)); + else + colorizeTexture = (Texture2D)EditorGUILayout.ObjectField(colorizeTexture, typeof(Texture2D), false, GUILayout.Width(70), GUILayout.Height(17)); + textureColorize = GUILayout.Toggle(textureColorize, new GUIContent("T", "Use Texture"), EditorStyles.miniButton, GUILayout.Width(19), GUILayout.Height(16)); + alphaColorize = GUILayout.Toggle(alphaColorize, new GUIContent("A", "Use Alpha"), EditorStyles.miniButton, GUILayout.Width(19), GUILayout.Height(16)); + } + } + + } + using (new GUILayout.VerticalScope()) + { + using (new GUILayout.VerticalScope("box")) + { + EditorGUIUtility.labelWidth = 1; + GUILayout.Label("Main", GUILayout.Width(65)); + EditorGUI.BeginChangeCheck(); + mainTexture = (Texture2D)EditorGUILayout.ObjectField("", mainTexture, typeof(Texture2D), false, GUILayout.Width(65)); + if (EditorGUI.EndChangeCheck()) + ResetDimensions(); + EditorGUIUtility.labelWidth = 0; + } + EditorGUI.BeginDisabledGroup(!(hueShifting || saturating || inverting || colorizing)); + using (new GUILayout.VerticalScope("box")) + { + EditorGUIUtility.labelWidth = 1; + GUILayout.Label("Mask", GUILayout.Width(65)); + maskTexture = (Texture2D)EditorGUILayout.ObjectField("", maskTexture, typeof(Texture2D), false, GUILayout.Width(65)); + EditorGUIUtility.labelWidth = 0; + } + EditorGUI.EndDisabledGroup(); + } + } + EditorGUI.BeginDisabledGroup(!mainTexture); + if (GUILayout.Button("Apply")) + { + ApplyTexture(); + } + EditorGUI.EndDisabledGroup(); + } + + private void DrawCreatingTab() + { + using (new GUILayout.HorizontalScope("box")) + { + if (!creatingCustomSize) + { + SetColorIcon(creatingCustomSize); + creatingCustomSize = GUILayout.Toggle(inverting, "Custom Dimensions", "toolbarbutton"); + GUI.backgroundColor = originalGUIColor; + } + else + { + SetColorIcon(creatingCustomSize); + creatingCustomSize = GUILayout.Toggle(creatingCustomSize, "", "toolbarbutton", GUILayout.Width(17), GUILayout.Height(17)); + GUI.backgroundColor = originalGUIColor; + + DrawDimensionsGUI(false); + } + } + + using (new GUILayout.HorizontalScope("box")) + { + encoding = (TexEncoding)EditorGUILayout.EnumPopup(encoding); + + EditorGUI.BeginDisabledGroup(encoding != TexEncoding.SaveAsJPG); + EditorGUIUtility.labelWidth = 50; + jpgQuality = EditorGUILayout.IntSlider("Quality", jpgQuality, 1, 100); + EditorGUIUtility.labelWidth = 0; + EditorGUI.EndDisabledGroup(); + } + + using (new GUILayout.HorizontalScope("box")) + { + pingTexture = EditorGUILayout.Toggle(new GUIContent("Highlight Texture", "Highlight the newly created texture in Assets"), pingTexture); + + EditorGUI.BeginDisabledGroup(creatingMode != TextureCreatingMode.HorizontalGradient && creatingMode != TextureCreatingMode.VerticalGradient); + creatingReverse = EditorGUILayout.Toggle("Reverse Texture", creatingReverse); + EditorGUI.EndDisabledGroup(); + } + + using (new GUILayout.HorizontalScope("box")) + { + creatingMode = (TextureCreatingMode)EditorGUILayout.EnumPopup("Texture Mode", creatingMode); + } + + switch ((int)creatingMode) + { + case 0: + solidColor = EditorGUILayout.ColorField(solidColor); + break; + case 1: + case 2: + gradientColor = EditorGUILayout.GradientField(gradientColor); + break; + } + if (GUILayout.Button("Create")) + { + CreateTexture(); + } + AssetFolderPath(ref creatingPath, "Save To", "TextureUtilityCreatingPath"); + } + + private void DrawPackingTab() + { + + using (new GUILayout.HorizontalScope("box")) + { + encoding = (TexEncoding)EditorGUILayout.EnumPopup(encoding); + EditorGUI.BeginDisabledGroup(encoding != TexEncoding.SaveAsJPG); + EditorGUIUtility.labelWidth = 50; + jpgQuality = EditorGUILayout.IntSlider("Quality", jpgQuality, 1, 100); + EditorGUIUtility.labelWidth = 0; + EditorGUI.EndDisabledGroup(); + } + using (new GUILayout.HorizontalScope("box")) + { + copyImport = EditorGUILayout.Toggle("Copy Import Settings", copyImport); + pingTexture = EditorGUILayout.Toggle(new GUIContent("Highlight Texture", "Highlight the newly created texture in Assets"), pingTexture); + } + using (new GUILayout.HorizontalScope()) + { + bool p = unpacking; + SetColorIcon(unpacking); + unpacking = GUILayout.Toggle(unpacking, "Unpack", "toolbarbutton"); + if (!p && unpacking) + packing = false; + + p = packing; + SetColorIcon(packing); + packing = GUILayout.Toggle(packing, "Pack", "toolbarbutton"); + if (!p && packing) + unpacking = false; + + GUI.backgroundColor = originalGUIColor; + } + if (packing) + { + using (new GUILayout.HorizontalScope()) + { + EditorGUIUtility.labelWidth = 1; + redChannel.DrawGUI(); + greenChannel.DrawGUI(); + blueChannel.DrawGUI(); + alphaChannel.DrawGUI(); + EditorGUIUtility.labelWidth = 0; + } + EditorGUI.BeginDisabledGroup(!channelTextures.Any(c => c.texture)); + if (GUILayout.Button("Pack")) + { + PackTexture(channelTextures); + } + } + if (unpacking) + { + + using (new GUILayout.VerticalScope("box")) + { + using (new GUILayout.HorizontalScope()) + { + GUILayout.FlexibleSpace(); + GUILayout.Label("Main Texture"); + GUILayout.FlexibleSpace(); + } + + using (new GUILayout.HorizontalScope()) + { + GUILayout.FlexibleSpace(); + EditorGUIUtility.labelWidth = 1; + mainTexture = (Texture2D)EditorGUILayout.ObjectField("", mainTexture, typeof(Texture2D), false, GUILayout.Width(66)); + EditorGUIUtility.labelWidth = 0; + GUILayout.FlexibleSpace(); + } + } + EditorGUI.BeginDisabledGroup(!mainTexture); + if (GUILayout.Button("Unpack")) + { + UnpackTexture(); + } + EditorGUI.EndDisabledGroup(); + } + + + EditorGUI.EndDisabledGroup(); + } + + private void DrawDimensionsGUI(bool drawReset=true) + { + GUIStyle iconStyle = new GUIStyle(GUI.skin.label) { padding = new RectOffset(), margin = new RectOffset(), imagePosition = ImagePosition.ImageOnly }; + + EditorGUI.BeginDisabledGroup(!mainTexture && !creatingTab); + if (drawReset) + { + if (GUILayout.Button(resetIcon, iconStyle, GUILayout.Height(16), GUILayout.Width(16))) + ResetDimensions(); + } + EditorGUIUtility.labelWidth = 20; + texWidth = EditorGUILayout.IntField(new GUIContent("W","Width"), texWidth); + texHeight = EditorGUILayout.IntField(new GUIContent("H", "Height"), texHeight); + EditorGUIUtility.labelWidth = 0; + + int dummy = -1; + EditorGUI.BeginChangeCheck(); + dummy = EditorGUILayout.Popup(dummy, DimensionPresets,GUILayout.Width(17)); + if (EditorGUI.EndChangeCheck()) + { + string[] dimensions = ((string)DimensionPresets.GetValue(dummy)).Split('x'); + texWidth = int.Parse(dimensions[0]); + texHeight = int.Parse(dimensions[1]); + } + + EditorGUI.EndDisabledGroup(); + + } + + public static Texture2D GetColors(Texture2D texture, out Color[] Colors, bool unloadTempTexture = false) + { + return GetColors(texture, texture.width, texture.height, out Colors, unloadTempTexture); + } + + public static Texture2D GetColors(Texture2D texture, int width, int height, out Color[] Colors,bool unloadTempTexture = false) + { + //Thanks to + //https://gamedev.stackexchange.com/questions/92285/unity3d-resize-texture-without-corruption + texture.filterMode = FilterMode.Point; + RenderTexture rt = RenderTexture.GetTemporary(width, height); + + rt.filterMode = FilterMode.Point; + RenderTexture.active = rt; + Graphics.Blit(texture, rt); + Texture2D newTexture = new Texture2D(width, height); + newTexture.ReadPixels(new Rect(0, 0, width, height), 0, 0); + Color[] myColors = newTexture.GetPixels(); + RenderTexture.active = null; + ///////////////////// + Colors = myColors; + if (unloadTempTexture) + { + DestroyImmediate(newTexture); + return null; + } + return newTexture; + } + + private static void SaveTexture(byte[] textureEncoding, string path, bool refresh=false, bool ping=false) + { + System.IO.FileStream stream = System.IO.File.Create(path); + stream.Write(textureEncoding, 0, textureEncoding.Length); + stream.Dispose(); + if (refresh) + { + AssetDatabase.Refresh(); + if (ping) + { + Ping(path); + } + } + + } + private static void Ping(string path) + { + EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath<Object>(path)); + } + + private void ApplyTexture() + { + if (colorizing && !colorizeTexture && textureColorize) + { + Debug.LogError("Cannot Colorize using a texture without a texture!"); + return; + } + + string destinationPath = GetDestinationFolder(mainTexture); + string texPath = AssetDatabase.GetAssetPath(mainTexture); + + Texture2D newTexture = GetColors(mainTexture, texWidth, texHeight, out Color[] myColors); + + if (rotating) + { + List<Color> rotatedColors = new List<Color>(); + switch (rotationType) + { + case TexRotation.Clockwise90: + for (int i = texWidth-1; i >=0; i--) + { + rotatedColors.AddRange(newTexture.GetPixels(i, 0, 1, texHeight)); + } + myColors = rotatedColors.ToArray(); + newTexture = new Texture2D(texHeight, texWidth); + break; + + case TexRotation.CClockwise90: + for (int i = 0; i < texWidth; i++) + { + rotatedColors.AddRange(ReverseArray(newTexture.GetPixels(i, 0, 1, texHeight))); + } + myColors = rotatedColors.ToArray(); + newTexture = new Texture2D(texHeight, texWidth); + break; + + case TexRotation.Rotate180: + myColors = ReverseArray(myColors); + break; + + case TexRotation.FlipHorizontal: + for (int i = 0; i < texHeight; i++) + { + rotatedColors.AddRange(ReverseArray(newTexture.GetPixels(0, i, texWidth, 1))); + } + myColors = rotatedColors.ToArray(); + break; + + case TexRotation.FlipVertical: + for (int i = texHeight - 1; i >= 0; i--) + { + rotatedColors.AddRange(newTexture.GetPixels(0, i, texWidth, 1)); + } + myColors = rotatedColors.ToArray(); + break; + } + + } + + bool colorInverting = (invertRedS || invertGreenS || invertBlueS || invertAlphaS) && inverting; + bool HSVEditing = hueShifting || saturating; + bool colorEditing = HSVEditing || colorizing; + bool editing = colorEditing || colorInverting || unpacking; + bool masking = ((maskColorize && colorizing) || (maskInvert && colorInverting) || (maskSaturate && saturating) || (maskHueShift && hueShifting)) && maskTexture; + + Color[] maskColors; + if (masking) + { + GetColors(maskTexture, texWidth, texHeight, out maskColors, true); + } + else + maskColors = null; + + Color[] colorizeTextureColors; + if (colorizing && textureColorize) + { + GetColors(colorizeTexture, texWidth, texHeight, out colorizeTextureColors, true); + } + else + colorizeTextureColors = null; + + + Color[] newColors = new Color[myColors.Length]; + if (editing) + { + for (int i = 0; i < myColors.Length; i++) + { + Color currentColor = myColors[i]; + + if (colorEditing) + { + if (HSVEditing) + { + Color.RGBToHSV(currentColor, out float h, out float s, out float v); + currentColor = Color.HSVToRGB(hueShifting ? (Mathf.Repeat(h + (hueShiftFloat * (maskTexture && maskHueShift ? maskColors[i].r : 1)), 1)) : h, saturating ? (Mathf.Clamp01(s + (saturationFloat * (maskTexture && maskSaturate ? maskColors[i].r : 1)))) : s, v); + currentColor.a = myColors[i].a; + } + if (colorizing) + { + float oga = currentColor.a; + currentColor = Color.Lerp(currentColor, textureColorize ? colorizeTextureColors[i] : colorizeColor, colorizeFloat * (maskColorize && maskTexture ? maskColors[i].r : 1)); + + if (!alphaColorize) + currentColor.a = oga; + } + } + + float r = colorInverting && invertRedS ? currentColor.r - ((currentColor.r - (1 - currentColor.r)) * (maskInvert && maskTexture ? maskColors[i].r : 1)) : currentColor.r; + float g = colorInverting && invertGreenS ? currentColor.g - ((currentColor.g - (1 - currentColor.g)) * (maskInvert && maskTexture ? maskColors[i].g : 1)) : currentColor.g; + float b = colorInverting && invertBlueS ? currentColor.b - ((currentColor.b - (1 - currentColor.b)) * (maskInvert && maskTexture ? maskColors[i].b : 1)) : currentColor.b; + float a = colorInverting && invertAlphaS ? currentColor.a - ((currentColor.a - (1 - currentColor.a)) * (maskInvert && maskTexture ? maskColors[i].a : 1)) : currentColor.a; + + newColors[i] = new Color(r, g, b, a); + } + } + newTexture.SetPixels(editing ? newColors : myColors); + newTexture.Apply(); + + GetEncoding(newTexture, encoding, out byte[] data, out string ext); + + string newTexturePath = AssetDatabase.GenerateUniqueAssetPath(destinationPath + "/" + mainTexture.name + + (colorInverting ? " Inverted" : "") + ext); + + SaveTexture(data, newTexturePath, true, pingTexture); + + if (copyImport) + { + CopyTextureSettings(texPath, newTexturePath); + } + } + + private static void GetEncoding(Texture2D texture, TexEncoding encodingType, out byte[] data, out string ext) + { + switch ((int)encodingType) + { + default: + ext = ".png"; + data = texture.EncodeToPNG(); + break; + case 1: + ext = ".jpg"; + data = texture.EncodeToJPG(jpgQuality); + break; + case 2: + ext = ".tga"; + data = texture.EncodeToTGA(); + break; + } + } + + + private void CreateTexture() + { + Texture2D newTexture = null; + int w = creatingCustomSize ? texWidth : 0; + int h = creatingCustomSize ? texHeight : 0; + + Color[] myColors = null; + switch ((int)creatingMode) + { + case 0: + if (!creatingCustomSize) + { + w = h = 4; + } + newTexture = new Texture2D(w, h); + + myColors = CreateFilledArray(solidColor, w * h); + newTexture.SetPixels(0, 0, w, h, myColors); + break; + case 1: + { + if (!creatingCustomSize) + { + w = 256; + h = 4; + } + newTexture = new Texture2D(w, h); + + int i = creatingReverse ? w - 1 : 0; + int istep = creatingReverse ? -1 : 1; + + float xstepValue = (1f / w); + float xcurrentStep = 0; + for (; i < w && i >= 0; i += istep) + { + newTexture.SetPixels(i, 0, 1, h, CreateFilledArray(gradientColor.Evaluate(xcurrentStep), h)); + xcurrentStep += xstepValue; + } + } + break; + case 2: + { + if (!creatingCustomSize) + { + w = 4; + h = 256; + } + newTexture = new Texture2D(w, h); + + int i = creatingReverse ? h - 1 : 0; + int istep = creatingReverse ? -1 : 1; + + float ystepValue = 1f / h; + float ycurrentStep = 0; + for (; i < h && i >= 0; i += istep) + { + newTexture.SetPixels(0, i, w, 1, CreateFilledArray(gradientColor.Evaluate(ycurrentStep), w)); + ycurrentStep += ystepValue; + } + } + break; + } + + GetEncoding(newTexture, encoding, out byte[] data, out string ext); + + RecreateFolders(creatingPath); + SaveTexture(data, AssetDatabase.GenerateUniqueAssetPath(creatingPath +"/Generated Texture"+ext), true, pingTexture); + } + + private void UnpackTexture() + { + string destinationPath = GetDestinationFolder(mainTexture); + string texPath = AssetDatabase.GetAssetPath(mainTexture); + int x = mainTexture.width, y = mainTexture.height; + Texture2D newTexture = GetColors(mainTexture, x, y, out Color[] myColors); + List<System.Tuple<string, string>> copyFromTo = new List<System.Tuple<string, string>>(); + + bool isRedPass = true, isGreenPass, isBluePass, isAlphaPass; + isGreenPass = isBluePass = isAlphaPass = false; + try + { + AssetDatabase.StartAssetEditing(); + + do + { + Color[] newColors = new Color[myColors.Length]; + + bool hasAlpha = false; + for (int i = 0; i < myColors.Length; i++) + { + Color currentColor = myColors[i]; + + float r = currentColor.r; + float g = currentColor.g; + float b = currentColor.b; + float a = currentColor.a; + + if (isRedPass) + { + g = b = r; + a = 1; + } + if (isGreenPass) + { + r = b = g; + a = 1; + } + if (isBluePass) + { + r = g = b; + a = 1; + } + if (isAlphaPass) + { + r = g = b = a; + if (a != 1) + hasAlpha = true; + } + + newColors[i] = new Color(r, g, b, a); + } + + if (isAlphaPass && !hasAlpha) + { + isAlphaPass = false; + goto Skip; + } + + newTexture.SetPixels(newColors); + newTexture.Apply(); + + GetEncoding(newTexture, encoding, out byte[] data, out string ext); + + string newTexturePath = AssetDatabase.GenerateUniqueAssetPath(destinationPath + "/" + mainTexture.name + + (isRedPass ? "-Red" : isGreenPass ? "-Green" : isBluePass ? "-Blue" : "-Alpha") + ext); + + SaveTexture(data, newTexturePath); + + if (copyImport) + { + copyFromTo.Add(new System.Tuple<string, string>(texPath, newTexturePath)); + } + + if (isAlphaPass) + isAlphaPass = false; + if (isBluePass) + { + isBluePass = false; + isAlphaPass = true; + } + if (isGreenPass) + { + isGreenPass = false; + isBluePass = true; + } + if (isRedPass) + { + isRedPass = false; + isGreenPass = true; + } + + if (unpacking) + newTexture = new Texture2D(x, y); + + Skip:; + + } while (isRedPass || isGreenPass || isBluePass || isAlphaPass); + } + finally + { + AssetDatabase.StopAssetEditing(); + } + AssetDatabase.Refresh(); + if (copyImport) + { + for (int i = 0; i < copyFromTo.Count; i++) + { + CopyTextureSettings(copyFromTo[i].Item1, copyFromTo[i].Item2); + } + } + } + + public void PackTexture(ChannelTexture[] channels) + { + int firstIndex = 0; + for (int i = 3; i >= 0; i--) + { + if (channels[i].texture) + firstIndex = i; + } + ChannelTexture firstChannel = channels[firstIndex]; + int w = firstChannel.texture.width; + int h = firstChannel.texture.height; + PackTexture(channels, AssetDatabase.GetAssetPath(firstChannel.texture), w, h, encoding); + } + + public static string PackTexture(ChannelTexture[] channels, TexEncoding encodingType, bool refresh=true, bool copyImportSettings=true) + { + int firstIndex = -1; + for (int i = 3; i >= 0; i--) + { + if (channels[i].texture) + firstIndex = i; + } + if (firstIndex < 0) + return string.Empty; + ChannelTexture firstChannel = channels[firstIndex]; + int w = firstChannel.texture.width; + int h = firstChannel.texture.height; + return PackTexture(channels, AssetDatabase.GetAssetPath(firstChannel.texture), w, h, encodingType,refresh,false,copyImportSettings); + } + + public static string PackTexture(ChannelTexture[] channels, string destination,int width, int height, TexEncoding encodingType, bool refresh=true,bool overwrite=false, bool copyImportSettings=true) + { + int firstIndex = -1; + for (int i = 3; i >= 0; i--) + { + if (channels[i].texture) + firstIndex = i; + } + if (firstIndex < 0) + return string.Empty; + + ChannelTexture firstChannel = channels[firstIndex]; + + + Texture2D newTexture = new Texture2D(width, height); + channels[0].GetChannelColors(width, height, out float[] reds, true); + channels[1].GetChannelColors(width, height, out float[] greens, true); + channels[2].GetChannelColors(width, height, out float[] blues, true); + channels[3].GetChannelColors(width, height, out float[] alphas, true); + Color[] finalColors = new Color[width*height]; + + for (int i=0;i< finalColors.Length;i++) + { + finalColors[i].r = (reds!=null) ? reds[i] : 0; + finalColors[i].g = (greens != null) ? greens[i] : 0; + finalColors[i].b = (blues != null) ? blues[i] : 0; + finalColors[i].a = (alphas != null) ? alphas[i] : 1; + } + newTexture.SetPixels(finalColors); + newTexture.Apply(); + + GetEncoding(newTexture, encodingType, out byte[] data, out string ext); + + string newTexturePath = GetDestinationFolder(destination)+"/"+System.IO.Path.GetFileNameWithoutExtension(destination)+ext; + if (!overwrite) + newTexturePath = AssetDatabase.GenerateUniqueAssetPath(newTexturePath); + SaveTexture(data, newTexturePath); + DestroyImmediate(newTexture); + if (refresh) + AssetDatabase.Refresh(); + + + if (copyImportSettings) + { + CopyTextureSettings(AssetDatabase.GetAssetPath(firstChannel.texture), newTexturePath); + } + return newTexturePath; + } + + private static void CopyTextureSettings(string from, string to) + { + TextureImporter source = (TextureImporter)AssetImporter.GetAtPath(from); + TextureImporterSettings sourceSettings = new TextureImporterSettings(); + source.ReadTextureSettings(sourceSettings); + + TextureImporter destination = (TextureImporter)AssetImporter.GetAtPath(to); + destination.SetTextureSettings(sourceSettings); + destination.maxTextureSize = source.maxTextureSize; + destination.textureCompression = source.textureCompression; + destination.crunchedCompression = source.crunchedCompression; + destination.SaveAndReimport(); + } + + private static string GetDestinationFolder(Object o) + { + string path = AssetDatabase.GetAssetPath(o); + return GetDestinationFolder(path); + } + private static string GetDestinationFolder(string path) + { + return path.Substring(0, path.LastIndexOf('/')); + } + + private void ResetDimensions() + { + if (mainTexture) + { + texHeight = mainTexture.height; + texWidth = mainTexture.width; + } + } + + private void SetColorIcon(bool value) + { + if (value) + GUI.backgroundColor = Color.green; + else + GUI.backgroundColor = Color.grey; + } + + private void OnEnable() + { + resetIcon = new GUIContent(EditorGUIUtility.IconContent("d_Refresh")) { tooltip = "Reset Dimensions" }; + creatingPath = PlayerPrefs.GetString("TextureUtilityCreatingPath", "Assets/DreadScripts/Texture Utility/Generated Assets"); + + for (int i=0;i<channelTextures.Length;i++) + { + channelTextures[i].SetMode(EditorPrefs.GetInt("TextureUtilityChannel" + channelTextures[i].name, (int)channelTextures[i].mode)); + } + } + + private static T[] CreateFilledArray<T>(T variable,int length) + { + T[] myArray = new T[length]; + for (int i=0;i< myArray.Length;i++) + { + myArray[i] = variable; + } + return myArray; + } + + private static T[] ReverseArray<T>(T[] array) + { + T[] reversed = new T[array.Length]; + int index = array.Length - 1; + for (int i = 0; i < reversed.Length; i++) + { + reversed[i] = array[index]; + index--; + } + return reversed; + } + + #region Extracted From DS_CommonMethods + public static void AssetFolderPath(ref string variable, string title, string playerpref) + { + EditorGUILayout.BeginHorizontal(); + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.TextField(title, variable); + EditorGUI.EndDisabledGroup(); + if (GUILayout.Button("...", GUILayout.Width(30))) + { + string dummyPath = EditorUtility.OpenFolderPanel(title, variable, ""); + if (string.IsNullOrEmpty(dummyPath)) + return; + + if (!dummyPath.Contains("Assets")) + { + Debug.LogWarning("New Path must be a folder within Assets!"); + return; + } + variable = FileUtil.GetProjectRelativePath(dummyPath); + PlayerPrefs.SetString(playerpref, variable); + } + EditorGUILayout.EndHorizontal(); + } + + public static void RecreateFolders(string fullPath) + { + string[] folderNames = fullPath.Split('/'); + string[] folderPaths = new string[folderNames.Length]; + for (int i = 0; i < folderNames.Length; i++) + { + folderPaths[i] = folderNames[0]; + for (int j = 1; j <= i; j++) + { + folderPaths[i] = folderPaths[i] + "/" + folderNames[j]; + } + } + for (int i = 0; i < folderPaths.Length; i++) + { + if (!AssetDatabase.IsValidFolder(folderPaths[i])) + { + AssetDatabase.CreateFolder(folderPaths[i].Substring(0, folderPaths[i].LastIndexOf('/')), folderPaths[i].Substring(folderPaths[i].LastIndexOf('/') + 1, folderPaths[i].Length - folderPaths[i].LastIndexOf('/') - 1)); + } + + } + } + #endregion + + private static void Credit() + { + GUIStyle creditLabelStyle = new GUIStyle(GUI.skin.label) { richText = true }; + using (new GUILayout.HorizontalScope()) + { + GUILayout.FlexibleSpace(); + if (GUILayout.Button("<b>Made by Dreadrith#3238</b>",creditLabelStyle)) + { + Application.OpenURL("https://github.com/Dreadrith/DreadScripts"); + } + + } + } + } + + [System.Serializable] + public class ChannelTexture + { + public string name; + public Texture2D texture; + public bool invert; + public ColorMode mode = ColorMode.Red; + public enum ColorMode + { + Red, + Green, + Blue, + Alpha + } + public ChannelTexture(string n, int mode) + { + name = n; + SetMode(mode, true); + } + + public void SetMode(int i, bool ignoreSave = false) + { + switch (i) + { + case 0: + mode = ColorMode.Red; + break; + case 1: + mode = ColorMode.Green; + break; + case 2: + mode = ColorMode.Blue; + break; + case 3: + mode = ColorMode.Alpha; + break; + } + if (!ignoreSave) + { + EditorPrefs.SetInt("TextureUtilityChannel" + name, i); + } + } + + public Texture2D GetChannelColors(int width, int height, out float[] colors, bool unloadTempTexture) + { + if (!texture) + { + colors = null; + return null; + } + else + { + Texture2D newTexture = TextureUtility.GetColors(texture, width, height, out Color[] myColors, unloadTempTexture); + colors = myColors.Select(c => + { + if (mode == ColorMode.Red) + return c.r; + if (mode == ColorMode.Green) + return c.g; + if (mode == ColorMode.Blue) + return c.b; + + return c.a; + }).ToArray(); + if (invert) + { + for (int i = 0; i < colors.Length; i++) + { + colors[i] = 1 - colors[i]; + } + } + return newTexture; + } + } + + public void DrawGUI() + { + GUIStyle buttonGroupStyle = new GUIStyle(GUI.skin.GetStyle("toolbarbutton")) { padding = new RectOffset(1, 1, 1, 1), margin = new RectOffset(0, 0, 1, 1) }; + using (new GUILayout.VerticalScope("box")) + { + using (new GUILayout.HorizontalScope()) + { + GUILayout.FlexibleSpace(); + GUILayout.Label(name, "boldlabel"); + GUILayout.FlexibleSpace(); + } + using (new GUILayout.HorizontalScope()) + { + GUILayout.FlexibleSpace(); + bool dummy; + EditorGUI.BeginChangeCheck(); + dummy = GUILayout.Toggle(mode == ColorMode.Red, "R", buttonGroupStyle, GUILayout.Width(16)); + if (EditorGUI.EndChangeCheck()) + if (dummy) + SetMode(0); + + EditorGUI.BeginChangeCheck(); + dummy = GUILayout.Toggle(mode == ColorMode.Green, "G", buttonGroupStyle, GUILayout.Width(16)); + if (EditorGUI.EndChangeCheck()) + if (dummy) + SetMode(1); + + EditorGUI.BeginChangeCheck(); + dummy = GUILayout.Toggle(mode == ColorMode.Blue, "B", buttonGroupStyle, GUILayout.Width(16)); + if (EditorGUI.EndChangeCheck()) + if (dummy) + SetMode(2); + + EditorGUI.BeginChangeCheck(); + dummy = GUILayout.Toggle(mode == ColorMode.Alpha, "A", buttonGroupStyle, GUILayout.Width(16)); + if (EditorGUI.EndChangeCheck()) + if (dummy) + SetMode(3); + GUILayout.FlexibleSpace(); + } + using (new GUILayout.HorizontalScope()) + { + GUILayout.FlexibleSpace(); + texture = (Texture2D)EditorGUILayout.ObjectField("", texture, typeof(Texture2D), false, GUILayout.Width(66)); + GUILayout.FlexibleSpace(); + } + invert = GUILayout.Toggle(invert, "Invert", "toolbarbutton"); + } + } + + + } +}
\ No newline at end of file diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/TextureUtility.cs.meta b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/TextureUtility.cs.meta new file mode 100644 index 00000000..8752585e --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Editor/TextureUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cb8d94d5a72732e4b8b754b8138f95d8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources.meta b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources.meta new file mode 100644 index 00000000..604e4ea7 --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 362826441ef464c458314d76942a2c67 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi.meta b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi.meta new file mode 100644 index 00000000..903cc2d6 --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2526eb19e2b785f43934a75ebbdfb35e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/ModularShadersGeneratorStyle.uss b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/ModularShadersGeneratorStyle.uss new file mode 100644 index 00000000..a1df90f1 --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/ModularShadersGeneratorStyle.uss @@ -0,0 +1,26 @@ +.error +{ + background-image: resource("CollabError"); + margin-top: 2px; + margin-left: 6px; + height: 12px; + width: 12px; +} + +.buttons-area +{ + flex-direction: row; + margin-bottom: 10px; +} + +.folder-selector +{ + flex-direction: row; + margin-top: 10px; + margin-left: 4px; +} + +ModularShadersGeneratorElement +{ + margin-left: 4px; +}
\ No newline at end of file diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/ModularShadersGeneratorStyle.uss.meta b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/ModularShadersGeneratorStyle.uss.meta new file mode 100644 index 00000000..36d9b656 --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/ModularShadersGeneratorStyle.uss.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a77a12c151c44847b8de5c6c7be71d8e +timeCreated: 1638406657
\ No newline at end of file diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/PoiTexturePacker.shader b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/PoiTexturePacker.shader new file mode 100644 index 00000000..2f366a9e --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/PoiTexturePacker.shader @@ -0,0 +1,169 @@ +// Made with Amplify Shader Editor +// Available at the Unity Asset Store - http://u3d.as/y3X +Shader "Hidden/Poi/TexturePacker" +{ + Properties + { + _Invert_Red("Invert_Red", Float) = 0 + _Invert_Green("Invert_Green", Float) = 0 + _Invert_Blue("Invert_Blue", Float) = 0 + _Invert_Alpha("Invert_Alpha", Float) = 0 + _Red("Red", 2D) = "white" {} + _Green("Green", 2D) = "white" {} + _Blue("Blue", 2D) = "white" {} + _Alpha("Alpha", 2D) = "white" {} + [HideInInspector] _texcoord( "", 2D ) = "white" {} + } + + SubShader + { + Tags { "RenderType"="Opaque" } + LOD 100 + CGINCLUDE + #pragma target 3.0 + ENDCG + Blend Off + Cull Back + ColorMask RGBA + ZWrite On + ZTest LEqual + Offset 0 , 0 + + + + Pass + { + Name "Unlit" + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma multi_compile_instancing + #include "UnityCG.cginc" + + + struct appdata + { + float4 vertex : POSITION; + UNITY_VERTEX_INPUT_INSTANCE_ID + float4 ase_texcoord : TEXCOORD0; + }; + + struct v2f + { + float4 vertex : SV_POSITION; + float4 ase_texcoord : TEXCOORD0; + UNITY_VERTEX_OUTPUT_STEREO + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + uniform sampler2D _Red; + uniform float4 _Red_ST; + uniform float _Invert_Red; + uniform sampler2D _Green; + uniform float4 _Green_ST; + uniform float _Invert_Green; + uniform sampler2D _Blue; + uniform float4 _Blue_ST; + uniform float _Invert_Blue; + uniform sampler2D _Alpha; + uniform float4 _Alpha_ST; + uniform float _Invert_Alpha; + + v2f vert ( appdata v ) + { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + UNITY_TRANSFER_INSTANCE_ID(v, o); + + o.ase_texcoord.xy = v.ase_texcoord.xy; + + //setting value to unused interpolator channels and avoid initialization warnings + o.ase_texcoord.zw = 0; + + v.vertex.xyz += float3(0,0,0) ; + o.vertex = UnityObjectToClipPos(v.vertex); + return o; + } + + fixed4 frag (v2f i ) : SV_Target + { + UNITY_SETUP_INSTANCE_ID(i); + fixed4 finalColor; + float2 uv_Red = i.ase_texcoord.xy * _Red_ST.xy + _Red_ST.zw; + float4 tex2DNode28 = tex2D( _Red, uv_Red ); + float4 temp_cast_0 = (_Invert_Red).xxxx; + float4 lerpResult27 = lerp( tex2DNode28 , ( temp_cast_0 - tex2DNode28 ) , _Invert_Red); + float2 uv_Green = i.ase_texcoord.xy * _Green_ST.xy + _Green_ST.zw; + float4 tex2DNode12 = tex2D( _Green, uv_Green ); + float4 temp_cast_2 = (_Invert_Green).xxxx; + float4 lerpResult20 = lerp( tex2DNode12 , ( temp_cast_2 - tex2DNode12 ) , _Invert_Green); + float2 uv_Blue = i.ase_texcoord.xy * _Blue_ST.xy + _Blue_ST.zw; + float4 tex2DNode14 = tex2D( _Blue, uv_Blue ); + float4 temp_cast_4 = (_Invert_Blue).xxxx; + float4 lerpResult21 = lerp( tex2DNode14 , ( temp_cast_4 - tex2DNode14 ) , _Invert_Blue); + float2 uv_Alpha = i.ase_texcoord.xy * _Alpha_ST.xy + _Alpha_ST.zw; + float4 tex2DNode13 = tex2D( _Alpha, uv_Alpha ); + float4 temp_cast_6 = (_Invert_Alpha).xxxx; + float4 lerpResult19 = lerp( tex2DNode13 , ( temp_cast_6 - tex2DNode13 ) , _Invert_Alpha); + float4 appendResult30 = (float4(lerpResult27.r , lerpResult20.r , lerpResult21.r , lerpResult19.r)); + + + finalColor = appendResult30; + return finalColor; + } + ENDCG + } + } + CustomEditor "ASEMaterialInspector" + + +} +/*ASEBEGIN +Version=15902 +0;0;1368;850;1368.399;595.2781;1;True;False +Node;AmplifyShaderEditor.SamplerNode;14;-1193.289,314.7757;Float;True;Property;_Blue;Blue;6;0;Create;True;0;0;False;0;None;None;True;0;False;white;Auto;False;Object;-1;Auto;Texture2D;6;0;SAMPLER2D;;False;1;FLOAT2;0,0;False;2;FLOAT;0;False;3;FLOAT2;0,0;False;4;FLOAT2;0,0;False;5;FLOAT;1;False;5;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4 +Node;AmplifyShaderEditor.RangedFloatNode;25;-815.7044,759.9294;Float;False;Property;_Invert_Alpha;Invert_Alpha;3;0;Create;True;0;0;False;0;0;0;0;0;0;1;FLOAT;0 +Node;AmplifyShaderEditor.RangedFloatNode;15;-819.5868,472.4816;Float;False;Property;_Invert_Blue;Invert_Blue;2;0;Create;True;0;0;False;0;0;0;0;0;0;1;FLOAT;0 +Node;AmplifyShaderEditor.RangedFloatNode;31;-803.4256,177.2413;Float;False;Property;_Invert_Green;Invert_Green;1;0;Create;True;0;0;False;0;0;0;0;0;0;1;FLOAT;0 +Node;AmplifyShaderEditor.RangedFloatNode;29;-795.8423,-109.6157;Float;False;Property;_Invert_Red;Invert_Red;0;0;Create;True;0;0;False;0;0;0;0;0;0;1;FLOAT;0 +Node;AmplifyShaderEditor.SamplerNode;28;-1189.017,-285.634;Float;True;Property;_Red;Red;4;0;Create;True;0;0;False;0;None;None;True;0;False;white;Auto;False;Object;-1;Auto;Texture2D;6;0;SAMPLER2D;;False;1;FLOAT2;0,0;False;2;FLOAT;0;False;3;FLOAT2;0,0;False;4;FLOAT2;0,0;False;5;FLOAT;1;False;5;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4 +Node;AmplifyShaderEditor.SamplerNode;12;-1199.358,5.317238;Float;True;Property;_Green;Green;5;0;Create;True;0;0;False;0;None;None;True;0;False;white;Auto;False;Object;-1;Auto;Texture2D;6;0;SAMPLER2D;;False;1;FLOAT2;0,0;False;2;FLOAT;0;False;3;FLOAT2;0,0;False;4;FLOAT2;0,0;False;5;FLOAT;1;False;5;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4 +Node;AmplifyShaderEditor.SamplerNode;13;-1182.523,665.4475;Float;True;Property;_Alpha;Alpha;7;0;Create;True;0;0;False;0;None;None;True;0;False;white;Auto;False;Object;-1;Auto;Texture2D;6;0;SAMPLER2D;;False;1;FLOAT2;0,0;False;2;FLOAT;0;False;3;FLOAT2;0,0;False;4;FLOAT2;0,0;False;5;FLOAT;1;False;5;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4 +Node;AmplifyShaderEditor.SimpleSubtractOpNode;16;-610.2974,-218.5994;Float;False;2;0;FLOAT;0;False;1;COLOR;0,0,0,0;False;1;COLOR;0 +Node;AmplifyShaderEditor.SimpleSubtractOpNode;26;-570.7031,710.9296;Float;False;2;0;FLOAT;0;False;1;COLOR;0,0,0,0;False;1;COLOR;0 +Node;AmplifyShaderEditor.SimpleSubtractOpNode;17;-612.9231,67.14128;Float;False;2;0;FLOAT;0;False;1;COLOR;0,0,0,0;False;1;COLOR;0 +Node;AmplifyShaderEditor.SimpleSubtractOpNode;18;-589.0041,392.5837;Float;False;2;0;FLOAT;0;False;1;COLOR;0,0,0,0;False;1;COLOR;0 +Node;AmplifyShaderEditor.LerpOp;19;-279.5903,619.9736;Float;False;3;0;COLOR;0,0,0,0;False;1;COLOR;0,0,0,0;False;2;FLOAT;0;False;1;COLOR;0 +Node;AmplifyShaderEditor.LerpOp;27;-318.2486,-275.2707;Float;False;3;0;COLOR;0,0,0,0;False;1;COLOR;0,0,0,0;False;2;FLOAT;0;False;1;COLOR;0 +Node;AmplifyShaderEditor.LerpOp;20;-299.71,16.80488;Float;False;3;0;COLOR;0,0,0,0;False;1;COLOR;0,0,0,0;False;2;FLOAT;0;False;1;COLOR;0 +Node;AmplifyShaderEditor.LerpOp;21;-296.069,300.6409;Float;False;3;0;COLOR;0,0,0,0;False;1;COLOR;0,0,0,0;False;2;FLOAT;0;False;1;COLOR;0 +Node;AmplifyShaderEditor.DynamicAppendNode;30;98.28339,102.1202;Float;False;FLOAT4;4;0;FLOAT;0;False;1;FLOAT;0;False;2;FLOAT;0;False;3;FLOAT;0;False;1;FLOAT4;0 +Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;0;369.802,98.57185;Float;False;True;2;Float;ASEMaterialInspector;0;1;Hidden/Poi/TexturePacker;0770190933193b94aaa3065e307002fa;0;0;Unlit;2;True;0;1;False;-1;0;False;-1;0;1;False;-1;0;False;-1;True;0;False;-1;0;False;-1;True;0;False;-1;True;True;True;True;True;0;False;-1;True;False;255;False;-1;255;False;-1;255;False;-1;7;False;-1;1;False;-1;1;False;-1;1;False;-1;7;False;-1;1;False;-1;1;False;-1;1;False;-1;True;1;False;-1;True;3;False;-1;True;True;0;False;-1;0;False;-1;True;1;RenderType=Opaque=RenderType;True;2;0;False;False;False;False;False;False;False;False;False;False;0;;0;0;Standard;0;2;0;FLOAT4;0,0,0,0;False;1;FLOAT3;0,0,0;False;0 +WireConnection;16;0;29;0 +WireConnection;16;1;28;0 +WireConnection;26;0;25;0 +WireConnection;26;1;13;0 +WireConnection;17;0;31;0 +WireConnection;17;1;12;0 +WireConnection;18;0;15;0 +WireConnection;18;1;14;0 +WireConnection;19;0;13;0 +WireConnection;19;1;26;0 +WireConnection;19;2;25;0 +WireConnection;27;0;28;0 +WireConnection;27;1;16;0 +WireConnection;27;2;29;0 +WireConnection;20;0;12;0 +WireConnection;20;1;17;0 +WireConnection;20;2;31;0 +WireConnection;21;0;14;0 +WireConnection;21;1;18;0 +WireConnection;21;2;15;0 +WireConnection;30;0;27;0 +WireConnection;30;1;20;0 +WireConnection;30;2;21;0 +WireConnection;30;3;19;0 +WireConnection;0;0;30;0 +ASEEND*/ +//CHKSM=2C30DB01285F07958B9316BD81CB0A64AD7E3B0E
\ No newline at end of file diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/PoiTexturePacker.shader.meta b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/PoiTexturePacker.shader.meta new file mode 100644 index 00000000..1658d888 --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/PoiTexturePacker.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 71129bd3774e04d48827a25fc98d45a7 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/PoiTextureUnpacker.shader b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/PoiTextureUnpacker.shader new file mode 100644 index 00000000..736465be --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/PoiTextureUnpacker.shader @@ -0,0 +1,156 @@ +// Made with Amplify Shader Editor +// Available at the Unity Asset Store - http://u3d.as/y3X +Shader "Hidden/Poi/TextureUnpacker" +{ + Properties + { + _MainTex("MainTex", 2D) = "white" {} + _Mode("Mode", Range( 0 , 3)) = 3 + _Invert("Invert", Float) = 0 + [HideInInspector] _texcoord( "", 2D ) = "white" {} + } + + SubShader + { + Tags { "RenderType"="Opaque" } + LOD 100 + CGINCLUDE + #pragma target 3.0 + ENDCG + Blend Off + Cull Back + ColorMask RGBA + ZWrite On + ZTest LEqual + Offset 0 , 0 + + + + Pass + { + Name "Unlit" + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma multi_compile_instancing + #include "UnityCG.cginc" + + + struct appdata + { + float4 vertex : POSITION; + UNITY_VERTEX_INPUT_INSTANCE_ID + float4 ase_texcoord : TEXCOORD0; + }; + + struct v2f + { + float4 vertex : SV_POSITION; + float4 ase_texcoord : TEXCOORD0; + UNITY_VERTEX_OUTPUT_STEREO + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + uniform float _Mode; + uniform sampler2D _MainTex; + uniform float4 _MainTex_ST; + uniform float _Invert; + + v2f vert ( appdata v ) + { + v2f o; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + UNITY_TRANSFER_INSTANCE_ID(v, o); + + o.ase_texcoord.xy = v.ase_texcoord.xy; + + //setting value to unused interpolator channels and avoid initialization warnings + o.ase_texcoord.zw = 0; + + v.vertex.xyz += float3(0,0,0) ; + o.vertex = UnityObjectToClipPos(v.vertex); + return o; + } + + fixed4 frag (v2f i ) : SV_Target + { + UNITY_SETUP_INSTANCE_ID(i); + fixed4 finalColor; + float2 uv_MainTex = i.ase_texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw; + float4 tex2DNode32 = tex2D( _MainTex, uv_MainTex ); + float ifLocalVar34 = 0; + if( _Mode == 0.0 ) + ifLocalVar34 = tex2DNode32.r; + float ifLocalVar35 = 0; + if( _Mode == 1.0 ) + ifLocalVar35 = tex2DNode32.g; + float ifLocalVar36 = 0; + if( _Mode == 2.0 ) + ifLocalVar36 = tex2DNode32.b; + float ifLocalVar37 = 0; + if( _Mode == 3.0 ) + ifLocalVar37 = tex2DNode32.a; + float4 ifLocalVar42 = 0; + if( _Mode < 0.0 ) + ifLocalVar42 = tex2DNode32; + float4 ifLocalVar43 = 0; + if( _Mode > 3.0 ) + ifLocalVar43 = tex2DNode32; + float4 temp_output_40_0 = ( ifLocalVar34 + ifLocalVar35 + ifLocalVar36 + ifLocalVar37 + ifLocalVar42 + ifLocalVar43 ); + float4 temp_cast_0 = (_Invert).xxxx; + float4 lerpResult46 = lerp( temp_output_40_0 , ( temp_cast_0 - temp_output_40_0 ) , _Invert); + + + finalColor = lerpResult46; + return finalColor; + } + ENDCG + } + } + CustomEditor "ASEMaterialInspector" + + +} +/*ASEBEGIN +Version=15902 +0;0;1368;850;930.0129;673.0209;1.753676;True;False +Node;AmplifyShaderEditor.SamplerNode;32;-446.011,1.547681;Float;True;Property;_MainTex;MainTex;0;0;Create;True;0;0;False;0;None;None;True;0;False;white;Auto;False;Object;-1;Auto;Texture2D;6;0;SAMPLER2D;;False;1;FLOAT2;0,0;False;2;FLOAT;0;False;3;FLOAT2;0,0;False;4;FLOAT2;0,0;False;5;FLOAT;1;False;5;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4 +Node;AmplifyShaderEditor.RangedFloatNode;33;-414.2798,-86.22936;Float;False;Property;_Mode;Mode;1;0;Create;True;0;0;False;0;3;0;0;3;0;1;FLOAT;0 +Node;AmplifyShaderEditor.ConditionalIfNode;35;17.04439,123.3313;Float;False;False;5;0;FLOAT;0;False;1;FLOAT;1;False;2;FLOAT;0;False;3;FLOAT;0;False;4;FLOAT;0;False;1;FLOAT;0 +Node;AmplifyShaderEditor.ConditionalIfNode;36;17.16646,287.5046;Float;False;False;5;0;FLOAT;0;False;1;FLOAT;2;False;2;FLOAT;0;False;3;FLOAT;0;False;4;FLOAT;0;False;1;FLOAT;0 +Node;AmplifyShaderEditor.ConditionalIfNode;37;15.75801,456.534;Float;False;False;5;0;FLOAT;0;False;1;FLOAT;3;False;2;FLOAT;0;False;3;FLOAT;0;False;4;FLOAT;0;False;1;FLOAT;0 +Node;AmplifyShaderEditor.ConditionalIfNode;34;17.15299,-44.90865;Float;False;False;5;0;FLOAT;0;False;1;FLOAT;0;False;2;FLOAT;0;False;3;FLOAT;0;False;4;FLOAT;0;False;1;FLOAT;0 +Node;AmplifyShaderEditor.ConditionalIfNode;42;19.07808,-276.4948;Float;False;False;5;0;FLOAT;0;False;1;FLOAT;0;False;2;FLOAT;0;False;3;FLOAT;0;False;4;COLOR;0,0,0,0;False;1;COLOR;0 +Node;AmplifyShaderEditor.ConditionalIfNode;43;19.07608,697.2275;Float;False;False;5;0;FLOAT;0;False;1;FLOAT;3;False;2;COLOR;0,0,0,0;False;3;FLOAT;0;False;4;COLOR;0,0,0,0;False;1;COLOR;0 +Node;AmplifyShaderEditor.SimpleAddOpNode;40;370.6085,1.924235;Float;True;6;6;0;FLOAT;0;False;1;FLOAT;0;False;2;FLOAT;0;False;3;FLOAT;0;False;4;COLOR;0,0,0,0;False;5;COLOR;0,0,0,0;False;1;COLOR;0 +Node;AmplifyShaderEditor.RangedFloatNode;44;440.5474,232.555;Float;False;Property;_Invert;Invert;2;0;Create;True;0;0;False;0;0;0;0;0;0;1;FLOAT;0 +Node;AmplifyShaderEditor.SimpleSubtractOpNode;45;609.8499,63.25506;Float;False;2;0;FLOAT;0;False;1;COLOR;0,0,0,0;False;1;COLOR;0 +Node;AmplifyShaderEditor.LerpOp;46;780.463,-0.6814048;Float;False;3;0;COLOR;0,0,0,0;False;1;COLOR;0,0,0,0;False;2;FLOAT;0;False;1;COLOR;0 +Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;0;975.2405,-1.718735;Float;False;True;2;Float;ASEMaterialInspector;0;1;Hidden/Poi/TextureUnpacker;0770190933193b94aaa3065e307002fa;0;0;Unlit;2;True;0;1;False;-1;0;False;-1;0;1;False;-1;0;False;-1;True;0;False;-1;0;False;-1;True;0;False;-1;True;True;True;True;True;0;False;-1;True;False;255;False;-1;255;False;-1;255;False;-1;7;False;-1;1;False;-1;1;False;-1;1;False;-1;7;False;-1;1;False;-1;1;False;-1;1;False;-1;True;1;False;-1;True;3;False;-1;True;True;0;False;-1;0;False;-1;True;1;RenderType=Opaque=RenderType;True;2;0;False;False;False;False;False;False;False;False;False;False;0;;0;0;Standard;0;2;0;FLOAT4;0,0,0,0;False;1;FLOAT3;0,0,0;False;0 +WireConnection;35;0;33;0 +WireConnection;35;3;32;2 +WireConnection;36;0;33;0 +WireConnection;36;3;32;3 +WireConnection;37;0;33;0 +WireConnection;37;3;32;4 +WireConnection;34;0;33;0 +WireConnection;34;3;32;1 +WireConnection;42;0;33;0 +WireConnection;42;4;32;0 +WireConnection;43;0;33;0 +WireConnection;43;2;32;0 +WireConnection;40;0;34;0 +WireConnection;40;1;35;0 +WireConnection;40;2;36;0 +WireConnection;40;3;37;0 +WireConnection;40;4;42;0 +WireConnection;40;5;43;0 +WireConnection;45;0;44;0 +WireConnection;45;1;40;0 +WireConnection;46;0;40;0 +WireConnection;46;1;45;0 +WireConnection;46;2;44;0 +WireConnection;0;0;46;0 +ASEEND*/ +//CHKSM=FB476DC839C9D986CDFBE64BF68940FC3E2666AE
\ No newline at end of file diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/PoiTextureUnpacker.shader.meta b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/PoiTextureUnpacker.shader.meta new file mode 100644 index 00000000..d7c2c86d --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/PoiTextureUnpacker.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 245e67c21ccaa9a43ad7e84d1c7bb5fc +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/icon_link.png b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/icon_link.png Binary files differnew file mode 100755 index 00000000..f2221935 --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/icon_link.png diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/icon_link.png.meta b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/icon_link.png.meta new file mode 100644 index 00000000..2534f427 --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/icon_link.png.meta @@ -0,0 +1,99 @@ +fileFormatVersion: 2 +guid: bf576c4a5c9c7d6408d714bfc0779a3f +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 9 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/icon_link_pro.png b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/icon_link_pro.png Binary files differnew file mode 100755 index 00000000..c6454537 --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/icon_link_pro.png diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/icon_link_pro.png.meta b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/icon_link_pro.png.meta new file mode 100644 index 00000000..1c244949 --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/poi-tools/Resources/Poi/icon_link_pro.png.meta @@ -0,0 +1,99 @@ +fileFormatVersion: 2 +guid: e5afc9f6ee88c964cbc59accc832fbbe +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 9 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: |