protected void AddPixel(int x, int y, ref RgbSpectrum r, float w, SamplePixel[] pixelD = null) { //var offset = x + (Height - 1 - y) * Width; var offset = x + (y) * this.Width; if (pixelD == null) { pixelD = pixelData; } if (offset >= this.pixelData.Length) return; if (offset < 0) return; /*Parallel._AtomicAdd(ref pixels[offset].radiance.r, r.r); Parallel._AtomicAdd(ref pixels[offset].radiance.g, r.g); Parallel._AtomicAdd(ref pixels[offset].radiance.b, r.b); Parallel._AtomicAdd(ref pixels[offset].weight, w); */ // var c = new RgbSpectrum(r.XYZ()); #if !DadePixelSampling //r.ToXYZ(); #endif pixelD[offset].Radiance.Add(ref r); pixelD[offset].Weight += w; //r.IsBlack() ? 0f : w; var i = r; //this.frameBuffer.SetPixel(offset, ref i); }
protected virtual void UpdateFrameBuffer() { #if VERBOSE try { #endif var pixelCount = this.Width * this.Height; var sampledPixels = this.pixelData; var pix = new RgbSpectrum(); if (!this.ToneMap) { //lock (lclock) for (int i = 0; i < pixelCount; ++i) { if (this.SplatMode) { if (pixelData[i].Weight <= 0f) continue; pix = new RgbSpectrum(this.Radiance2PixelFloat(pixelData[i].Radiance.c1), this.Radiance2PixelFloat(pixelData[i].Radiance.c2), this.Radiance2PixelFloat(pixelData[i].Radiance.c3)); this.frameBuffer.AddPixel(i, ref pix); } else { ComputePixel(i); } } } else if (ToneMapping != null) { ToneMapping.ComputeImage(); } if (false && this.toneMap != null) { switch (this.toneMap.GetToneMapType()) { case ToneMapType.TONEMAP_LINEAR: var tmparam = (LinearToneMapParams)this.toneMap; for (var j = 0; j < pixelCount; ++j) { if (this.SplatMode) { RgbSpectrum ppx = RgbSpectrum.ZeroSpectrum(); SSE.ComputePixel(ref sampledPixels[j].Radiance, tmparam.scale, ref ppx, gammaTable, GAMMA_TABLE_SIZE); this.SetPixel(j, ref pix); } else { if (!sampledPixels[j].Radiance.IsBlack()) { ComputePixel(j, tmparam.scale); } } } break; case ToneMapType.TONEMAP_REINHARD02: float alpha = .9f; var tm = new Reinhard02ToneMapParams(); //(Reinhard02ToneMapParams)this.toneMap; float preScale = tm.preScale; float postScale = tm.postScale; float burn = tm.burn; var xyzPixels = new SamplePixel[sampledPixels.Length]; float Ywa = 0f; for (int ii = 0; ii < pixelCount; ++ii) { float weight = sampledPixels[ii].Weight; if (weight > 0f) { float invWeight = 1f / weight; RgbSpectrum rgb = sampledPixels[ii].Radiance * invWeight; rgb.XYZ(out xyzPixels[ii].Radiance.c1, out xyzPixels[ii].Radiance.c2, out xyzPixels[ii].Radiance.c3); /* // Convert to XYZ color space xyzPixels[ii].Radiance.c1 = 0.412453f * rgb.c1 + 0.357580f * rgb.c2 + 0.180423f * rgb.c3; xyzPixels[ii].Radiance.c2 = 0.212671f * rgb.c1 + 0.715160f * rgb.c2 + 0.072169f * rgb.c3; xyzPixels[ii].Radiance.c3 = 0.019334f * rgb.c1 + 0.119193f * rgb.c2 + 0.950227f * rgb.c3; */ xyzPixels[ii].Weight = weight; // var xyz = pixelsRadiance[i].XYZ(); Ywa += xyzPixels[ii].Radiance.c2; } } Ywa /= pixelCount; // Avoid division by zero if (Ywa.NearEqual(0f)) Ywa = 1f; float Yw = preScale * alpha * burn; float invY2 = 1f / (Yw * Yw); float pScale = postScale * preScale * alpha / Ywa; for (int ii = 0; ii < pixelCount; ++ii) { var xyz = xyzPixels[ii].Radiance; float ys = xyz.c2; xyz *= pScale * (1f + ys * invY2) / (1f + ys); //xyz.GammaCorrection(); xyz.XYZToRGB(); /* // Convert back to RGB color space sampledPixels[ii].Radiance.c1 = 3.240479f * xyz.c1 - 1.537150f * xyz.c2 - 0.498535f * xyz.c3; sampledPixels[ii].Radiance.c2 = -0.969256f * xyz.c1 + 1.875991f * xyz.c2 + 0.041556f * xyz.c3; sampledPixels[ii].Radiance.c3 = 0.055648f * xyz.c1 - 0.204043f * xyz.c2 + 1.057311f * xyz.c3; this.pixelData[ii].Radiance = sampledPixels[ii].Radiance; */ //pixelData[ii].Weight = 1.0f; /* this.frameBuffer.SetPixel(ii, this.Radiance2PixelFloat(sampledPixels[ii].radiance.c1), this.Radiance2PixelFloat(sampledPixels[ii].radiance.c2), * this.Radiance2PixelFloat(sampledPixels[ii].radiance.c3));*/ //this.SetPixel(ii, ref xyz); this.ComputePixel(ii, ref xyz, 1.0f); /* pix = new RgbSpectrum( this.Radiance2PixelFloat(sampledPixels[ii].Radiance.c1), this.Radiance2PixelFloat(sampledPixels[ii].Radiance.c2), this.Radiance2PixelFloat(sampledPixels[ii].Radiance.c3)); this.SetPixel(ii, ref pix);*/ } break; } } #if VERBOSE } catch (Exception ex) { Tracer.TraceLine(ex.Message); throw ex; } #endif //ClearPixelData(); }
public override void Reset() { lock (lclock) { for (int i = 0; i < pixelData.Length; i++) { pixelData[i] = new SamplePixel(); } this.Samples.Reset(); this.frameBuffer.Clear(); } }
public void Merge(ImageFilmBase b) { if (b.pixelData.Length != pixelData.Length) { throw new ArgumentException("Invalid film size"); } for (int index = 0; index < b.pixelData.Length; index++) { var pixelA = pixelData[index]; var pixelB = b.pixelData[index]; pixelData[index] = new SamplePixel() { Radiance = (pixelA.Radiance + pixelB.Radiance) * 0.5f, Weight = (pixelA.Weight + pixelB.Weight) * 0.5f, }; } }
public void StatsRect(int xs, int ys, int wt, int ht, int colorIndex) { RgbSpectrum col = RgbSpectrum.UnitSpectrum(); //new RgbSpectrum(1f, 0.2f+ rnd.NextFloat()*0.5f, 1f); var w = Math.Min(Width - 1, wt); var h = Math.Min(Height - 1, ht); for (int x = xs; x < MathLab.Clamp(xs + w, 0, Width - 1); x++) { statsImage[x + ys * Width] = new SamplePixel() { Radiance = col, Weight = 1f }; statsImage[x + (MathLab.Clamp(ys + h, 0, Height - 1) * Width)] = new SamplePixel() { Radiance = col, Weight = 1f }; } for (int y = ys; y < MathLab.Clamp(ys + h, 0, Height - 1); y++) { statsImage[xs + y * Width] = new SamplePixel() { Radiance = col, Weight = 1f }; statsImage[MathLab.Clamp(xs + w, 0, Width - 1) + y * Width] = new SamplePixel() { Radiance = col, Weight = 1f }; } }