internal unsafe void RenderVectorized(Scene scene, int *rgb) { Camera camera = scene.Camera; // Iterate y then x in order to preserve cache locality. for (int y = 0; y < Height; y++) { int stride = y * Width; for (int x = 0; x < Width; x += VectorPacket256.Packet256Size) { float fx = x; Vector256 <float> Xs = Add(Vector256.Create(fx), SevenToZero); VectorPacket256 dirs = GetPoints(Xs, Vector256.Create((float)(y)), camera); var rayPacket256 = new RayPacket256(camera.Pos, dirs); var SoAcolors = TraceRay(rayPacket256, scene, depth: 0); var AoS = SoAcolors.Transpose(); var intAoS = AoS.ConvertToIntRGB(); int *output = &rgb[(x + stride) * 3]; // Each pixel has 3 fields (RGB) { Store(output, intAoS.Rs); Store(output + 8, intAoS.Gs); Store(output + 16, intAoS.Bs); } } } }
private Intersections MinIntersections(RayPacket256 rayPacket256, Scene scene) { Intersections mins = new Intersections(Intersections.NullDistance, Intersections.NullIndex); for (int i = 0; i < scene.Things.Length; i++) { Vector256 <float> distance = scene.Things[i].Intersect(rayPacket256); if (!Intersections.AllNullIntersections(distance)) { var notNullMask = Compare(distance, Intersections.NullDistance, FloatComparisonMode.NotEqualOrderedNonSignaling); var nullMinMask = Compare(mins.Distances, Intersections.NullDistance, FloatComparisonMode.EqualOrderedNonSignaling); var lessMinMask = Compare(mins.Distances, distance, FloatComparisonMode.GreaterThanOrderedNonSignaling); var minMask = And(notNullMask, Or(nullMinMask, lessMinMask)); var minDis = BlendVariable(mins.Distances, distance, minMask); var minIndices = BlendVariable(mins.ThingIndices.AsSingle(), Vector256.Create(i).AsSingle(), minMask).AsInt32(); mins.Distances = minDis; mins.ThingIndices = minIndices; } } return(mins); }
public override Vector256 <float> Intersect(RayPacket256 rayPacket256) { var denom = VectorPacket256.DotProduct(Norms, rayPacket256.Dirs); var dist = Divide(Add(VectorPacket256.DotProduct(Norms, rayPacket256.Starts), Offsets), Subtract(Vector256 <float> .Zero, denom)); var gtMask = Compare(denom, Vector256 <float> .Zero, FloatComparisonMode.GreaterThanOrderedNonSignaling); return(BlendVariable(dist, Intersections.NullDistance, gtMask)); }
private Vector256 <float> TestRay(RayPacket256 rayPacket256, Scene scene) { var isect = MinIntersections(rayPacket256, scene); if (isect.AllNullIntersections()) { return(Vector256 <float> .Zero); } var isNull = Compare(isect.Distances, Intersections.NullDistance, FloatComparisonMode.EqualOrderedNonSignaling); return(BlendVariable(isect.Distances, Vector256 <float> .Zero, isNull)); }
public override Vector256 <float> Intersect(RayPacket256 rayPacket256) { var eo = Centers - rayPacket256.Starts; var v = VectorPacket256.DotProduct(eo, rayPacket256.Dirs); var zero = Vector256 <float> .Zero; var vLessZeroMask = Compare(v, zero, FloatComparisonMode.OrderedLessThanNonSignaling); var discs = Subtract(Multiply(Radiuses, Radiuses), Subtract(VectorPacket256.DotProduct(eo, eo), Multiply(v, v))); var discLessZeroMask = Compare(discs, zero, FloatComparisonMode.OrderedLessThanNonSignaling); var dists = BlendVariable(Subtract(v, Sqrt(discs)), zero, Or(vLessZeroMask, discLessZeroMask)); var isZero = Compare(dists, zero, FloatComparisonMode.OrderedEqualNonSignaling); return(BlendVariable(dists, Intersections.NullDistance, isZero)); }
private ColorPacket256 Shade(Intersections isect, RayPacket256 rays, Scene scene, int depth) { var ds = rays.Dirs; var pos = isect.Distances * ds + rays.Starts; var normals = scene.Normals(isect.ThingIndices, pos); var reflectDirs = ds - (Multiply(VectorPacket256.DotProduct(normals, ds), Vector256.Create(2.0f)) * normals); var colors = GetNaturalColor(isect.ThingIndices, pos, normals, reflectDirs, scene); if (depth >= MaxDepth) { return(colors + new ColorPacket256(.5f, .5f, .5f)); } return(colors + GetReflectionColor(isect.ThingIndices, pos + (Vector256.Create(0.001f) * reflectDirs), normals, reflectDirs, scene, depth)); }
private ColorPacket256 TraceRay(RayPacket256 rayPacket256, Scene scene, int depth) { var isect = MinIntersections(rayPacket256, scene); if (isect.AllNullIntersections()) { return(ColorPacket256Helper.BackgroundColor); } var color = Shade(isect, rayPacket256, scene, depth); var isNull = Compare(isect.Distances, Intersections.NullDistance, FloatComparisonMode.EqualOrderedNonSignaling); var backgroundColor = ColorPacket256Helper.BackgroundColor.Xs; return(new ColorPacket256(BlendVariable(color.Xs, backgroundColor, isNull), BlendVariable(color.Ys, backgroundColor, isNull), BlendVariable(color.Zs, backgroundColor, isNull))); }
public abstract Vector256 <float> Intersect(RayPacket256 rayPacket256);