public override double3 CalculateColor(Scene scene, Traceable traceable, IntersectData data, Ray ray, TraceData traceData) { double2 t = traceable.GetTexCoord(data); return(Sampler.GetColor(t)); }
public static void DrawXAlignedTexturedTriangle(this HdrBuffer image, double3 pStart, double endX1, double endX2, double sideY, double endZ1, double endZ2, double2 tStart, double2 endT1, double2 endT2, Sampler2d sampler, double tpp) { int w1 = image.Size.width - 1, h1 = image.Size.height - 1; if ((pStart.y < 0 && sideY < 0) || (pStart.y > h1 && sideY > h1) || (pStart.x < 0 && endX1 < 0 && endX2 < 0) || (pStart.x > w1 && endX1 > w1 && endX2 > w1)) { return; } if (endX1 > endX2) { Util.Swap(ref endX1, ref endX2); Util.Swap(ref endZ1, ref endZ2); Util.Swap(ref endT1, ref endT2); } double dy = Math.Abs(sideY - pStart.y); var x1Lerp = pStart.x.LerpTo(endX1, dy).GetInterpolator(); var x2Lerp = pStart.x.LerpTo(endX2, dy).GetInterpolator(); var z1Lerp = pStart.z.ZLerpTo(endZ1, dy, pStart.z, endZ1).GetInterpolator(); var z2Lerp = pStart.z.ZLerpTo(endZ2, dy, pStart.z, endZ2).GetInterpolator(); var t1Lerp = tStart.ZLerpTo(endT1, dy, pStart.z, endZ1).GetInterpolator(); var t2Lerp = tStart.ZLerpTo(endT2, dy, pStart.z, endZ2).GetInterpolator(); var yRasterizer = Rasterizer.Create <object> (0, h1, pStart.y, sideY, null, x1Lerp, x2Lerp, z1Lerp, z2Lerp, t1Lerp, t2Lerp ); foreach (var ySample in yRasterizer) { int iy = ySample.Item1.PreciseRound(); double x1 = x1Lerp.Current; double x2 = x2Lerp.Current; double z1 = z1Lerp.Current; double z2 = z2Lerp.Current; double2 t1 = t1Lerp.Current; double2 t2 = t2Lerp.Current; double dx = Math.Abs(x2 - x1); if (dx == 0) { continue; // FIXIT: draw 1 pixel or... } var zLerp = z1.ZLerpTo(z2, dx, z1, z2).GetInterpolator(); var tLerp = t1.ZLerpTo(t2, dx, z1, z2).GetInterpolator(); var xRasterizer = Rasterizer.Create <object> (0, w1, x1, x2, null, zLerp, tLerp); foreach (var xSample in xRasterizer) { int ix = xSample.Item1.PreciseRound(); double z = zLerp.Current; double2 t = tLerp.Current; double lod = Math.Log(tpp * z, 2); if (ShowLods) { // Grayscale lods //double intLod = ( double ) ( int ) lod / sampler.Map.NumLods; //double realLod = lod / sampler.Map.NumLods; //image.Values [ix, iy] = new double3 ( realLod, intLod, intLod ); // Colored lods int intLod = ( int )Math.Abs(lod); if (intLod != 0) { double lodMagnitude = 0.5; double3 lodColor = double3.Zero; if ((intLod & 1) == 1) { lodColor [0] = lodMagnitude; } if ((intLod & 2) == 2) { lodColor [1] = lodMagnitude; } if ((intLod & 4) == 4) { lodColor [2] = lodMagnitude; } double3 c = sampler.GetColor(t, lod); image.Values [ix, iy] = (lodColor + c) * 0.5; } else { image.Values [ix, iy] = sampler.GetColor(t, lod); } } else { image.Values [ix, iy] = sampler.GetColor(t, lod); } } } }
public static void DrawTexturedTriangle(this HdrBuffer image, double3 [] pts, double2 [] t, Sampler2d sampler, double tpp) { int bottomIdx, midIdx, topIdx, separateIdx, coincidentIdx; Classify3Result res = Math3.Classify3(new [] { pts [0].y, pts [1].y, pts [2].y }, out topIdx, out midIdx, out bottomIdx, out separateIdx, out coincidentIdx); if (res == Classify3Result.AllCoincident) { int x = ( int )Math.Round(pts [0].x, MidpointRounding.AwayFromZero); int y = ( int )Math.Round(pts [0].y, MidpointRounding.AwayFromZero); image.Values [x, y] = sampler.GetColor(t [0]); return; } else if (res == Classify3Result.HasCoincidence) { double3 separatePoint = pts [separateIdx]; double3 midPoint = pts [midIdx]; double3 coincidentPoint = pts [coincidentIdx]; double2 separateT = t [separateIdx]; double2 midT = t [midIdx]; double2 coincidentT = t [coincidentIdx]; image.DrawXAlignedTexturedTriangle(separatePoint, midPoint.x, coincidentPoint.x, midPoint.y, midPoint.z, coincidentPoint.z, separateT, midT, coincidentT, sampler, tpp); //image.DrawXAlignedHollowTriangle ( separatePoint, midPoint.x, coincidentPoint.x, midPoint.y, double3.UnitY ); } else { double3 topPoint = pts [topIdx]; double3 midPoint = pts [midIdx]; double3 bottomPoint = pts [bottomIdx]; double k = (midPoint.y - bottomPoint.y) / (topPoint.y - bottomPoint.y); double x2 = k.Lerp(bottomPoint.x, topPoint.x); double2 topT = t [topIdx]; double2 midT = t [midIdx]; double2 bottomT = t [bottomIdx]; double zInv = k.Lerp(1 / bottomPoint.z, 1 / topPoint.z); double z2 = 1 / zInv; double2 coincidentT = k.ZLerp(bottomT, topT, bottomPoint.z, topPoint.z, zInv); image.DrawXAlignedTexturedTriangle(bottomPoint, midPoint.x, x2, midPoint.y, midPoint.z, z2, bottomT, midT, coincidentT, sampler, tpp); image.DrawXAlignedTexturedTriangle(topPoint, midPoint.x, x2, midPoint.y, midPoint.z, z2, topT, midT, coincidentT, sampler, tpp); //image.DrawXAlignedHollowTriangle ( bottomPoint, midPoint.x, x2, midPoint.y, double3.UnitX ); //image.DrawXAlignedHollowTriangle ( topPoint, midPoint.x, x2, midPoint.y, double3.UnitX ); //double3 white = new double3 ( 1, 1, 1 ); //Func <double3, double3, double3> blendFunc = ( bg, fg ) => bg == white ? double3.UnitX : ( bg == double3.UnitY ? double3.UnitZ : double3.UnitY ); //image.DrawYSteppingLine ( bottomPoint, new double2 ( midPoint.x, midPoint.y ), double3.UnitX, true, false, blendFunc ); //image.DrawYSteppingLine ( bottomPoint, new double2 ( x2, midPoint.y ), double3.UnitX, false, false, blendFunc ); //image.DrawYSteppingLine ( topPoint, new double2 ( midPoint.x, midPoint.y ), double3.UnitX, true, true, blendFunc ); //image.DrawYSteppingLine ( topPoint, new double2 ( x2, midPoint.y ), double3.UnitX, false, true, blendFunc ); } }