public static MyDColor Integrate(double x0, double x1, Func <double, MyDColor> f, int num = 15) { double dx = (x1 - x0) / (num - 1); MyDColor acc = new MyDColor(); MyDColor f0 = f(x0); MyDColor f1 = f(x1); acc.R = (f0.R + f1.R) / 2; acc.G = (f0.G + f1.G) / 2; acc.B = (f0.B + f1.B) / 2; for (int i = 1; i < (num - 1); i++) { var fi = f(x0 + i * dx); acc.R += fi.R; acc.G += fi.G; acc.B += fi.B; } acc.R *= dx; acc.G *= dx; acc.B *= dx; return(acc); }
public bool TryGetValues(double dist, ref MyDColor attenuation, ref MyDColor airColorR, ref MyDColor airColorM, ref MyDColor directPart) { double[] values = new double[12]; if (!inters.TryGetValue(dist, values)) { return(false); } attenuation.R = values[0]; attenuation.G = values[1]; attenuation.B = values[2]; airColorR.R = values[3]; airColorR.G = values[4]; airColorR.B = values[5]; airColorM.R = values[6]; airColorM.G = values[7]; airColorM.B = values[8]; directPart.R = values[9]; directPart.G = values[10]; directPart.B = values[11]; return(true); }
private static MyColor ScaleColor(ref MyDColor tot) { double scale = -45.0; var color = new MyColor( (byte)(255 * Math.Max(0.0, Math.Min(1.0, 1 - Math.Exp(scale * tot.R)))), (byte)(255 * Math.Max(0.0, Math.Min(1.0, 1 - Math.Exp(scale * tot.G)))), (byte)(255 * Math.Max(0.0, Math.Min(1.0, 1 - Math.Exp(scale * tot.B))))); return(color); }
private static MyDColor InverseScaleColor(ref MyColor color) { double scale = -45.0; MyDColor tot = new MyDColor() { R = Math.Log(1.0 - color.R / 255.0) / scale, G = Math.Log(1.0 - color.G / 255.0) / scale, B = Math.Log(1.0 - color.B / 255.0) / scale, }; return(tot); }
public MyColor SkyColorAtPointDist(GeoPolar2d p, double dist, MyColor ground, double nDotL) { double theta = skyColor.GetTheta(p); MyDColor attenuation = new MyDColor(); MyDColor airColorR = new MyDColor(); MyDColor airColorM = new MyDColor(); MyDColor directPart = new MyDColor(); aerialPers.Value.TryGetValues(dist, ref attenuation, ref airColorR, ref airColorM, ref directPart); MyColor color = Nishita.CombineForAerialPrespective(ground, theta, nDotL, ambientLight, ref attenuation, ref airColorR, ref airColorM, ref directPart); return(color); }
internal void SkyColorAtPointComputer(double h0, double dist, out MyDColor attenuation, out MyDColor airColorR, out MyDColor airColorM, out MyDColor directPart) { attenuation = ElementLightAP(h0, dist, 0); airColorR = new MyDColor(); airColorM = new MyDColor(); directPart = new MyDColor(); var hitEarth = Intersect(h0, sinPhiSun, 0); if (!hitEarth.HasValue || hitEarth.Value < 0) { // Air has no color if there is no sunlight double lmaxP = Intersect(h0, sinPhiSun, H_atmosphere).Value; double sunAttenuationRbase = TOverBeta(h0, sinPhiSun, lmaxP, H_R); MyDColor sunAttenuationR = new MyDColor() { R = Math.Exp(-BetaR0[(int)Channel.R] * sunAttenuationRbase), G = Math.Exp(-BetaR0[(int)Channel.G] * sunAttenuationRbase), B = Math.Exp(-BetaR0[(int)Channel.B] * sunAttenuationRbase), }; double sunAttenuationM = Math.Exp(-mieScale * BetaM0 * TOverBeta(h0, sinPhiSun, lmaxP, H_M)); // *P_R(theta) var rayR = new MyDColor() { R = BetaR0[(int)Channel.R], G = BetaR0[(int)Channel.G], B = BetaR0[(int)Channel.B], }.Mult(Math.Exp(-h0 / H_R)); // P_M(theta) var rayM = mieScale * BetaM0 * Math.Exp(-h0 / H_M); var airColor = Integrate(0, dist, l => ElementLightAP(h0, l, 0)); airColorR = airColor.Mult(sunAttenuationR).Mult(sunAttenuationM).Mult(rayR); airColorM = airColor.Mult(sunAttenuationR).Mult(sunAttenuationM).Mult(rayM); directPart = sunAttenuationR.Mult(sunAttenuationM).Mult(attenuation); } }
internal static MyColor CombineForAerialPrespective(MyColor ground, double theta, double nDotL, double ambiantLight, ref MyDColor attenuation, ref MyDColor airColorR, ref MyDColor airColorM, ref MyDColor directPart) { var pr = P_R(theta); var pm = P_M(theta); var dground = InverseScaleColor(ref ground); // var ambient = dground.Mult(ambiantLight).Mult(attenuation); //var direct = dground.Mult(nDotL * 2).Mult(directPart); //var total = airColorR.Mult(pr).Add(airColorM.Mult(pm)).Add(ambient).Add(direct); var total = new MyDColor(); total.R = airColorR.R * pr + airColorM.R * pm + (dground.R * ambiantLight * attenuation.R) + (dground.R * nDotL * 2 * directPart.R); total.G = airColorR.G * pr + airColorM.G * pm + (dground.G * ambiantLight * attenuation.G) + (dground.G * nDotL * 2 * directPart.G); total.B = airColorR.B * pr + airColorM.B * pm + (dground.B * ambiantLight * attenuation.B) + (dground.B * nDotL * 2 * directPart.B); return(ScaleColor(ref total)); }