diff options
| author | yum <yum.food.vr@gmail.com> | 2025-02-01 19:15:58 -0800 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2025-02-01 19:15:58 -0800 |
| commit | fb26b02a20ef751cdd1832abc925b5e57bb2234b (patch) | |
| tree | 265f343a4b57e6345468ff5c37902fdd66a3764e | |
| parent | 4bd9c2ba494013f292ddc14d793bc2b362aff365 (diff) | |
Implement surface stable fractal dithering
27 files changed, 1471 insertions, 1 deletions
diff --git a/Editor/stack_2d_noise_to_3d.cs b/Editor/stack_2d_noise_to_3d.cs new file mode 100644 index 0000000..adc2773 --- /dev/null +++ b/Editor/stack_2d_noise_to_3d.cs @@ -0,0 +1,120 @@ +using UnityEngine;
+using UnityEditor;
+using System.Collections.Generic;
+
+public class ImageSequenceToTexture3D : EditorWindow
+{
+ private List<Texture2D> sourceImages = new List<Texture2D>();
+ private string textureName = "Texture3DFromSequence";
+ private FilterMode filterMode = FilterMode.Bilinear;
+ private TextureWrapMode wrapMode = TextureWrapMode.Repeat;
+
+ [MenuItem("Tools/yum_food/Image Sequence to Texture3D")]
+ public static void ShowWindow()
+ {
+ GetWindow<ImageSequenceToTexture3D>("Image Sequence to Texture3D");
+ }
+
+ private void OnGUI()
+ {
+ GUILayout.Label("Image Sequence to Texture3D Converter", EditorStyles.boldLabel);
+ EditorGUILayout.HelpBox("Add images in the order they should appear in the Z-axis", MessageType.Info);
+
+ // Image sequence management
+ EditorGUILayout.LabelField("Source Images", EditorStyles.boldLabel);
+ for (int i = 0; i < sourceImages.Count; i++)
+ {
+ EditorGUILayout.BeginHorizontal();
+ sourceImages[i] = (Texture2D)EditorGUILayout.ObjectField($"Slice {i}", sourceImages[i], typeof(Texture2D), false);
+ if (GUILayout.Button("Remove", GUILayout.Width(60)))
+ {
+ sourceImages.RemoveAt(i);
+ GUILayout.EndHorizontal();
+ break;
+ }
+ EditorGUILayout.EndHorizontal();
+ }
+
+ if (GUILayout.Button("Add Image Slot"))
+ {
+ sourceImages.Add(null);
+ }
+
+ textureName = EditorGUILayout.TextField("Texture Name", textureName);
+ filterMode = (FilterMode)EditorGUILayout.EnumPopup("Filter Mode", filterMode);
+ wrapMode = (TextureWrapMode)EditorGUILayout.EnumPopup("Wrap Mode", wrapMode);
+
+ if (GUILayout.Button("Generate 3D Texture"))
+ {
+ if (ValidateInputs())
+ {
+ Generate3DTexture();
+ }
+ }
+ }
+
+ private bool ValidateInputs()
+ {
+ if (sourceImages.Count == 0)
+ {
+ EditorUtility.DisplayDialog("Error", "Please add at least one image.", "OK");
+ return false;
+ }
+
+ if (sourceImages.Contains(null))
+ {
+ EditorUtility.DisplayDialog("Error", "Please assign all image slots.", "OK");
+ return false;
+ }
+
+ // Verify all images have the same dimensions
+ int width = sourceImages[0].width;
+ int height = sourceImages[0].height;
+
+ for (int i = 1; i < sourceImages.Count; i++)
+ {
+ if (sourceImages[i].width != width || sourceImages[i].height != height)
+ {
+ EditorUtility.DisplayDialog("Error",
+ $"All images must have the same dimensions. Expected {width}x{height}, but image {i} is {sourceImages[i].width}x{sourceImages[i].height}",
+ "OK");
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private void Generate3DTexture()
+ {
+ int width = sourceImages[0].width;
+ int height = sourceImages[0].height;
+ int depth = sourceImages.Count;
+
+ // Create the 3D texture
+ Texture3D texture3D = new Texture3D(width, height, depth, TextureFormat.RGBA32, false);
+ texture3D.filterMode = filterMode;
+ texture3D.wrapMode = wrapMode;
+
+ // Prepare the color array
+ Color[] colors = new Color[width * height * depth];
+
+ // Copy the pixel data from each source image
+ for (int z = 0; z < depth; z++)
+ {
+ Color[] imageColors = sourceImages[z].GetPixels();
+ System.Array.Copy(imageColors, 0, colors, z * width * height, width * height);
+ }
+
+ texture3D.SetPixels(colors);
+ texture3D.Apply();
+
+ // Save the texture asset
+ string path = $"Assets/{textureName}.asset";
+ AssetDatabase.CreateAsset(texture3D, path);
+ AssetDatabase.SaveAssets();
+ AssetDatabase.Refresh();
+
+ EditorUtility.DisplayDialog("Success", $"3D texture generated and saved at {path}", "OK");
+ }
+}
diff --git a/Editor/tooner.cs b/Editor/tooner.cs index fab06e0..c7d89d4 100644 --- a/Editor/tooner.cs +++ b/Editor/tooner.cs @@ -3236,6 +3236,33 @@ public class ToonerGUI : ShaderGUI { EditorGUI.indentLevel -= 1; } + void DoSurfaceStableFractalDithering() { + MaterialProperty bc; + + bc = FindProperty("_Surface_Stable_Fractal_Dithering_Enable_Static"); + bool enabled = (bc.floatValue != 0.0); + EditorGUI.BeginChangeCheck(); + enabled = Toggle("Stable fractal dithering", enabled); + EditorGUI.EndChangeCheck(); + bc.floatValue = enabled ? 1.0f : 0.0f; + SetKeyword("_SURFACE_STABLE_FRACTAL_DITHERING", enabled); + + if (!enabled) { + return; + } + + EditorGUI.indentLevel += 1; + + bc = FindProperty("_Surface_Stable_Fractal_Dithering_Noise"); + TexturePropertySingleLine(MakeLabel(bc, "Noise"), bc); + bc = FindProperty("_Surface_Stable_Fractal_Dithering_Scale"); + FloatProperty(bc, "Scale"); + bc = FindProperty("_Surface_Stable_Fractal_Dithering_Max_Fwidth"); + FloatProperty(bc, "Max fwidth"); + + EditorGUI.indentLevel -= 1; + } + void DoGimmicks() { show_ui.Add(AddCollapsibleMenu("Gimmicks", "_Gimmicks")); EditorGUI.indentLevel += 1; @@ -3269,6 +3296,7 @@ public class ToonerGUI : ShaderGUI { DoGeoScroll(); DoGimmickEpilepsyMode(); DoLens00(); + DoSurfaceStableFractalDithering(); EditorGUI.indentLevel -= 1; show_ui.RemoveAt(show_ui.Count - 1); diff --git a/Textures/SSFD_2x2/README.md b/Textures/SSFD_2x2/README.md new file mode 100644 index 0000000..2c17d37 --- /dev/null +++ b/Textures/SSFD_2x2/README.md @@ -0,0 +1,4 @@ +Images for surface stable fractal dithering. + +https://www.youtube.com/watch?v=HPqGaIMVuLs + diff --git a/Textures/SSFD_2x2/Texture3DFromSequence.asset b/Textures/SSFD_2x2/Texture3DFromSequence.asset new file mode 100644 index 0000000..d037f79 --- /dev/null +++ b/Textures/SSFD_2x2/Texture3DFromSequence.asset @@ -0,0 +1,40 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!117 &11700000 +Texture3D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Texture3DFromSequence + m_ImageContentsHash: + serializedVersion: 2 + Hash: 00000000000000000000000000000000 + m_ForcedFallbackFormat: 4 + m_DownscaleFallback: 0 + m_IsAlphaChannelOptional: 0 + serializedVersion: 3 + m_ColorSpace: 0 + m_Format: 8 + m_Width: 32 + m_Height: 32 + m_Depth: 4 + m_MipCount: 1 + m_DataSize: 16384 + m_TextureSettings: + serializedVersion: 2 + m_FilterMode: 1 + m_Aniso: 1 + m_MipBias: 0 + m_WrapU: 0 + m_WrapV: 0 + m_WrapW: 0 + m_UsageMode: 0 + m_IsReadable: 1 + image data: 16384 + _typelessdata: 89ffffff89ffffff88ffffff87ffffff86ffffff85ffffff84ffffff84ffffff83ffffff82ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff82ffffff83ffffff84ffffff84ffffff85ffffff86ffffff87ffffff88ffffff89ffffff88ffffff88ffffff87ffffff87ffffff86ffffff85ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff85ffffff86ffffff87ffffff87ffffff88ffffff87ffffff87ffffff87ffffff86ffffff85ffffff84ffffff84ffffff83ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff83ffffff84ffffff84ffffff85ffffff86ffffff87ffffff87ffffff87ffffff86ffffff86ffffff85ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff85ffffff86ffffff86ffffff86ffffff85ffffff85ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff85ffffff85ffffff85ffffff84ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7bffffff7affffff79ffffff7affffff7bffffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff84ffffff84ffffff84ffffff83ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7affffff79ffffff78ffffff79ffffff7affffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff83ffffff84ffffff83ffffff83ffffff82ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff79ffffff78ffffff79ffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff82ffffff83ffffff82ffffff82ffffff82ffffff81ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff79ffffff78ffffff78ffffff78ffffff79ffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff81ffffff82ffffff82ffffff81ffffff81ffffff81ffffff81ffffff7fffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff79ffffff79ffffff78ffffff77ffffff78ffffff79ffffff79ffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff7fffffff81ffffff81ffffff81ffffff7fffffff7fffffff7fffffff7fffffff7effffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff79ffffff79ffffff78ffffff77ffffff76ffffff77ffffff78ffffff79ffffff79ffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7effffff7fffffff7fffffff7fffffff7effffff7effffff7effffff7effffff7dffffff7dffffff7cffffff7cffffff7bffffff7bffffff7affffff79ffffff79ffffff78ffffff77ffffff76ffffff76ffffff76ffffff77ffffff78ffffff79ffffff79ffffff7affffff7bffffff7bffffff7cffffff7cffffff7dffffff7dffffff7effffff7effffff7effffff7dffffff7dffffff7dffffff7dffffff7cffffff7cffffff7bffffff7bffffff7bffffff7affffff79ffffff79ffffff78ffffff77ffffff76ffffff76ffffff75ffffff76ffffff76ffffff77ffffff78ffffff79ffffff79ffffff7affffff7bffffff7bffffff7bffffff7cffffff7cffffff7dffffff7dffffff7dffffff7cffffff7cffffff7cffffff7cffffff7bffffff7bffffff7bffffff7affffff7affffff79ffffff79ffffff78ffffff77ffffff76ffffff76ffffff75ffffff74ffffff75ffffff76ffffff76ffffff77ffffff78ffffff79ffffff79ffffff7affffff7affffff7bffffff7bffffff7bffffff7cffffff7cffffff7cffffff7bffffff7bffffff7bffffff7bffffff7affffff7affffff7affffff79ffffff79ffffff78ffffff78ffffff77ffffff76ffffff76ffffff75ffffff74ffffff74ffffff74ffffff75ffffff76ffffff76ffffff77ffffff78ffffff78ffffff79ffffff79ffffff7affffff7affffff7affffff7bffffff7bffffff7bffffff7affffff7affffff7affffff7affffff79ffffff79ffffff79ffffff78ffffff78ffffff78ffffff77ffffff76ffffff76ffffff75ffffff74ffffff74ffffff73ffffff74ffffff74ffffff75ffffff76ffffff76ffffff77ffffff78ffffff78ffffff78ffffff79ffffff79ffffff79ffffff7affffff7affffff7affffff7bffffff7bffffff7bffffff7bffffff7affffff7affffff7affffff79ffffff79ffffff78ffffff78ffffff77ffffff76ffffff76ffffff75ffffff74ffffff74ffffff74ffffff75ffffff76ffffff76ffffff77ffffff78ffffff78ffffff79ffffff79ffffff7affffff7affffff7affffff7bffffff7bffffff7bffffff7cffffff7cffffff7cffffff7cffffff7bffffff7bffffff7bffffff7affffff7affffff79ffffff79ffffff78ffffff77ffffff76ffffff76ffffff75ffffff74ffffff75ffffff76ffffff76ffffff77ffffff78ffffff79ffffff79ffffff7affffff7affffff7bffffff7bffffff7bffffff7cffffff7cffffff7cffffff7dffffff7dffffff7dffffff7dffffff7cffffff7cffffff7bffffff7bffffff7bffffff7affffff79ffffff79ffffff78ffffff77ffffff76ffffff76ffffff75ffffff76ffffff76ffffff77ffffff78ffffff79ffffff79ffffff7affffff7bffffff7bffffff7bffffff7cffffff7cffffff7dffffff7dffffff7dffffff7effffff7effffff7effffff7effffff7dffffff7dffffff7cffffff7cffffff7bffffff7bffffff7affffff79ffffff79ffffff78ffffff77ffffff76ffffff76ffffff76ffffff77ffffff78ffffff79ffffff79ffffff7affffff7bffffff7bffffff7cffffff7cffffff7dffffff7dffffff7effffff7effffff7effffff7fffffff7fffffff7fffffff7fffffff7effffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff79ffffff79ffffff78ffffff77ffffff76ffffff77ffffff78ffffff79ffffff79ffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7effffff7fffffff7fffffff7fffffff81ffffff81ffffff81ffffff81ffffff7fffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff79ffffff79ffffff78ffffff77ffffff78ffffff79ffffff79ffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff7fffffff81ffffff81ffffff81ffffff82ffffff82ffffff82ffffff81ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff79ffffff78ffffff78ffffff78ffffff79ffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff81ffffff82ffffff82ffffff83ffffff83ffffff82ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff79ffffff78ffffff79ffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff82ffffff83ffffff84ffffff84ffffff83ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7affffff79ffffff78ffffff79ffffff7affffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff83ffffff84ffffff85ffffff84ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7bffffff7affffff79ffffff7affffff7bffffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff84ffffff86ffffff85ffffff85ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff85ffffff85ffffff87ffffff86ffffff86ffffff85ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff85ffffff86ffffff86ffffff87ffffff87ffffff87ffffff86ffffff85ffffff84ffffff84ffffff83ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff83ffffff84ffffff84ffffff85ffffff86ffffff87ffffff87ffffff88ffffff88ffffff87ffffff87ffffff86ffffff85ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff85ffffff86ffffff87ffffff87ffffff88ffffff89ffffff89ffffff88ffffff87ffffff86ffffff85ffffff84ffffff84ffffff83ffffff82ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff82ffffff83ffffff84ffffff84ffffff85ffffff86ffffff87ffffff88ffffff89ffffff8affffff89ffffff88ffffff87ffffff87ffffff86ffffff85ffffff84ffffff83ffffff82ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff82ffffff83ffffff84ffffff85ffffff86ffffff87ffffff87ffffff88ffffff89ffffff86ffffff86ffffff85ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff78ffffff78ffffff78ffffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff85ffffff86ffffff85ffffff85ffffff84ffffff84ffffff83ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff79ffffff79ffffff79ffffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff83ffffff84ffffff84ffffff85ffffff84ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff7affffff7affffff7affffff7affffff7affffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff84ffffff83ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff7affffff7bffffff7bffffff7bffffff7bffffff7bffffff7affffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff83ffffff83ffffff82ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7bffffff7bffffff7bffffff7cffffff7cffffff7cffffff7cffffff7cffffff7bffffff7bffffff7bffffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff82ffffff82ffffff82ffffff81ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7cffffff7cffffff7dffffff7dffffff7dffffff7dffffff7dffffff7cffffff7cffffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff81ffffff82ffffff81ffffff81ffffff81ffffff7fffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7cffffff7cffffff7dffffff7dffffff7effffff7effffff7effffff7effffff7effffff7dffffff7dffffff7cffffff7cffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff7fffffff81ffffff81ffffff7fffffff7fffffff7fffffff7effffff7effffff7dffffff7dffffff7cffffff7bffffff7cffffff7dffffff7dffffff7effffff7effffff7fffffff7fffffff7fffffff7fffffff7fffffff7effffff7effffff7dffffff7dffffff7cffffff7bffffff7cffffff7dffffff7dffffff7effffff7effffff7fffffff7fffffff7effffff7effffff7effffff7dffffff7dffffff7cffffff7cffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff7fffffff81ffffff81ffffff81ffffff81ffffff81ffffff7fffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7cffffff7cffffff7dffffff7dffffff7effffff7effffff7dffffff7dffffff7dffffff7cffffff7cffffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff81ffffff82ffffff82ffffff82ffffff81ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7cffffff7cffffff7dffffff7dffffff7cffffff7cffffff7cffffff7bffffff7bffffff7bffffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff82ffffff83ffffff82ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7bffffff7bffffff7bffffff7cffffff7cffffff7bffffff7bffffff7bffffff7affffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff83ffffff84ffffff83ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff7affffff7bffffff7bffffff7affffff7affffff7affffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff84ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff7affffff7affffff79ffffff79ffffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff83ffffff84ffffff84ffffff85ffffff85ffffff85ffffff84ffffff84ffffff83ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff79ffffff78ffffff78ffffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff85ffffff86ffffff86ffffff86ffffff85ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff78ffffff77ffffff78ffffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff82ffffff83ffffff84ffffff84ffffff85ffffff86ffffff87ffffff86ffffff85ffffff84ffffff84ffffff83ffffff82ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff78ffffff78ffffff78ffffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff85ffffff86ffffff86ffffff86ffffff85ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff78ffffff79ffffff79ffffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff83ffffff84ffffff84ffffff85ffffff85ffffff85ffffff84ffffff84ffffff83ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff79ffffff7affffff7affffff7affffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff84ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff7affffff7affffff7bffffff7bffffff7bffffff7affffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff83ffffff84ffffff83ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff7affffff7bffffff7bffffff7cffffff7cffffff7cffffff7bffffff7bffffff7bffffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff82ffffff83ffffff82ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7bffffff7bffffff7bffffff7cffffff7cffffff7dffffff7dffffff7dffffff7cffffff7cffffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff81ffffff82ffffff82ffffff82ffffff81ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7cffffff7cffffff7dffffff7dffffff7effffff7effffff7effffff7dffffff7dffffff7cffffff7cffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff7fffffff81ffffff81ffffff81ffffff81ffffff81ffffff7fffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7cffffff7cffffff7dffffff7dffffff7effffff7effffff7fffffff7fffffff7fffffff7effffff7effffff7dffffff7dffffff7cffffff7bffffff7cffffff7dffffff7dffffff7effffff7effffff7fffffff7fffffff7fffffff7fffffff7fffffff7effffff7effffff7dffffff7dffffff7cffffff7bffffff7cffffff7dffffff7dffffff7effffff7effffff7fffffff7fffffff81ffffff81ffffff81ffffff7fffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7cffffff7cffffff7dffffff7dffffff7effffff7effffff7effffff7effffff7effffff7dffffff7dffffff7cffffff7cffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff7fffffff81ffffff81ffffff82ffffff82ffffff81ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7cffffff7cffffff7dffffff7dffffff7dffffff7dffffff7dffffff7cffffff7cffffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff81ffffff82ffffff83ffffff82ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7bffffff7bffffff7bffffff7cffffff7cffffff7cffffff7cffffff7cffffff7bffffff7bffffff7bffffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff82ffffff84ffffff83ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff7affffff7bffffff7bffffff7bffffff7bffffff7bffffff7affffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff83ffffff84ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff7affffff7affffff7affffff7affffff7affffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff85ffffff85ffffff84ffffff84ffffff83ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff79ffffff79ffffff79ffffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff83ffffff84ffffff84ffffff85ffffff86ffffff86ffffff85ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff78ffffff78ffffff78ffffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff85ffffff86ffffff87ffffff86ffffff85ffffff84ffffff84ffffff83ffffff82ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff78ffffff77ffffff78ffffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff82ffffff83ffffff84ffffff84ffffff85ffffff86ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff84ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff81ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff81ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff7fffffff7fffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff7fffffff7fffffff7fffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff7fffffff7effffff7effffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7effffff7effffff7effffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7effffff7dffffff7dffffff7dffffff7cffffff7cffffff7bffffff7bffffff7affffff79ffffff7affffff7bffffff7bffffff7cffffff7cffffff7dffffff7dffffff7dffffff7dffffff7dffffff7cffffff7cffffff7bffffff7bffffff7affffff79ffffff7affffff7bffffff7bffffff7cffffff7cffffff7dffffff7dffffff7cffffff7cffffff7cffffff7bffffff7bffffff7bffffff7affffff79ffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7effffff7effffff7effffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff79ffffff7affffff7bffffff7bffffff7bffffff7cffffff7cffffff7bffffff7bffffff7bffffff7affffff7affffff7affffff79ffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff7fffffff7fffffff7fffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff79ffffff7affffff7affffff7affffff7bffffff7bffffff7affffff7affffff7affffff79ffffff79ffffff79ffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff81ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff79ffffff79ffffff79ffffff7affffff7affffff79ffffff79ffffff79ffffff78ffffff78ffffff79ffffff7affffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7affffff79ffffff78ffffff78ffffff79ffffff79ffffff78ffffff78ffffff78ffffff77ffffff78ffffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff78ffffff77ffffff78ffffff78ffffff77ffffff77ffffff77ffffff78ffffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff84ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff78ffffff77ffffff77ffffff76ffffff76ffffff77ffffff78ffffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff78ffffff77ffffff76ffffff75ffffff76ffffff77ffffff78ffffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff82ffffff83ffffff84ffffff84ffffff85ffffff84ffffff84ffffff83ffffff82ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff78ffffff77ffffff76ffffff76ffffff76ffffff77ffffff78ffffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff78ffffff77ffffff76ffffff77ffffff77ffffff77ffffff78ffffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff84ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff78ffffff77ffffff77ffffff78ffffff78ffffff78ffffff77ffffff78ffffff79ffffff7affffff7bffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7bffffff7affffff79ffffff78ffffff77ffffff78ffffff78ffffff79ffffff79ffffff79ffffff78ffffff78ffffff79ffffff7affffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7affffff79ffffff78ffffff78ffffff79ffffff79ffffff7affffff7affffff7affffff79ffffff79ffffff79ffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff81ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff79ffffff79ffffff79ffffff7affffff7affffff7bffffff7bffffff7bffffff7affffff7affffff7affffff79ffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff7fffffff7fffffff7fffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff79ffffff7affffff7affffff7affffff7bffffff7bffffff7cffffff7cffffff7cffffff7bffffff7bffffff7bffffff7affffff79ffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7effffff7effffff7effffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff79ffffff7affffff7bffffff7bffffff7bffffff7cffffff7cffffff7dffffff7dffffff7dffffff7cffffff7cffffff7bffffff7bffffff7affffff79ffffff7affffff7bffffff7bffffff7cffffff7cffffff7dffffff7dffffff7dffffff7dffffff7dffffff7cffffff7cffffff7bffffff7bffffff7affffff79ffffff7affffff7bffffff7bffffff7cffffff7cffffff7dffffff7dffffff7effffff7effffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7effffff7effffff7effffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7effffff7fffffff7fffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff7fffffff7fffffff7fffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff7fffffff81ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff81ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff84ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff84ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff85ffffff84ffffff84ffffff83ffffff82ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff82ffffff83ffffff84ffffff84ffffff85ffffff84ffffff84ffffff83ffffff82ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff82ffffff83ffffff84ffffff84ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff84ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff81ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff81ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff7fffffff7fffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff7fffffff7fffffff7fffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff7fffffff7effffff7effffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7effffff7effffff7effffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7effffff7dffffff7dffffff7dffffff7cffffff7cffffff7bffffff7bffffff7affffff79ffffff7affffff7bffffff7bffffff7cffffff7cffffff7dffffff7dffffff7dffffff7dffffff7dffffff7cffffff7cffffff7bffffff7bffffff7affffff79ffffff7affffff7bffffff7bffffff7cffffff7cffffff7dffffff7dffffff7effffff7effffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7effffff7effffff7effffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7effffff7fffffff7fffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff7fffffff7fffffff7fffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff7fffffff81ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff81ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff84ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff84ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff85ffffff84ffffff84ffffff83ffffff82ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff82ffffff83ffffff84ffffff84ffffff85ffffff84ffffff84ffffff83ffffff82ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff82ffffff83ffffff84ffffff84ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff84ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff81ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff81ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff7fffffff7fffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff7fffffff7fffffff7fffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff7fffffff7effffff7effffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7effffff7effffff7effffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7effffff7dffffff7dffffff7dffffff7cffffff7cffffff7bffffff7bffffff7affffff79ffffff7affffff7bffffff7bffffff7cffffff7cffffff7dffffff7dffffff7dffffff7dffffff7dffffff7cffffff7cffffff7bffffff7bffffff7affffff79ffffff7affffff7bffffff7bffffff7cffffff7cffffff7dffffff7dffffff7effffff7effffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7effffff7effffff7effffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7affffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7effffff7fffffff7fffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff7fffffff7fffffff7fffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7bffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff7fffffff81ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff81ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7bffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7dffffff7cffffff7dffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7cffffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff84ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff84ffffff83ffffff82ffffff82ffffff81ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff84ffffff84ffffff83ffffff82ffffff82ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff82ffffff82ffffff83ffffff84ffffff85ffffff84ffffff84ffffff83ffffff82ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff82ffffff83ffffff84ffffff84ffffff85ffffff84ffffff84ffffff83ffffff82ffffff81ffffff7fffffff7effffff7dffffff7effffff7fffffff81ffffff82ffffff83ffffff84ffffff84ffffff + m_StreamData: + serializedVersion: 2 + offset: 0 + size: 0 + path: diff --git a/Textures/SSFD_2x2/Texture3DFromSequence.asset.meta b/Textures/SSFD_2x2/Texture3DFromSequence.asset.meta new file mode 100644 index 0000000..91f92fa --- /dev/null +++ b/Textures/SSFD_2x2/Texture3DFromSequence.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 88d49b37d73085a4a9fba2a31aca23a8 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11700000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Textures/SSFD_2x2/dots_L1-sdf.png b/Textures/SSFD_2x2/dots_L1-sdf.png Binary files differnew file mode 100644 index 0000000..b13a467 --- /dev/null +++ b/Textures/SSFD_2x2/dots_L1-sdf.png diff --git a/Textures/SSFD_2x2/dots_L1-sdf.png.meta b/Textures/SSFD_2x2/dots_L1-sdf.png.meta new file mode 100644 index 0000000..82a34ca --- /dev/null +++ b/Textures/SSFD_2x2/dots_L1-sdf.png.meta @@ -0,0 +1,127 @@ +fileFormatVersion: 2 +guid: e250e710129eb0246b4edba42ad04709 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 1 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 128 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 128 + resizeAlgorithm: 0 + textureFormat: 63 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 1 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Textures/SSFD_2x2/dots_L1.png b/Textures/SSFD_2x2/dots_L1.png Binary files differnew file mode 100644 index 0000000..b038984 --- /dev/null +++ b/Textures/SSFD_2x2/dots_L1.png diff --git a/Textures/SSFD_2x2/dots_L1.png.meta b/Textures/SSFD_2x2/dots_L1.png.meta new file mode 100644 index 0000000..3bb9af5 --- /dev/null +++ b/Textures/SSFD_2x2/dots_L1.png.meta @@ -0,0 +1,127 @@ +fileFormatVersion: 2 +guid: 16dbeda9f06ea2e40b9d57bb1f2dac18 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 1 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Textures/SSFD_2x2/dots_L2-sdf.png b/Textures/SSFD_2x2/dots_L2-sdf.png Binary files differnew file mode 100644 index 0000000..30fa038 --- /dev/null +++ b/Textures/SSFD_2x2/dots_L2-sdf.png diff --git a/Textures/SSFD_2x2/dots_L2-sdf.png.meta b/Textures/SSFD_2x2/dots_L2-sdf.png.meta new file mode 100644 index 0000000..a16a5da --- /dev/null +++ b/Textures/SSFD_2x2/dots_L2-sdf.png.meta @@ -0,0 +1,127 @@ +fileFormatVersion: 2 +guid: 4080328d94716ac49a1b63ab33301779 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 1 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 128 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 128 + resizeAlgorithm: 0 + textureFormat: 63 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 1 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Textures/SSFD_2x2/dots_L2.png b/Textures/SSFD_2x2/dots_L2.png Binary files differnew file mode 100644 index 0000000..b994fbf --- /dev/null +++ b/Textures/SSFD_2x2/dots_L2.png diff --git a/Textures/SSFD_2x2/dots_L2.png.meta b/Textures/SSFD_2x2/dots_L2.png.meta new file mode 100644 index 0000000..878ae5c --- /dev/null +++ b/Textures/SSFD_2x2/dots_L2.png.meta @@ -0,0 +1,127 @@ +fileFormatVersion: 2 +guid: f07d4cf96598fe441a03e12746205bdb +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 1 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Textures/SSFD_2x2/dots_L3-sdf.png b/Textures/SSFD_2x2/dots_L3-sdf.png Binary files differnew file mode 100644 index 0000000..f895230 --- /dev/null +++ b/Textures/SSFD_2x2/dots_L3-sdf.png diff --git a/Textures/SSFD_2x2/dots_L3-sdf.png.meta b/Textures/SSFD_2x2/dots_L3-sdf.png.meta new file mode 100644 index 0000000..5b3d66a --- /dev/null +++ b/Textures/SSFD_2x2/dots_L3-sdf.png.meta @@ -0,0 +1,127 @@ +fileFormatVersion: 2 +guid: 4a6a92f4dedeb2240ac75d4f2e5d73dd +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 1 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 128 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 128 + resizeAlgorithm: 0 + textureFormat: 63 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 1 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Textures/SSFD_2x2/dots_L3.png b/Textures/SSFD_2x2/dots_L3.png Binary files differnew file mode 100644 index 0000000..c6209d6 --- /dev/null +++ b/Textures/SSFD_2x2/dots_L3.png diff --git a/Textures/SSFD_2x2/dots_L3.png.meta b/Textures/SSFD_2x2/dots_L3.png.meta new file mode 100644 index 0000000..7bc9920 --- /dev/null +++ b/Textures/SSFD_2x2/dots_L3.png.meta @@ -0,0 +1,127 @@ +fileFormatVersion: 2 +guid: 050570fab8254644792b440fc832ccf5 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 1 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Textures/SSFD_2x2/dots_L4-sdf.png b/Textures/SSFD_2x2/dots_L4-sdf.png Binary files differnew file mode 100644 index 0000000..117bb48 --- /dev/null +++ b/Textures/SSFD_2x2/dots_L4-sdf.png diff --git a/Textures/SSFD_2x2/dots_L4-sdf.png.meta b/Textures/SSFD_2x2/dots_L4-sdf.png.meta new file mode 100644 index 0000000..72992b0 --- /dev/null +++ b/Textures/SSFD_2x2/dots_L4-sdf.png.meta @@ -0,0 +1,127 @@ +fileFormatVersion: 2 +guid: 28d40e9889ec9e44da1eed65dd9e51ed +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 1 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 128 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 128 + resizeAlgorithm: 0 + textureFormat: 63 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 1 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Textures/SSFD_2x2/dots_L4.png b/Textures/SSFD_2x2/dots_L4.png Binary files differnew file mode 100644 index 0000000..92c8d25 --- /dev/null +++ b/Textures/SSFD_2x2/dots_L4.png diff --git a/Textures/SSFD_2x2/dots_L4.png.meta b/Textures/SSFD_2x2/dots_L4.png.meta new file mode 100644 index 0000000..e4104c5 --- /dev/null +++ b/Textures/SSFD_2x2/dots_L4.png.meta @@ -0,0 +1,127 @@ +fileFormatVersion: 2 +guid: 0fe8f5ad256f8ac4987a8e0caa3dea84 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + 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 + flipGreenChannel: 0 + isReadable: 1 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + 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: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Third_Party/generate_recursive_dithering.py b/Third_Party/generate_recursive_dithering.py new file mode 100644 index 0000000..417647e --- /dev/null +++ b/Third_Party/generate_recursive_dithering.py @@ -0,0 +1,88 @@ +import numpy as np
+from PIL import Image, ImageDraw
+import argparse
+import math
+
+from shift_image_to_corner import shift_to_corner
+
+def create_circle_image(res, radius, center=None):
+ """Create a binary image with a white circle on black background."""
+ if center is None:
+ center = (res/2, res/2)
+
+ img = Image.new('L', (res, res), 0)
+ draw = ImageDraw.Draw(img)
+
+ # Convert radius and center to pixels
+ r_px = int(radius * res)
+ cx, cy = int(center[0]), int(center[1])
+
+ # Draw white circle (255)
+ draw.ellipse([cx-r_px, cy-r_px, cx+r_px, cy+r_px], fill=255)
+ return img
+
+def main():
+ parser = argparse.ArgumentParser(description="Generate dot and circle images.")
+ parser.add_argument("--res", type=int, default=128, help="Resolution of the images.")
+ args = parser.parse_args()
+
+ res = args.res
+ goal_area = 0.1
+ # a = pi * r^2
+ # r = sqrt(a / pi)
+ initial_r = math.sqrt(goal_area / math.pi) * res # Start with a circle that fills 1/4 of the image
+
+ # Calculate areas and radii for each layer
+ initial_area = math.pi * (initial_r/res)**2
+
+ # Layer 1: Single circle in corner
+ r1 = math.sqrt(initial_area/1) * res # Calculate radius consistently with other layers
+ base_img = create_circle_image(res, r1/res)
+ corner_img = shift_to_corner(base_img)
+ corner_img.save("dots_L1.png")
+
+ # Layer 2: Two circles, split area
+ r2 = math.sqrt(initial_area/2) * res # New radius for each circle
+ # Create corner circle
+ corner_img = shift_to_corner(create_circle_image(res, r2/res))
+ # Create center circle
+ center_img = create_circle_image(res, r2/res)
+ # Combine images
+ layer2 = Image.fromarray(np.maximum(np.array(corner_img), np.array(center_img)))
+ layer2.save("dots_L2.png")
+
+ # Layer 3: Three circles
+ r3 = math.sqrt(initial_area/3) * res
+ # Create corner and center circles as before
+ corner_img = shift_to_corner(create_circle_image(res, r3/res))
+ center_img = create_circle_image(res, r3/res)
+ # Create top circle
+ top_img = shift_to_corner(create_circle_image(res, r3/res), shift_side=False)
+ # Combine images
+ layer3 = Image.fromarray(np.maximum.reduce([
+ np.array(corner_img),
+ np.array(center_img),
+ np.array(top_img)
+ ]))
+ layer3.save("dots_L3.png")
+
+ # Layer 4: Four circles
+ r4 = math.sqrt(initial_area/4) * res
+ # Create corner and center circles
+ corner_img = shift_to_corner(create_circle_image(res, r4/res))
+ center_img = create_circle_image(res, r4/res)
+ # Create top and right circles
+ top_img = shift_to_corner(create_circle_image(res, r4/res), shift_side=False)
+ right_img = shift_to_corner(create_circle_image(res, r4/res), shift_up=False)
+ # Combine images
+
+ layer4 = Image.fromarray(np.maximum.reduce([
+ np.array(corner_img),
+ np.array(center_img),
+ np.array(top_img),
+ np.array(right_img)
+ ]))
+ layer4.save("dots_L4.png")
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file diff --git a/Third_Party/shift_image_to_corner.py b/Third_Party/shift_image_to_corner.py new file mode 100644 index 0000000..8f365a7 --- /dev/null +++ b/Third_Party/shift_image_to_corner.py @@ -0,0 +1,97 @@ +"""
+Shift image to corner, wrapping it toroidally.
+"""
+
+from PIL import Image
+import numpy as np
+import argparse
+import os
+
+def shift_to_corner(img, shift_side=True, shift_up=True):
+ """
+ Shifts an image to edges with toroidal wrapping based on specified directions.
+
+ Args:
+ img (PIL.Image): Input Pillow image
+ shift_side (bool): Whether to shift horizontally to the right edge
+ shift_up (bool): Whether to shift vertically to the top edge
+
+ Returns:
+ PIL.Image: Shifted image
+ """
+ # Convert image to numpy array
+ img_array = np.array(img)
+
+ # Get dimensions
+ height, width = img_array.shape[:2]
+ half_height = height // 2
+ half_width = width // 2
+
+ # Create new array for the shifted image
+ shifted = np.zeros_like(img_array)
+
+ if shift_side and shift_up:
+ # Original behavior - shift to upper right corner
+ shifted[half_height:, half_width:] = img_array[:half_height, :half_width] # Q1 -> BR
+ shifted[half_height:, :half_width] = img_array[:half_height, half_width:] # Q2 -> BL
+ shifted[:half_height, half_width:] = img_array[half_height:, :half_width] # Q3 -> TR
+ shifted[:half_height, :half_width] = img_array[half_height:, half_width:] # Q4 -> TL
+ elif shift_side:
+ # Only shift horizontally to right
+ shifted[:, half_width:] = img_array[:, :half_width] # Left half -> Right
+ shifted[:, :half_width] = img_array[:, half_width:] # Right half -> Left
+ elif shift_up:
+ # Only shift vertically to top
+ shifted[half_height:, :] = img_array[:half_height, :] # Top half -> Bottom
+ shifted[:half_height, :] = img_array[half_height:, :] # Bottom half -> Top
+ else:
+ # No shift, return original image
+ shifted = img_array.copy()
+
+ # Convert back to PIL Image and return
+ return Image.fromarray(shifted)
+
+def shift_to_corner_from_file(image_path, output_path, shift_side=True, shift_up=True):
+ """
+ Wrapper function that shifts an image file to edges with toroidal wrapping.
+
+ Args:
+ image_path (str): Path to the input image
+ output_path (str): Path where the shifted image will be saved
+ shift_side (bool): Whether to shift horizontally to the right edge
+ shift_up (bool): Whether to shift vertically to the top edge
+
+ Returns:
+ PIL.Image: Shifted image
+ """
+ img = Image.open(image_path)
+ result = shift_to_corner(img, shift_side=shift_side, shift_up=shift_up)
+ result.save(output_path)
+ return result
+
+def get_output_path(input_path):
+ """
+ Generate output path by adding '_shifted' before the file extension.
+
+ Args:
+ input_path (str): Path to the input image
+ Returns:
+ str: Path for the output image
+ """
+ base, ext = os.path.splitext(input_path)
+ return f"{base}_shifted{ext}"
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(description='Shift an image to the corner with toroidal wrapping.')
+ parser.add_argument('input_image', help='Path to the input image file')
+ parser.add_argument('--no-side', action='store_false', dest='shift_side',
+ help='Disable horizontal shifting (default: enabled)')
+ parser.add_argument('--no-up', action='store_false', dest='shift_up',
+ help='Disable vertical shifting (default: enabled)')
+
+ args = parser.parse_args()
+ output_path = get_output_path(args.input_image)
+
+ shift_to_corner_from_file(args.input_image, output_path,
+ shift_side=args.shift_side,
+ shift_up=args.shift_up)
diff --git a/feature_macros.cginc b/feature_macros.cginc index ecbc709..3f5d177 100644 --- a/feature_macros.cginc +++ b/feature_macros.cginc @@ -291,6 +291,7 @@ #pragma shader_feature_local _ _GIMMICK_LENS_00_GRABPASS #pragma shader_feature_local _ _GIMMICK_LENS_00_BAYER #pragma shader_feature_local _ _GIMMICK_LENS_00_INTERLEAVED_GRADIENT_NOISE +#pragma shader_feature_local _ _SURFACE_STABLE_FRACTAL_DITHERING #endif // __FEATURE_MACROS_INC diff --git a/globals.cginc b/globals.cginc index a1eca79..88abb0f 100644 --- a/globals.cginc +++ b/globals.cginc @@ -1139,5 +1139,11 @@ float _Gimmick_Lens_00_Frame_Counter_Speed; #endif #endif +#if defined(_SURFACE_STABLE_FRACTAL_DITHERING) +texture3D _Surface_Stable_Fractal_Dithering_Noise; +float _Surface_Stable_Fractal_Dithering_Scale; +float _Surface_Stable_Fractal_Dithering_Max_Fwidth; +#endif + #endif diff --git a/tooner.shader b/tooner.shader index a816e67..5632ce2 100644 --- a/tooner.shader +++ b/tooner.shader @@ -1175,7 +1175,10 @@ Shader "yum_food/tooner" _Gimmick_Lens_00_Mode("Mode", Float) = 0 // 0 = Bayer, 1 = InterleavedGradientNoise _Gimmick_Lens_00_Scale("Scale", Float) = 1 - + _Surface_Stable_Fractal_Dithering_Enable_Static("Enable stable fractal dithering", Float) = 0 + _Surface_Stable_Fractal_Dithering_Noise("Noise", 3D) = "white" {} + _Surface_Stable_Fractal_Dithering_Scale("Scale", Float) = 1 + _Surface_Stable_Fractal_Dithering_Max_Fwidth("Max fwidth", Float) = 0.001 } SubShader { diff --git a/tooner_lighting.cginc b/tooner_lighting.cginc index 3241394..ab885e6 100644 --- a/tooner_lighting.cginc +++ b/tooner_lighting.cginc @@ -1069,6 +1069,65 @@ float4 effect(inout v2f i, out float depth) const float frame = 0; #endif // _FRAME_COUNTER +#if defined(_SURFACE_STABLE_FRACTAL_DITHERING) + { + float2 duv = i.uv0; + + //float duv_fw = fwidth(duv.x) + fwidth(duv.y); + // Original paper uses SVD instead of fwidth. + float2x2 M = float2x2(ddx(duv), ddy(duv)); + float2x2 MtM = mul(transpose(M), M); + float trace = MtM[0][0] + MtM[1][1]; + float det = determinant(MtM); + // Calculate eigenvalues using quadratic formula. + float tmp = sqrt(trace * trace - 4 * det); + float e1 = (trace + tmp) * 0.5; + float e2 = (trace - tmp) * 0.5; + float2 singular_values = sqrt(float2(e1, e2)); + // Logic from original paper: the smaller eigenvalue corresponds to the + // largest amount of stretching, so we use it to determine when to + // subdivide. + float duv_fw = singular_values.y; + + // Suppose Max_Fwidth is 1. + // duv_fw is 16. That means UV is changing a lot per pixel. That means we want to shrink the scale of the UV. + // Factor is 16. + // log_2(factor) is 4. + // Divide original by 16. + float fw_factor = duv_fw / _Surface_Stable_Fractal_Dithering_Max_Fwidth; + float fractal_level = log2(fw_factor); + float fractal_level_floor = floor(fractal_level); + float fractal_remainder = fractal_level - fractal_level_floor; + duv /= pow(2, fractal_level_floor); + duv *= _Surface_Stable_Fractal_Dithering_Scale; + + //float subdivisions = 4; + //float fractal_remainder_subd = fractal_remainder * subdivisions; + +#if 1 + // Four layers -> coarsest at 0.125, finest at 0.875. + uint width, height, depth; + _Surface_Stable_Fractal_Dithering_Noise.GetDimensions(width, height, depth); + float n_layers = depth; + float not_used_lo = 1/(n_layers*2); + float not_used_hi = 1 - not_used_lo; + float uvw = (not_used_hi - not_used_lo) * (1 - fractal_remainder) + not_used_lo; + + float3 duv_3d = float3(duv, uvw); +#else + float3 duv_3d = float3(duv, 0); +#endif + float noise = _Surface_Stable_Fractal_Dithering_Noise.SampleLevel(bilinear_repeat_s, duv_3d, 0); + noise = (noise > 0.5) ? 1 : 0; + + albedo.rgb = noise; +#if 0 + float hue = 0; + hue += glsl_mod(fractal_level_floor*.1, 1); + albedo.rgb *= HSVtoRGB(float3(hue, 1, 1)); +#endif + } +#endif #if defined(_GIMMICK_GERSTNER_WATER) #if defined(_EXPLODE) |
