Hello, fellow Uniters! I’m in the situation where I have and editor script that generates a grayscaled, graded and blurred copy of a texture. It’s a standard operation, and doesn’t take too much time (like, 3 or 5 seconds in total). The problem it’s that I usually convert a lot of textures at once, and easily scalates to a wait of 1 or 2 minutes. I’m investigating if its possible to optimize this process, but the only idea I have in mind is to use compute shaders to do the operation.
My doubt is if this is a viable option (I know compute shaders has some speed issues comunicating between CPU and GPU), if someone has some documentation at hand, or if there are better alternatives.
I drop the code here:
private static void GrayScale(Texture2D _currentDiffuse)
{
Color32[] pixels = _currentDiffuse.GetPixels32();
Color32[] pixelsDest = _currentDiffuse.GetPixels32();
for (int x = 0; x < _currentDiffuse.width; x++)
{
for (int y = 0; y < _currentDiffuse.height; y++)
{
Color32 pixel = pixels[x + y * _currentDiffuse.width];
int p = (int)(((256 * 256 + pixel.r) * 256 + pixel.b) * 256 + pixel.g);
int b = p % 256;
p = Mathf.FloorToInt(p / 256);
int g = p % 256;
p = Mathf.FloorToInt(p / 256);
int r = p % 256;
float l = (0.2126f * r / 255f) + 0.7152f * (g / 255f) + 0.0722f * (b / 255f);
Color c = new Color(l, l, l, pixel.a);
pixelsDest[x + y * _currentDiffuse.width] = c;
}
}
_currentDiffuse.SetPixels32(pixelsDest);
_currentDiffuse.Apply();
}
protected static void CreateGradientMap(Texture2D t, float gradientStrenght)
{
Color[] pixels = new Color[t.width * t.height];
Color[] pixelsNew = new Color[t.width * t.height];
pixels = t.GetPixels();
for (int y = 0; y < t.height; y++)
{
for (int x = 0; x < t.width; x++)
{
if (x == 0 || y == 0 || x == t.width - 1 || y == t.height - 1)
{
pixelsNew[x + y * t.width] = Color.black;
}
else
{
Color tc = pixels[(x - 1) + (y - 1) * t.width];
Vector3 cSampleNegXNegY = new Vector3(tc.r, tc.g, tc.g);
tc = pixels[(x) + (y - 1) * t.width];
Vector3 cSampleZerXNegY = new Vector3(tc.r, tc.g, tc.g);
tc = pixels[(x + 1) + (y - 1) * t.width];
Vector3 cSamplePosXNegY = new Vector3(tc.r, tc.g, tc.g);
tc = pixels[(x - 1) + (y) * t.width];
Vector3 cSampleNegXZerY = new Vector3(tc.r, tc.g, tc.g);
tc = pixels[(x + 1) + (y) * t.width];
Vector3 cSamplePosXZerY = new Vector3(tc.r, tc.g, tc.g);
tc = pixels[(x - 1) + (y + 1) * t.width];
Vector3 cSampleNegXPosY = new Vector3(tc.r, tc.g, tc.g);
tc = pixels[(x) + (y + 1) * t.width];
Vector3 cSampleZerXPosY = new Vector3(tc.r, tc.g, tc.g);
tc = pixels[(x + 1) + (y + 1) * t.width];
Vector3 cSamplePosXPosY = new Vector3(tc.r, tc.g, tc.g);
float fSampleNegXNegY = cSampleNegXNegY.x;
float fSampleZerXNegY = cSampleZerXNegY.x;
float fSamplePosXNegY = cSamplePosXNegY.x;
float fSampleNegXZerY = cSampleNegXZerY.x;
float fSamplePosXZerY = cSamplePosXZerY.x;
float fSampleNegXPosY = cSampleNegXPosY.x;
float fSampleZerXPosY = cSampleZerXPosY.x;
float fSamplePosXPosY = cSamplePosXPosY.x;
float edgeX = (fSampleNegXNegY - fSamplePosXNegY) * 0.25f + (fSampleNegXZerY - fSamplePosXZerY) * 0.5f + (fSampleNegXPosY - fSamplePosXPosY) * 0.25f;
float edgeY = (fSampleNegXNegY - fSampleNegXPosY) * 0.25f + (fSampleZerXNegY - fSampleZerXPosY) * 0.5f + (fSamplePosXNegY - fSamplePosXPosY) * 0.25f;
float fValue = (edgeX + edgeY) / 2.0f;
fValue = 1 - fValue / gradientStrenght;
Color c = new Color(fValue, fValue, fValue, tc.a);
pixelsNew[x + y * t.width] = c;
}
}
}
t.SetPixels(pixelsNew);
t.Apply();
}
protected static void BlurImage(Texture2D t)
{
Color[] pixels = new Color[t.width * t.height];
Color[] pixelsNew = new Color[t.width * t.height];
pixels = t.GetPixels();
for (int y = 0; y < t.height; y++)
{
for (int x = 0; x < t.width; x++)
{
if (x == 0 || y == 0 || x == t.width - 1 || y == t.height - 1)
{
pixelsNew[x + y * t.width] = Color.black;
}
else
{
Color tc = pixels[(x - 1) + (y - 1) * t.width];
Vector3 cSampleNegXNegY = new Vector3(tc.r, tc.g, tc.g);
tc = pixels[(x) + (y - 1) * t.width];
Vector3 cSampleZerXNegY = new Vector3(tc.r, tc.g, tc.g);
tc = pixels[(x + 1) + (y - 1) * t.width];
Vector3 cSamplePosXNegY = new Vector3(tc.r, tc.g, tc.g);
tc = pixels[(x - 1) + (y) * t.width];
Vector3 cSampleNegXZerY = new Vector3(tc.r, tc.g, tc.g);
tc = pixels[(x + 1) + (y) * t.width];
Vector3 cSamplePosXZerY = new Vector3(tc.r, tc.g, tc.g);
tc = pixels[(x - 1) + (y + 1) * t.width];
Vector3 cSampleNegXPosY = new Vector3(tc.r, tc.g, tc.g);
tc = pixels[(x) + (y + 1) * t.width];
Vector3 cSampleZerXPosY = new Vector3(tc.r, tc.g, tc.g);
tc = pixels[(x + 1) + (y + 1) * t.width];
Vector3 cSamplePosXPosY = new Vector3(tc.r, tc.g, tc.g);
tc = pixels[x + y * t.width];
Vector3 cSampleXY = new Vector3(tc.r, tc.g, tc.g);
float fSampleNegXNegY = cSampleNegXNegY.x;
float fSampleZerXNegY = cSampleZerXNegY.x;
float fSamplePosXNegY = cSamplePosXNegY.x;
float fSampleNegXZerY = cSampleNegXZerY.x;
float fSamplePosXZerY = cSamplePosXZerY.x;
float fSampleNegXPosY = cSampleNegXPosY.x;
float fSampleZerXPosY = cSampleZerXPosY.x;
float fSamplePosXPosY = cSamplePosXPosY.x;
float fSampleXY = cSampleXY.x;
float fBlurredValue = (fSampleNegXNegY + fSampleZerXNegY + fSamplePosXNegY + fSampleNegXZerY + fSamplePosXZerY + fSampleNegXPosY + fSampleZerXPosY + fSamplePosXPosY + 3 * fSampleXY) / 11.0f;
Color c = new Color(fBlurredValue, fBlurredValue, fBlurredValue, tc.a);
pixelsNew[x + y * t.width] = c;
}
}
}
t.SetPixels(pixelsNew);
t.Apply();
}


