private void ExtractCross( Vector4D[,] _HDRValues, int _CubeFaceSize, Vector4D[][,] _CubeFaces ) { int Width = _HDRValues.GetLength( 0 ), Height = _HDRValues.GetLength( 1 ); // Extract cube faces Vector4D[][,] TempCubeFaces = new Vector4D[6][,]; int SourceCubeFaceSize = 0; if ( Height > Width ) { // Vertical cross SourceCubeFaceSize = Height / 4; if ( Width != SourceCubeFaceSize * 3 ) throw new Exception( "The cube map " + Width + "x" + Height + " was detected as a VERTICAL CROSS with a cube face size of " + SourceCubeFaceSize + " (Height/4) but the width is not of the expected size of 3x" + SourceCubeFaceSize + " (3xWidth)! Are you sure you're using a CROSS cube map?" ); TempCubeFaces[0] = ReadCubeFace( _HDRValues, SourceCubeFaceSize, 2, 1 ); // +X TempCubeFaces[1] = ReadCubeFace( _HDRValues, SourceCubeFaceSize, 0, 1 ); // -X TempCubeFaces[2] = ReadCubeFace( _HDRValues, SourceCubeFaceSize, 1, 0 ); // +Y TempCubeFaces[3] = ReadCubeFace( _HDRValues, SourceCubeFaceSize, 1, 2 ); // -Y TempCubeFaces[4] = ReadCubeFace( _HDRValues, SourceCubeFaceSize, 1, 1 ); // +Z TempCubeFaces[5] = ReadCubeFace( _HDRValues, SourceCubeFaceSize, 1, 3, true ); // -Z } else { // Horizontal cross SourceCubeFaceSize = Width / 4; if ( Height != SourceCubeFaceSize * 3 ) throw new Exception( "The cube map " + Width + "x" + Height + " was detected as a HORIZONTAL CROSS with a cube face size of " + SourceCubeFaceSize + " (Width/4) but the height is not of the expected size of 3x" + SourceCubeFaceSize + " (3xHeight)! Are you sure you're using a CROSS cube map?" ); TempCubeFaces[0] = ReadCubeFace( _HDRValues, SourceCubeFaceSize, 2, 1 ); // +X TempCubeFaces[1] = ReadCubeFace( _HDRValues, SourceCubeFaceSize, 0, 1 ); // -X TempCubeFaces[2] = ReadCubeFace( _HDRValues, SourceCubeFaceSize, 1, 0 ); // +Y TempCubeFaces[3] = ReadCubeFace( _HDRValues, SourceCubeFaceSize, 1, 2 ); // -Y TempCubeFaces[4] = ReadCubeFace( _HDRValues, SourceCubeFaceSize, 1, 1 ); // +Z TempCubeFaces[5] = ReadCubeFace( _HDRValues, SourceCubeFaceSize, 3, 1 ); // -Z } // Convert to final size m_CubeSize = SourceCubeFaceSize; m_CubeFaces = TempCubeFaces; BuildTargetCubeMapMip0( _CubeFaceSize, _CubeFaces, ( Vector _Direction ) => { Vector4D Result = PointSampleCubeMap( _Direction ); return Result; } ); }
private void ExtractProbe( Vector4D[,] _HDRValues, int _CubeFaceSize, Vector4D[][,] _CubeFaces ) { int Width = _HDRValues.GetLength( 0 ), Height = _HDRValues.GetLength( 1 ); BuildTargetCubeMapMip0( _CubeFaceSize, _CubeFaces, ( Vector _Direction ) => { // Stolen from http://www.pauldebevec.com/Probes/ double R = (1.0/ Math.PI) * Math.Acos( _Direction.z ) / Math.Sqrt( _Direction.x*_Direction.x + _Direction.y*_Direction.y ); double U = _Direction.x * R; double V = _Direction.y * R; // Bilinear interpolate float X = (float) (Width * (0.5 * (1.0 + U))); float Y = (float) (Height * (0.5 * (1.0 - V))); int X0 = (int) Math.Floor( X ); int Y0 = (int) Math.Floor( Y ); float x = X - X0; float y = Y - Y0; X0 = Math.Min( Width-1, X0 ); Y0 = Math.Min( Height-1, Y0 ); int X1 = Math.Min( Width-1, X0+1 ); int Y1 = Math.Min( Height-1, Y0+1 ); Vector4D V00 = _HDRValues[X0,Y0]; Vector4D V01 = _HDRValues[X1,Y0]; Vector4D V10 = _HDRValues[X0,Y1]; Vector4D V11 = _HDRValues[X1,Y1]; Vector4D V0 = V00 + x * (V01 - V00); Vector4D V1 = V10 + x * (V11 - V10); Vector4D Result = V0 + y * (V1 - V0); return Result; } ); }