Wit*_*RIT 1 shader image-processing texture2d unity-game-engine compute-shader
我在 vuforia 中偶然发现了一个奇怪的问题。当我使用 CameraDevice.GetCameraImage(mypixelformat) 请求相机图像时,返回的图像既向侧面翻转又旋转了 180 度。因此,要获得正常图像,我必须先旋转图像,然后将其侧向翻转。我使用的方法只是迭代图像的像素并修改它们。这种方法的性能非常差。下面是代码:
Texture2D image;
CameraDevice cameraDevice = Vuforia.CameraDevice.Instance;
Vuforia.Image vufImage = cameraDevice.GetCameraImage(pixelFormat);
image = new Texture2D(vufImage.Width, vufImage.Height);
vufImage.CopyToTexture(image);
Color32[] colors = image.GetPixels32();
System.Array.Reverse(colors, 0, colors.Length); //rotate 180deg
image.SetPixels32(colors); //apply rotation
image = FlipTexture(image); //flip sideways
//***** THE FLIP TEXTURE METHOD *******//
private Texture2D FlipTexture(Texture2D original, bool upSideDown = false)
{
Texture2D flipped = new Texture2D(original.width, original.height);
int width = original.width;
int height = original.height;
for (int col = 0; col < width; col++)
{
for (int row = 0; row < height; row++)
{
if (upSideDown)
{
flipped.SetPixel(row, (width - 1) - col, original.GetPixel(row, col));
}
else
{
flipped.SetPixel((width - 1) - col, row, original.GetPixel(col, row));
}
}
}
flipped.Apply();
return flipped;
}
Run Code Online (Sandbox Code Playgroud)
为了提高性能,我想以某种方式在 GPU 上安排这些像素操作,我听说可以使用计算着色器,但我不知道从哪里开始。有人可以帮我在计算着色器中编写相同的操作吗? GPU 可以处理它们,谢谢!
小智 5
整个计算着色器对我来说也是新的,但我也借此机会为自己研究了一下。以下适用于垂直翻转纹理(水平旋转和翻转应该只是垂直翻转)。有人可能会为您提供更详细的解决方案,但也许这足以让您入门。
计算着色器代码:
#pragma kernel CSMain
// Create a RenderTexture with enableRandomWrite flag and set it
// with cs.SetTexture
RWTexture2D<float4> Result;
Texture2D<float4> ImageInput;
float2 flip;
[numthreads(8,8,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
flip = float2(512 , 1024) - id.xy ;
Result[id.xy] = float4(ImageInput[flip].x, ImageInput[flip].y, ImageInput[flip].z, 1.0);
}
Run Code Online (Sandbox Code Playgroud)
并从任何脚本调用:
public void FlipImage()
{
int kernelHandle = shader.FindKernel("CSMain");
RenderTexture tex = new RenderTexture(512, 1024, 24);
tex.enableRandomWrite = true;
tex.Create();
shader.SetTexture(kernelHandle, "Result", tex);
shader.SetTexture(kernelHandle, "ImageInput", myTexture);
shader.Dispatch(kernelHandle, 512/8 , 1024 / 8, 1);
RenderTexture.active = tex;
result.ReadPixels(new Rect(0, 0, tex.width, tex.height), 0, 0);
result.Apply();
}
Run Code Online (Sandbox Code Playgroud)
这需要一个输入 Texture2D,在着色器中翻转它,将它应用到 RenderTexture 和 Texture2D,无论你需要什么。请注意,图像大小在我的实例中是硬编码的,应替换为您需要的任何大小。(在着色器中使用 shader.SetInt(); )