I have a list of RenderTexture objects which I am looking to hand into a compute shader without bringing them into CPU memory. They are using the ARGBFloat format, which I’m tied to and cannot change. When I try to put them into a Texture2DArray object, each pixel in them shows up as the float4 value {NaN, NaN, NaN, NaN}.
There has got to be a way to do this, I feel like this is super basic. Any assistance is much appreciated.
var layerShader = (ComputeShader)Resources.Load("Shaders/LayeredImageShader");
int kernelHandle = layerShader.FindKernel("CSMain");
. . .
var layersToShaderArray = new Texture2DArray(width, height, layers.Count, TextureFormat.RGBAFloat, false);
layersToShaderArray.filterMode = FilterMode.Point;
// Load textures into the array without bringing to CPU space
for (int i = 0; i < layers.Count; i++)
Graphics.CopyTexture(layers[i], 0, 0, layersToShaderArray, i, 0);
layerShader.SetTexture(kernelHandle, "layerArray", layersToShaderArray);
layerShader.Dispatch(kernelHandle, numGroups, numGroups, 1);
Thanks in advance, this one really has me bonking my head against a wall.
Ok, I know this post comes almost immediately after the question, but I think I rubber ducked this one… For whatever reason, RenderTextures with the format ARGBFloat just do not get along well with being copied into Texture2DArray objects (other formats like ARGB32 seem to do fine…). So I copied the RenderTexture into a Texture2D without doing an Apply(), which leaves all the data in GPU space. After this, I simply fed the Texture2D object to the Texture2DArray, and it worked fine. Code updated below:
var layerShader = (ComputeShader)Resources.Load("Shaders/LayeredImageShader");
int kernelHandle = layerShader.FindKernel("CSMain");
. . .
var layersToShaderArray = new Texture2DArray(width, height, layers.Count, TextureFormat.RGBAFloat, false);
layersToShaderArray.filterMode = FilterMode.Point;
// Load textures into the array without bringing to CPU space
for (int i = 0; i < layers.Count; i++)
{
Texture2D tempTexture = new Texture2D(layers[i].width, layers[i].height, TextureFormat.RGBAFloat, false);
Graphics.CopyTexture(layers[i], tempTexture);
Graphics.CopyTexture(tempTexture, 0, 0, layersToShaderArray, i, 0);
}
layerShader.SetTexture(kernelHandle, "layerArray", layersToShaderArray);
layerShader.Dispatch(kernelHandle, numGroups, numGroups, 1);
FYI: This is not the correct use of the 2D-Graphics tag which is related to 2D rendering features. Texture2D is not a 2D team feature, it’s the basic texture used throughout Unity. Adding 2D tags incorrectly puts your question in the 2D product area.
I’ll remove that tag for you.
Thanks.