Added dithering option to textures
This commit is contained in:
@@ -14,8 +14,9 @@ public class QuantizedPreviewWindow : EditorWindow
|
|||||||
private int bpp = 4;
|
private int bpp = 4;
|
||||||
private int targetWidth = 128;
|
private int targetWidth = 128;
|
||||||
private int targetHeight = 128;
|
private int targetHeight = 128;
|
||||||
|
public bool dithering = true;
|
||||||
private int maxKMeans = 100;
|
private int maxKMeans = 100;
|
||||||
private int previewSize = 256;
|
private readonly int previewSize = 256;
|
||||||
|
|
||||||
[MenuItem("Window/Quantized Preview")]
|
[MenuItem("Window/Quantized Preview")]
|
||||||
public static void ShowWindow()
|
public static void ShowWindow()
|
||||||
@@ -33,6 +34,8 @@ public class QuantizedPreviewWindow : EditorWindow
|
|||||||
targetWidth = EditorGUILayout.IntField("Target Width", targetWidth);
|
targetWidth = EditorGUILayout.IntField("Target Width", targetWidth);
|
||||||
targetHeight = EditorGUILayout.IntField("Target Height", targetHeight);
|
targetHeight = EditorGUILayout.IntField("Target Height", targetHeight);
|
||||||
|
|
||||||
|
dithering = EditorGUILayout.Toggle("Dithering", dithering);
|
||||||
|
|
||||||
bpp = EditorGUILayout.IntPopup("Bits Per Pixel", bpp, new[] { "4 bpp", "8 bpp", "16 bpp" }, new[] { 4, 8, 16 });
|
bpp = EditorGUILayout.IntPopup("Bits Per Pixel", bpp, new[] { "4 bpp", "8 bpp", "16 bpp" }, new[] { 4, 8, 16 });
|
||||||
maxKMeans = EditorGUILayout.IntField("Max K-Means", maxKMeans);
|
maxKMeans = EditorGUILayout.IntField("Max K-Means", maxKMeans);
|
||||||
|
|
||||||
@@ -132,6 +135,10 @@ public class QuantizedPreviewWindow : EditorWindow
|
|||||||
{
|
{
|
||||||
Texture2D resizedTexture = PSXTexture.ResizeTexture(originalTexture, targetWidth, targetHeight);
|
Texture2D resizedTexture = PSXTexture.ResizeTexture(originalTexture, targetWidth, targetHeight);
|
||||||
|
|
||||||
|
if(dithering) {
|
||||||
|
resizedTexture = PSXTexture.DitherTexture(resizedTexture);
|
||||||
|
}
|
||||||
|
|
||||||
if (bpp == 16)
|
if (bpp == 16)
|
||||||
{
|
{
|
||||||
quantizedTexture = null;
|
quantizedTexture = null;
|
||||||
|
|||||||
@@ -44,6 +44,10 @@ namespace PSXSplash.RuntimeCode
|
|||||||
Texture2D originalTexture = (Texture2D)texture;
|
Texture2D originalTexture = (Texture2D)texture;
|
||||||
|
|
||||||
Texture2D newTexture = ResizeTexture(originalTexture, Width, Height);
|
Texture2D newTexture = ResizeTexture(originalTexture, Width, Height);
|
||||||
|
if (Dithering)
|
||||||
|
{
|
||||||
|
newTexture = DitherTexture(newTexture);
|
||||||
|
}
|
||||||
if (TextureType == PSXTextureType.TEX16_BPP)
|
if (TextureType == PSXTextureType.TEX16_BPP)
|
||||||
{
|
{
|
||||||
ushort[] converted = ConvertTo16Bpp(newTexture);
|
ushort[] converted = ConvertTo16Bpp(newTexture);
|
||||||
@@ -138,6 +142,55 @@ namespace PSXSplash.RuntimeCode
|
|||||||
return packedData;
|
return packedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Texture2D DitherTexture(Texture2D sourceTexture, float threshold = 0.2f, float errorDiffusionStrength = 0.1f)
|
||||||
|
{
|
||||||
|
int width = sourceTexture.width;
|
||||||
|
int height = sourceTexture.height;
|
||||||
|
Color[] pixels = sourceTexture.GetPixels();
|
||||||
|
Color[] ditheredPixels = new Color[pixels.Length];
|
||||||
|
|
||||||
|
for (int y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
int index = y * width + x;
|
||||||
|
Color pixel = pixels[index];
|
||||||
|
|
||||||
|
// Convert the pixel to grayscale
|
||||||
|
float gray = pixel.grayscale;
|
||||||
|
|
||||||
|
// Apply threshold to determine if it's black or white
|
||||||
|
int dithered = (gray > threshold) ? 1 : 0;
|
||||||
|
|
||||||
|
// Calculate the error as the difference between the grayscale value and the dithered result
|
||||||
|
float error = gray - dithered;
|
||||||
|
|
||||||
|
// Store the dithered pixel
|
||||||
|
ditheredPixels[index] = new Color(dithered, dithered, dithered);
|
||||||
|
|
||||||
|
// Spread the error to neighboring pixels with customizable error diffusion strength
|
||||||
|
if (x + 1 < width) pixels[(y * width) + (x + 1)] += new Color(error * 7f / 16f * errorDiffusionStrength, error * 7f / 16f * errorDiffusionStrength, error * 7f / 16f * errorDiffusionStrength);
|
||||||
|
if (y + 1 < height) pixels[((y + 1) * width) + x] += new Color(error * 3f / 16f * errorDiffusionStrength, error * 3f / 16f * errorDiffusionStrength, error * 3f / 16f * errorDiffusionStrength);
|
||||||
|
if (x - 1 >= 0 && y + 1 < height) pixels[((y + 1) * width) + (x - 1)] += new Color(error * 5f / 16f * errorDiffusionStrength, error * 5f / 16f * errorDiffusionStrength, error * 5f / 16f * errorDiffusionStrength);
|
||||||
|
if (x + 1 < width && y + 1 < height) pixels[((y + 1) * width) + (x + 1)] += new Color(error * 1f / 16f * errorDiffusionStrength, error * 1f / 16f * errorDiffusionStrength, error * 1f / 16f * errorDiffusionStrength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clamp the final pixel values to ensure they are valid colors
|
||||||
|
for (int i = 0; i < pixels.Length; i++)
|
||||||
|
{
|
||||||
|
pixels[i].r = Mathf.Clamp01(pixels[i].r);
|
||||||
|
pixels[i].g = Mathf.Clamp01(pixels[i].g);
|
||||||
|
pixels[i].b = Mathf.Clamp01(pixels[i].b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the resulting dithered texture
|
||||||
|
Texture2D ditheredTexture = new Texture2D(width, height);
|
||||||
|
ditheredTexture.SetPixels(pixels);
|
||||||
|
ditheredTexture.Apply();
|
||||||
|
|
||||||
|
return ditheredTexture;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user