private void DoAntialiasPass2(RTScanLineJob job) { Bitmap image = job.RenderImage; int i, j, n = 0; double colourDiffThreshold = 5; // second pass - now on individual pixel level int imgX; int imgY; lock (job.Semaphore) { imgX = image.Width; imgY = image.Height; } Console.WriteLine("Antialiasing second pass..."); foreach (int line in job.LinesList) { for (j = line; j < line + this.samplesPerCell; j++) // at this point we only get every second line to process { n = 0; // count rays for (i = 0; i < imgX - 1; i++) { // determine if there are differences in colour between neighbouring pixels. If no - then colour all pixels the same // otherwise - launch additional samples Color p00, p01, p11, p10; lock (job.Semaphore) { p00 = image.GetPixel(i, imgY - j - 1); p10 = image.GetPixel(i + 1, imgY - j - 1); p11 = image.GetPixel(i + 1, Math.Max(imgY - (j + 1) - 1, 0)); p01 = image.GetPixel(i, Math.Max(imgY - (j + 1) - 1, 0)); } if (ColorHelper.ColorDifference(p00, p10) < colourDiffThreshold && ColorHelper.ColorDifference(p00, p11) < colourDiffThreshold && ColorHelper.ColorDifference(p00, p01) < colourDiffThreshold && this.Quality != RenderQuality.UltraHigh) // for UltraHigh quality do multismapling regardless of colour difference { // do nothing } else { Color sAvg; if (this.Quality != RenderQuality.UltraHigh) { var s10 = job.RayTracer.Calculate((double)i + 0.5, (double)j); var s11 = job.RayTracer.Calculate((double)i + 0.5, (double)j + 0.5); var s01 = job.RayTracer.Calculate((double)i, (double)j + 0.5); n += 3; sAvg = Color.FromArgb( (p00.R + s10.R + s11.R + s01.R) / 4, (p00.G + s10.G + s11.G + s01.G) / 4, (p00.B + s10.B + s11.B + s01.B) / 4); } else // UltraHigh - multi-sampling { int nRays = 4; int rAcc = 0; int gAcc = 0; int bAcc = 0; for (int k = 0; k < nRays; k++) { for (int l = 0; l < nRays; l++) { var rayColor = job.RayTracer.Calculate((double)i + (double)k / (double)nRays, (double)j + (double)l / (double)nRays); rAcc += rayColor.R; gAcc += rayColor.G; bAcc += rayColor.B; n++; } } sAvg = Color.FromArgb( rAcc / nRays / nRays, gAcc / nRays / nRays, bAcc / nRays / nRays); } lock (job.Semaphore) { image.SetPixel(i, imgY - j - 1, sAvg); } } } Console.WriteLine("Job {0}: Line {1} antialiased, {2} rays", job.JobId, j, n); } } }
private void DoAntialiasPass1(RTScanLineJob job) { Bitmap image = job.RenderImage; int i, n = 0; double colourDiffThreshold = 5; // first pass Console.WriteLine("Antialiasing first pass..."); int imgX; int imgY; lock (job.Semaphore) { imgX = image.Width; imgY = image.Height; } foreach (int j in job.LinesList) { n = 0; // count rays for (i = 0; i < imgX - this.samplesPerCell; i += this.samplesPerCell) { // determine if there are differences in colour between neighbouring pixels. If no - then colour all pixels the same // otherwise - launch additional samples Color p00, p01, p11, p10; lock (job.Semaphore) { p00 = image.GetPixel(i, imgY - j - 1); // check if we hit an empty pixel - if yes, then skip to next line if (p00.A == 0) { break; } p10 = image.GetPixel(i + samplesPerCell, imgY - j - 1); p11 = image.GetPixel(i + samplesPerCell, Math.Max(imgY - (j + samplesPerCell) - 1, 0)); p01 = image.GetPixel(i, Math.Max(imgY - (j + samplesPerCell) - 1, 0)); } if (ColorHelper.ColorDifference(p00, p10) < colourDiffThreshold && ColorHelper.ColorDifference(p00, p11) < colourDiffThreshold && ColorHelper.ColorDifference(p00, p01) < colourDiffThreshold) { for (int y = j; y < j + samplesPerCell; y++) { for (int x = i; x < i + samplesPerCell; x++) { lock (job.Semaphore) { image.SetPixel(x, imgY - y - 1, p00); } } } } else { for (int y = j; y < j + samplesPerCell; y++) { for (int x = i; x < i + samplesPerCell; x++) { if (!(x == i && y == j)) { var pixel = job.RayTracer.Calculate(x, y); n++; lock (job.Semaphore) { image.SetPixel(x, imgY - y - 1, pixel); } } } } } } Console.WriteLine("Job {0}: Line {1} antialiased, {2} rays", job.JobId, j, n); } }
private void DoAntialiasPass1(RTScanLineJob job) { Bitmap image = job.RenderImage; int i, n = 0; double colourDiffThreshold = 5; // first pass Console.WriteLine("Antialiasing first pass..."); int imgX; int imgY; lock (job.Semaphore) { imgX = image.Width; imgY = image.Height; } foreach (int j in job.LinesList) { n = 0; // count rays for (i = 0; i < imgX - this.samplesPerCell; i += this.samplesPerCell) { // determine if there are differences in colour between neighbouring pixels. If no - then colour all pixels the same // otherwise - launch additional samples Color p00, p01, p11, p10; lock (job.Semaphore) { p00 = image.GetPixel(i, imgY - j - 1); // check if we hit an empty pixel - if yes, then skip to next line if (p00.A == 0) { break; } p10 = image.GetPixel(i + samplesPerCell, imgY - j - 1); p11 = image.GetPixel(i + samplesPerCell, Math.Max(imgY - (j + samplesPerCell)-1, 0)); p01 = image.GetPixel(i, Math.Max(imgY - (j + samplesPerCell) - 1, 0)); } if (ColorHelper.ColorDifference(p00, p10) < colourDiffThreshold && ColorHelper.ColorDifference(p00, p11) < colourDiffThreshold && ColorHelper.ColorDifference(p00, p01) < colourDiffThreshold) { for(int y = j; y < j+samplesPerCell; y++) for (int x = i; x < i + samplesPerCell; x++) { lock (job.Semaphore) { image.SetPixel(x, imgY - y - 1, p00); } } } else { for (int y = j; y < j + samplesPerCell; y++) for (int x = i; x < i + samplesPerCell; x++) { if (!(x == i && y == j)) { var pixel = job.RayTracer.Calculate(x, y); n++; lock (job.Semaphore) { image.SetPixel(x, imgY - y - 1, pixel); } } } } } Console.WriteLine("Job {0}: Line {1} antialiased, {2} rays", job.JobId, j, n); } }