Fractrace.PictureArt.FastPreviewRenderer.CreateShadowInfo C# (CSharp) Method

CreateShadowInfo() protected method

Schatteninformationen, wenn das Licht von oben rechts kommen, werden erzeugt. Vorbereitet für weitere Lichtquellen.
protected CreateShadowInfo ( ) : void
return void
        protected virtual void CreateShadowInfo()
        {
            // Noch nicht öffentliche Parameter:
            Random rand = new Random();
            double glow = ParameterDict.Current.GetDouble("Renderer.ShadowGlow");
            // Drei "Schattenlichtquellen"
            // Eine für die Dunklen Tiefen
            // Eine für die breite Normalasicht
            // Und eine für die mit sehr geringen Eintreffwinkel
            // Ist bei perspektivischen Aufnahmen noch unbrauchbar.

            // Shadowlight1
            // 1 ist der Durchschnittswert.
            double shadowlight1Val = 0.1;
            // Die maximale Abweichung der Auftreffwinkel.
            double shadowlight1Range = 1;

            double shadowlight1Intensity = 0.2;

            double shadowlight2Val = 0.2;
            // Die maximale Abweichung der Auftreffwinkel.
            double shadowlight2Range = 2;
            double shadowlight2Intensity = 0.6;

            double shadowlight3Val = 1.5;
            // Die maximale Abweichung der Auftreffwinkel.
            double shadowlight3Range = 0.05;
            double shadowlight3Intensity = 1;

            double sharpness = 2.5; //

            // Beginnend von rechts oben werden die Bereiche, die im Dunklen liegen, berechnet.
            shadowInfo11 = new double[pData.Width, pData.Height];
            shadowInfo01 = new double[pData.Width, pData.Height];
            shadowInfo10 = new double[pData.Width, pData.Height];
            shadowInfo00 = new double[pData.Width, pData.Height];
            shadowInfo11sharp = new double[pData.Width, pData.Height];
            shadowInfo01sharp = new double[pData.Width, pData.Height];
            shadowInfo10sharp = new double[pData.Width, pData.Height];
            shadowInfo00sharp = new double[pData.Width, pData.Height];

            shadowPlane = new double[pData.Width, pData.Height];
            double[,] shadowTempPlane = new double[pData.Width, pData.Height];
            double diffy = shadowJustify * (areaDeph);

            // Main Iteration:
            double yd = 0;
            double ydv = 0;
            double ydh = 0;

            double dShadowNumber = shadowNumber;

            for (int i = 0; i < pData.Width; i++)
            {
                for (int j = 0; j < pData.Height; j++)
                {
                    shadowPlane[i, j] = 0;
                }
            }

            double currentShadowlightRange = 0;
            double shadowVal = 0.1;
            int shadowTypeCount = 0;
            double shadowlight1Level = 0.25;
            double shadowlight2Level = 0.5;
            double shadowlight3Level = 0.25;
            double currentIntensity = 1;

            for (int shadowMode = 0; shadowMode < 3; shadowMode++)
            {
                //       for (int shadowMode = 1; shadowMode <=1; shadowMode++) {
                switch (shadowMode)
                {

                    case 0:
                        diffy = shadowJustify * shadowlight1Val * (areaDeph);
                        shadowVal = shadowlight1Level;
                        currentShadowlightRange = shadowlight1Range;
                        currentIntensity = shadowlight1Intensity;
                        break;

                    case 1:
                        diffy = shadowJustify * shadowlight2Val * (areaDeph);
                        shadowVal = shadowlight2Level;
                        currentShadowlightRange = shadowlight2Range;
                        currentIntensity = shadowlight2Intensity;
                        break;

                    case 2:
                        diffy = shadowJustify * shadowlight3Val * (areaDeph);
                        shadowVal = shadowlight3Level;
                        currentShadowlightRange = shadowlight3Range;
                        currentIntensity = shadowlight3Intensity;
                        break;

                }

                int usedShadowNumber = shadowNumber + 1;
                if (shadowMode == 0 || shadowMode == 2)
                    usedShadowNumber = (int)(0.5 * shadowNumber + 1);
                /*
              if (shadowMode == 3 || shadowMode == 4)
                usedShadowNumber = (int)(0.1 * shadowNumber + 1);
              */

                for (int shadowIter = 1; shadowIter < usedShadowNumber + 1; shadowIter++)
                {

                    yd = diffy / ((double)(pData.Width + pData.Height));
                    ydv = diffy / ((double)(pData.Height));
                    ydh = diffy / ((double)(pData.Width));

                    yd *= (1.0 + currentShadowlightRange * 2.0 * (double)shadowIter / (double)dShadowNumber);
                    ydv *= (1.0 + currentShadowlightRange * 1.2 * (double)shadowIter / (double)dShadowNumber);
                    ydh *= (1.0 + currentShadowlightRange * 1.2 * (double)shadowIter / (double)dShadowNumber);

                    // Clean Plane
                    for (int i = 0; i < pData.Width; i++)
                    {
                        for (int j = 0; j < pData.Height; j++)
                        {
                            shadowTempPlane[i, j] = 0;
                        }
                    }

                    // initialize shadowInfo00, ... shadowInfo11, shadowInfo00sharp, ... , shadowInfo11sharp
                    for (int i = 0; i < pData.Width; i++)
                    {
                        for (int j = 0; j < pData.Height; j++)
                        {
                            shadowInfo11[i, j] = smoothDeph1[i, j];
                            shadowInfo10[i, j] = smoothDeph1[i, j];
                            shadowInfo01[i, j] = smoothDeph1[i, j];
                            shadowInfo00[i, j] = smoothDeph1[i, j];
                            shadowInfo11sharp[i, j] = smoothDeph1[i, j];
                            shadowInfo10sharp[i, j] = smoothDeph1[i, j];
                            shadowInfo01sharp[i, j] = smoothDeph1[i, j];
                            shadowInfo00sharp[i, j] = smoothDeph1[i, j];
                        }
                    }

                    // Randomize diagonal
                    int currentIntXval = 1;
                    int currentIntYval = 1;

                    shadowTypeCount++;
                    //  if (shadowTypeCount >= 35)
                    if (shadowTypeCount > 11)
                        shadowTypeCount = 1;

                    // Gleichmäßige Aufteilung bei 11

                    //shadowTypeCount = 4;
                    switch (shadowTypeCount)
                    {
                        case 1:
                            currentIntXval = 1;
                            currentIntYval = 1;
                            break;

                        case 2:
                            currentIntXval = 1;
                            currentIntYval = 0;
                            break;

                        case 3:
                            currentIntXval = 0;
                            currentIntYval = 1;
                            break;

                        case 4:
                            currentIntXval = 2;
                            currentIntYval = 1;
                            break;

                        case 5:
                            currentIntXval = 1;
                            currentIntYval = 2;
                            break;

                        case 6:
                            currentIntXval = 3;
                            currentIntYval = 1;
                            break;

                        case 7:
                            currentIntXval = 1;
                            currentIntYval = 3;
                            break;

                        case 8:
                            currentIntXval = 4;
                            currentIntYval = 3;
                            break;

                        case 9:
                            currentIntXval = 3;
                            currentIntYval = 4;
                            break;

                        case 10:
                            currentIntXval = 1;
                            currentIntYval = 5;
                            break;

                        case 11:
                            currentIntXval = 5;
                            currentIntYval = 1;
                            break;

                        case 12:
                            currentIntXval = 2;
                            currentIntYval = 7;
                            break;

                        case 13:
                            currentIntXval = 7;
                            currentIntYval = 2;
                            break;

                        case 14:
                            currentIntXval = 3;
                            currentIntYval = 5;
                            break;
                        case 15:
                            currentIntXval = 5;
                            currentIntYval = 3;
                            break;
                        case 16:
                            currentIntXval = 7;
                            currentIntYval = 3;
                            break;
                        case 17:
                            currentIntXval = 3;
                            currentIntYval = 7;
                            break;
                        case 18:
                            currentIntXval = 8;
                            currentIntYval = 3;
                            break;
                        case 19:
                            currentIntXval = 3;
                            currentIntYval = 8;
                            break;
                        case 20:
                            currentIntXval = 4;
                            currentIntYval = 5;
                            break;
                        case 21:
                            currentIntXval = 5;
                            currentIntYval = 4;
                            break;
                        case 22:
                            currentIntXval = 7;
                            currentIntYval = 4;
                            break;
                        case 23:
                            currentIntXval = 4;
                            currentIntYval = 7;
                            break;
                        case 24:
                            currentIntXval = 1;
                            currentIntYval = 1;
                            break;
                        case 25:
                            currentIntXval = 5;
                            currentIntYval = 4;
                            break;
                        case 26:
                            currentIntXval = 4;
                            currentIntYval = 5;
                            break;
                        case 27:
                            currentIntXval = 0;
                            currentIntYval = 1;
                            break;
                        case 28:
                            currentIntXval = 1;
                            currentIntYval = 0;
                            break;
                        case 29:
                            currentIntXval = 1;
                            currentIntYval = 6;
                            break;
                        case 30:
                            currentIntXval = 6;
                            currentIntYval = 1;
                            break;
                        case 31:
                            currentIntXval = 3;
                            currentIntYval = 7;
                            break;
                        case 32:
                            currentIntXval = 4;
                            currentIntYval = 7;
                            break;
                        case 33:
                            currentIntXval = 3;
                            currentIntYval = 8;
                            break;
                        case 34:
                            currentIntXval = 2;
                            currentIntYval = 7;
                            break;
                        case 35:
                            currentIntXval = 6;
                            currentIntYval = 2;
                            break;
                        case 36:
                        case 37:
                        case 38:
                        case 39:
                        case 40:
                            currentIntXval = 3;
                            currentIntYval = 7;
                            break;

                    }

                    // ***********  generate shadowplane ************

                    for (int i = pData.Width - currentIntXval; i >= 0; i--)
                    {
                        for (int j = pData.Height - currentIntYval; j >= 0; j--)
                        {

                            // *********  Fill shadowInfo11  ***********
                            if (i < pData.Width - currentIntXval && j < pData.Height - currentIntYval)
                            {
                                double localShadow = shadowInfo11[i + currentIntXval, j + currentIntYval] - ydh;
                                if (localShadow > shadowInfo11[i, j] && (rand.NextDouble() < glow))
                                {
                                    shadowInfo11[i, j] = localShadow;
                                }
                                localShadow = shadowInfo11sharp[i + currentIntXval, j + currentIntYval] - sharpness * ydh;
                                if (localShadow > shadowInfo11sharp[i, j] && (rand.NextDouble() < glow))
                                {
                                    shadowInfo11sharp[i, j] = localShadow;
                                }
                            }
                        }
                        for (int j = 0; j < pData.Height; j++)
                        {

                            // *********  Fill shadowInfo01  ***********
                            if (i < pData.Width - currentIntXval && j >= currentIntYval)
                            {
                                double localShadow = shadowInfo01[i + currentIntXval, j - currentIntYval] - ydh;
                                if (localShadow > shadowInfo01[i, j] && (rand.NextDouble() < glow))
                                {
                                    shadowInfo01[i, j] = localShadow;
                                }
                                localShadow = shadowInfo01sharp[i + currentIntXval, j - currentIntYval] - sharpness * ydh;
                                if (localShadow > shadowInfo01sharp[i, j] && (rand.NextDouble() < glow))
                                {
                                    shadowInfo01sharp[i, j] = localShadow;
                                }
                            }
                        }
                    }

                    for (int i = 0; i < pData.Width; i++)
                    {

                        // *********  Fill shadowInfo10  ***********
                        for (int j = pData.Height - currentIntXval; j >= 0; j--)
                        {
                            if (i >= currentIntXval && j < pData.Height - currentIntYval)
                            {
                                double localShadow = shadowInfo10[i - currentIntXval, j + currentIntYval] - ydv;
                                if (localShadow > shadowInfo10[i, j] && (rand.NextDouble() < glow))
                                    shadowInfo10[i, j] = localShadow;
                                localShadow = shadowInfo10sharp[i - currentIntXval, j + currentIntYval] - sharpness * ydv;
                                if (localShadow > shadowInfo10sharp[i, j] && (rand.NextDouble() < glow))
                                    shadowInfo10sharp[i, j] = localShadow;
                            }
                        }

                        // *********  Fill shadowInfo00  ***********
                        for (int j = 0; j < pData.Height; j++)
                        {
                            if (i >= currentIntXval && j >= currentIntYval)
                            {
                                double localShadow = shadowInfo00[i - currentIntXval, j - currentIntYval] - ydh;
                                if (localShadow > shadowInfo00[i, j] && (rand.NextDouble() < glow))
                                    shadowInfo00[i, j] = localShadow;
                                localShadow = shadowInfo00sharp[i - currentIntXval, j - currentIntYval] - sharpness * ydh;
                                if (localShadow > shadowInfo00sharp[i, j] && (rand.NextDouble() < glow))
                                    shadowInfo00sharp[i, j] = localShadow;
                            }
                        }
                    }

                    // *********  Combine shadowInfo00, ..., shadowInfo11sharp  ***********
                    // *********  create shadowTempPlane **********

                    for (int i = 0; i < pData.Width; i++)
                    {
                        for (int j = 0; j < pData.Height; j++)
                        {

                            double shadowMapEntry = 0;
                            double currentShadowMapEntry = 0;
                            double height = smoothDeph1[i, j];
                            double shadowHeight = 0;
                            double sharpShadowHeight = 0;

                            for (int k = 0; k < 4; k++)
                            {

                                switch (k)
                                {

                                    case 0:
                                        shadowHeight = shadowInfo00[i, j];
                                        sharpShadowHeight = shadowInfo00sharp[i, j];
                                        break;

                                    case 1:
                                        shadowHeight = shadowInfo01[i, j];
                                        sharpShadowHeight = shadowInfo01sharp[i, j];
                                        break;

                                    case 2:
                                        shadowHeight = shadowInfo10[i, j];
                                        sharpShadowHeight = shadowInfo10sharp[i, j];
                                        break;

                                    case 3:
                                        shadowHeight = shadowInfo11[i, j];
                                        sharpShadowHeight = shadowInfo11sharp[i, j];
                                        break;

                                }

                                if (height != double.MinValue)
                                {
                                    if (height < sharpShadowHeight) // inside the sharp shadow
                                        currentShadowMapEntry += shadowVal;
                                    if (height < shadowHeight) // inside the shadow
                                        currentShadowMapEntry += shadowVal;

                                    // Test:
                                    //currentShadowMapEntry = 0;
                                    shadowMapEntry += currentShadowMapEntry;
                                }
                            }
                            // shadowMapEntry /= 1114.0;
                            shadowMapEntry /= 16.0;
                            if (shadowMapEntry > 1)
                                shadowMapEntry = 1;
                            shadowMapEntry += shadowTempPlane[i, j];
                            shadowMapEntry /= 2.0;
                            if (shadowMapEntry > 1)
                                shadowMapEntry = 1;
                            shadowTempPlane[i, j] = shadowMapEntry;
                        }
                    }

                    for (int i = 0; i < pData.Width; i++)
                    {
                        for (int j = 0; j < pData.Height; j++)
                        {
                            shadowPlane[i, j] += currentIntensity * shadowTempPlane[i, j] / dShadowNumber;
                        }
                    }
                }
            }
            // Release Memory:
            shadowInfo11 = null;
            shadowInfo01 = null;
            shadowInfo10 = null;
            shadowInfo00 = null;
            shadowInfo11sharp = null;
            shadowInfo01sharp = null;
            shadowInfo10sharp = null;
            shadowInfo00sharp = null;

            // Normalize:
            double sMin = Double.MaxValue;
            double sMax = Double.MinValue;
            for (int i = 0; i < pData.Width; i++)
            {
                for (int j = 0; j < pData.Height; j++)
                {
                    if (sMin > shadowPlane[i, j])
                        sMin = shadowPlane[i, j];
                    if (sMax < shadowPlane[i, j])
                        sMax = shadowPlane[i, j];

                }
            }
            double sDiff = sMax - sMin;
            for (int i = 0; i < pData.Width; i++)
            {
                for (int j = 0; j < pData.Height; j++)
                {
                    shadowPlane[i, j] = (shadowPlane[i, j] - sMin) / sDiff;
                    if (double.IsNaN(shadowPlane[i, j]) || double.IsInfinity(shadowPlane[i, j]))
                    {
                        shadowPlane[i, j] = 0;
                    }
                }
            }
        }