private IEnumerator CubemapToEquirectangularCpuNegativeX(uint[] cameraPixels, byte[] pixelValues, int stride, int panoramaWidth, int panoramaHeight, int ssaaFactor, float startTime, float processingTimePerFrame, int numPixelsAveraged,
int startX, int startY, int endX, int endY)
{
for (int y = startY; y < endY; y++)
for (int x = startX; x < endX; x++)
{
int rTotal = 0, gTotal = 0, bTotal = 0, aTotal = 0;
for (int ySsaa = y * ssaaFactor; ySsaa < (y + 1) * ssaaFactor; ySsaa++)
for (int xSsaa = x * ssaaFactor; xSsaa < (x + 1) * ssaaFactor; xSsaa++)
{
float xcoord = (float)xSsaa / (panoramaWidth * ssaaFactor);
float ycoord = (float)ySsaa / (panoramaHeight * ssaaFactor);
float latitude = (ycoord - 0.5f) * Mathf.PI;
float longitude = (xcoord * 2.0f - 1.0f) * Mathf.PI;
float cosLat = Mathf.Cos(latitude);
Vector3 equirectRayDirection = new Vector3(
cosLat * Mathf.Sin(longitude), -Mathf.Sin(latitude), cosLat * Mathf.Cos(longitude));
float distance = 1.0f / equirectRayDirection.x;
float u = -equirectRayDirection.z * distance, v = equirectRayDirection.y * distance;
// Debug.Assert(equirectRayDirection.x < 0.0f);
// Debug.Assert (! (Mathf.Abs(u) > 1.0f || Mathf.Abs(v) > 1.0f) );
u = (u + 1.0f) / 2.0f;
v = (v + 1.0f) / 2.0f;
Color32 c = GetCameraPixelBilinear(cameraPixels, (int)CubemapFace.NegativeX, u, v);
rTotal += c.r; gTotal += c.g; bTotal += c.b; aTotal += c.a;
}
int baseIdx = stride * (panoramaHeight - 1 - y) + x * 4;
pixelValues[baseIdx + 0] = (byte)(bTotal / numPixelsAveraged);
pixelValues[baseIdx + 1] = (byte)(gTotal / numPixelsAveraged);
pixelValues[baseIdx + 2] = (byte)(rTotal / numPixelsAveraged);
pixelValues[baseIdx + 3] = (byte)(aTotal / numPixelsAveraged);
if ((x & 0xFF) == 0 && Time.realtimeSinceStartup - startTime > processingTimePerFrame)
{
yield return null; // Wait until next frame
startTime = Time.realtimeSinceStartup;
}
}
}