У меня довольно простое требование для вычислительного шейдера (DirectCompute через Unity).У меня есть текстура 128x128, и я хотел бы превратить красный канал этой текстуры в 1d массив с плавающей точкой.Мне нужно делать это очень часто, поэтому простое выполнение цикла на стороне процессора для каждого текселя не обрежет его.
Инициализация:
m_outputBuffer = new ComputeBuffer(m_renderTexture.width * m_renderTexture.height, sizeof(float));
m_kernelIndex = m_computeShader.FindKernel("CSMain");
Вот метод C #:
/// <summary>
/// This method converts the red channel of the given RenderTexture to a
/// one dimensional array of floats of size width * height.
/// </summary>
private float[] ConvertToFloatArray(RenderTexture renderTexture)
{
m_computeShader.SetTexture(m_kernelIndex, INPUT_TEXTURE, renderTexture);
float[] result = new float[renderTexture.width * renderTexture.height];
m_outputBuffer.SetData(result);
m_computeShader.SetBuffer(m_kernelIndex, OUTPUT_BUFFER, m_outputBuffer);
m_computeShader.Dispatch(m_kernelIndex, renderTexture.width / 8, renderTexture.height / 8, 1);
m_outputBuffer.GetData(result);
return result;
}
и весь вычислительный шейдер:
// Each #kernel tells which function to compile; you can have many kernels
#pragma kernel CSMain
// Create a RenderTexture with enableRandomWrite flag and set it
// with cs.SetTexture
Texture2D<float4> InputTexture;
RWBuffer<float> OutputBuffer;
[numthreads(8, 8, 1)]
void CSMain(uint3 id : SV_DispatchThreadID)
{
OutputBuffer[id.x * id.y] = InputTexture[id.xy].r;
}
метод C # возвращает массив ожидаемого размера, и он обычно в некотором роде соответствует ожидаемому.Однако, даже если моя входная текстура будет равномерно красной, все равно будут некоторые нули.