/// <summary> /// Generate a spherical harmonic from the faces of a cubemap, treating each pixel as a light source and averaging the result. /// </summary> public static SphericalHarmonicL2RGB GenerateSphericalHarmonicFromCubeMap( Vector3[] colourDataPositiveX, Vector3[] colourDataNegativeX, Vector3[] colourDataPositiveY, Vector3[] colourDataNegativeY, Vector3[] colourDataPositiveZ, Vector3[] colourDataNegativeZ) { if (colourDataPositiveX == null || colourDataNegativeX == null || colourDataPositiveY == null || colourDataNegativeY == null || colourDataPositiveZ == null || colourDataNegativeZ == null) { throw new ArgumentNullException(); } SphericalHarmonicL2RGB sh = new SphericalHarmonicL2RGB(); Vector3[][] source = { colourDataPositiveX, colourDataNegativeX, colourDataPositiveY, colourDataNegativeY, colourDataPositiveZ, colourDataNegativeZ, }; //extract the 6 faces of the cubemap. for (int face = 0; face < 6; face++) { int size = (int)(Math.Sqrt(source[face].Length) + 0.5); if (size * size != source[face].Length) { throw new ArgumentException("Cubemap face is an unexpected (non square) size"); } Microsoft.Xna.Framework.Graphics.CubeMapFace faceId = (Microsoft.Xna.Framework.Graphics.CubeMapFace)face; //get the transformation for this face, Matrix cubeFaceMatrix; Xen.Graphics.DrawTargetTextureCube.GetCubeMapFaceMatrix(faceId, out cubeFaceMatrix); //extract the spherical harmonic for this face and accumulate it. sh += ExtractSphericalHarmonicForCubeFace(cubeFaceMatrix, source[face], size); } //average out over the sphere return(sh.GetWeightedAverageLightInputFromSphere()); }
/// <summary> /// Generate a spherical harmonic from the faces of a cubemap, treating each pixel as a light source and averaging the result. /// </summary> public static SphericalHarmonicL2RGB GenerateSphericalHarmonicFromCubeMap( Vector3[] colourDataPositiveX, Vector3[] colourDataNegativeX, Vector3[] colourDataPositiveY, Vector3[] colourDataNegativeY, Vector3[] colourDataPositiveZ, Vector3[] colourDataNegativeZ) { if (colourDataPositiveX == null || colourDataNegativeX == null || colourDataPositiveY == null || colourDataNegativeY == null || colourDataPositiveZ == null || colourDataNegativeZ == null) throw new ArgumentNullException(); SphericalHarmonicL2RGB sh = new SphericalHarmonicL2RGB(); Vector3[][] source = { colourDataPositiveX, colourDataNegativeX, colourDataPositiveY, colourDataNegativeY, colourDataPositiveZ, colourDataNegativeZ, }; //extract the 6 faces of the cubemap. for (int face = 0; face < 6; face++) { int size = (int)(Math.Sqrt(source[face].Length) + 0.5); if (size * size != source[face].Length) throw new ArgumentException("Cubemap face is an unexpected (non square) size"); Microsoft.Xna.Framework.Graphics.CubeMapFace faceId = (Microsoft.Xna.Framework.Graphics.CubeMapFace)face; //get the transformation for this face, Matrix cubeFaceMatrix; Xen.Graphics.DrawTargetTextureCube.GetCubeMapFaceMatrix(faceId, out cubeFaceMatrix); //extract the spherical harmonic for this face and accumulate it. sh += ExtractSphericalHarmonicForCubeFace(cubeFaceMatrix, source[face], size); } //average out over the sphere return sh.GetWeightedAverageLightInputFromSphere(); }