我想使用Graphics.Blit
在GPU上实现算法。输入值是浮点数,输出值也是浮点数。我使用RFloat格式创建纹理,并希望为每个像素设置值。我怎么设置?根据统一manual SetPixels
不起作用:
此功能仅适用于ARGB32,RGB24和Alpha8纹理格式。 对于其他格式,将忽略SetPixels。
算法需要浮点精度,因此这些格式都不可用。那怎么办呢?
编辑:在使用单位RenderTextures进行更多努力之后,以下是我提出的将数据传输到GPU的代码。
int res=512;
Texture2D tempTexture= new Texture2D(res, res, TextureFormat.RFloat, false);
public void ApplyHeightsToRT(float[,] heights, RenderTexture renderTexture)
{
RenderTexture.active = renderTexture;
Texture2D tempTexture = new Texture2D(res, res, TextureFormat.RFloat, false);
tempTexture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0
, false);
for (int i = 0; i < tempTexture.width; i++)
for (int j = 0; j < tempTexture.height; j++)
{
tempTexture.SetPixel(i, j, new Color(heights[i, j], 0, 0, 0));
}
tempTexture.Apply();
RenderTexture.active = null;
Graphics.Blit(tempTexture, renderTexture);
}
此代码成功将tempTexture上传到RenderTexture。使用以下方法类似地完成逆操作(RenderTexture被复制到tempTexture):
public void ApplyRTToHeights(RenderTexture renderTexture, float[,] heights)
{
RenderTexture.active = renderTexture;
tempTexture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0
, false);
for (int i = 0; i < tempTexture.width; i++)
for (int j = 0; j < tempTexture.height; j++)
{
heights[i, j]=tempTexture.GetPixel(i, j).r;
}
RenderTexture.active = null;
}
为了测试代码我得到了地形的高度图,然后我调用第一个方法用高度图填充RenderTexture。然后我调用第二种方法从RenderTexture获取像素并将它们放在地形上。它什么都不做。对?
实际上一个接一个地调用这两个方法会翻转地形高度图并创建条带工件。很奇怪。在进一步调查之后,翻转的原因结果是格式化问题。在两种方法之上创建的tempTexture实际上是ARGB32纹理,而不是我希望它的RFloat。
这解释了翻转。将tempTexture的代码更改为ARGB32纹理并将RenderTexture更改为RGBA32后,翻转行为消失了。现在只有条带文物:
这是可以理解的,因为我只使用了tempTexture和RenderTexture的8位(红色通道)。
现在问题不在于在RFloat纹理上设置数据。问题是我的图形卡和许多其他不同的图形设备不支持RFloat纹理。 问题是要找到一种方法将float数组传递给RenderTexture。