Example #1
0
        } // GetWeightedAverageLightInputFromSphere

        private static SphericalHarmonicL2 ExtractSphericalHarmonicForCubeFace(Matrix faceTransform, Color[] colorDataRgb, int faceSize)
        {
            SphericalHarmonicL2 sh = new SphericalHarmonicL2();

            // For each pixel in the face, generate it's SH contribution.
            // Treat each pixel in the cube as a light source, which gets added to the SH.
            // This is used to generate an indirect lighting SH for the scene.

            float directionStep = 2.0f / (faceSize - 1.0f);
            int   pixelIndex    = 0;

            float dirY = 1.0f;

            for (int y = 0; y < faceSize; y++)
            {
                SphericalHarmonicL2 lineSh = new SphericalHarmonicL2();
                float dirX = -1.0f;

                for (int x = 0; x < faceSize; x++)
                {
                    //the direction to the pixel in the cube
                    Vector3 direction = new Vector3(dirX, dirY, 1);
                    Vector3.TransformNormal(ref direction, ref faceTransform, out direction);

                    //length of the direction vector
                    float length = direction.Length();
                    //approximate area of the pixel (pixels close to the cube edges appear smaller when projected)
                    float weight = 1.0f / length;

                    //normalise:
                    direction.X *= weight;
                    direction.Y *= weight;
                    direction.Z *= weight;

                    Vector3 rgbFloat;

                    Color rgbm = colorDataRgb[pixelIndex++];
                    rgbFloat = rgbm.ToVector3();

                    //Add it to the SH
                    lineSh.AddLight(rgbFloat, direction, weight);

                    dirX += directionStep;
                }

                //average the SH
                if (lineSh.weighting > 0)
                {
                    lineSh *= 1 / lineSh.weighting;
                }

                // Add the line to the full SH
                // (SH is generated line by line to ease problems with floating point accuracy loss)
                sh += lineSh;

                dirY -= directionStep;
            }

            if (sh.weighting > 0)
            {
                sh *= 1 / sh.weighting;
            }

            return(sh);
        } // ExtractSphericalHarmonicForCubeFace
        } // GetWeightedAverageLightInputFromSphere

        private static SphericalHarmonicL2 ExtractSphericalHarmonicForCubeFace(Matrix faceTransform, Color[] colorDataRgb, int faceSize)
        {
            SphericalHarmonicL2 sh = new SphericalHarmonicL2();

            // For each pixel in the face, generate it's SH contribution.
            // Treat each pixel in the cube as a light source, which gets added to the SH.
            // This is used to generate an indirect lighting SH for the scene.

            float directionStep = 2.0f / (faceSize - 1.0f);
            int pixelIndex = 0;

            float dirY = 1.0f;
            for (int y = 0; y < faceSize; y++)
            {
                SphericalHarmonicL2 lineSh = new SphericalHarmonicL2();
                float dirX = -1.0f;

                for (int x = 0; x < faceSize; x++)
                {
                    //the direction to the pixel in the cube
                    Vector3 direction = new Vector3(dirX, dirY, 1);
                    Vector3.TransformNormal(ref direction, ref faceTransform, out direction);

                    //length of the direction vector
                    float length = direction.Length();
                    //approximate area of the pixel (pixels close to the cube edges appear smaller when projected)
                    float weight = 1.0f / length;

                    //normalise:
                    direction.X *= weight;
                    direction.Y *= weight;
                    direction.Z *= weight;

                    Vector3 rgbFloat;
                    
                    Color rgbm = colorDataRgb[pixelIndex++];
                    rgbFloat = rgbm.ToVector3();
                    
                    //Add it to the SH
                    lineSh.AddLight(rgbFloat, direction, weight);

                    dirX += directionStep;
                }

                //average the SH
                if (lineSh.weighting > 0)
                    lineSh *= 1 / lineSh.weighting;

                // Add the line to the full SH
                // (SH is generated line by line to ease problems with floating point accuracy loss)
                sh += lineSh;

                dirY -= directionStep;
            }

            if (sh.weighting > 0)
                sh *= 1 / sh.weighting;

            return sh;
        } // ExtractSphericalHarmonicForCubeFace