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); } } } }
public Camera(VectorPacket256 pos, VectorPacket256 forward, VectorPacket256 up, VectorPacket256 right) { Pos = pos; Forward = forward; Up = up; Right = right; }
public static Vector256 <float> DotProduct(VectorPacket256 left, VectorPacket256 right) { var x2 = Multiply(left.Xs, right.Xs); var y2 = Multiply(left.Ys, right.Ys); var z2 = Multiply(left.Zs, right.Zs); return(Add(Add(x2, y2), z2)); }
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)); }
public Surface(Func <VectorPacket256, ColorPacket256> Diffuse, VectorPacket256 Specular, Func <VectorPacket256, Vector256 <float> > Reflect, float Roughness) { this.Diffuse = Diffuse; this.Specular = Specular; this.Reflect = Reflect; this.Roughness = Roughness; }
public static Camera Create(VectorPacket256 pos, VectorPacket256 lookAt) { VectorPacket256 forward = (lookAt - pos).Normalize(); VectorPacket256 down = new VectorPacket256(Vector256 <float> .Zero, Vector256.Create(-1.0f), Vector256 <float> .Zero); Vector256 <float> OnePointFive = Vector256.Create(1.5f); VectorPacket256 right = OnePointFive * VectorPacket256.CrossProduct(forward, down).Normalize(); VectorPacket256 up = OnePointFive * VectorPacket256.CrossProduct(forward, right).Normalize(); return(new Camera(pos, forward, up, right)); }
public Vector256 <float> Reflect(Vector256 <int> things, VectorPacket256 pos) { Vector256 <float> rfl = Vector256.Create(1.0f); for (int i = 0; i < Things.Length; i++) { Vector256 <float> mask = CompareEqual(things, Vector256.Create(i)).AsSingle(); rfl = BlendVariable(rfl, Things[i].Surface.Reflect(pos), mask); } return(rfl); }
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)); }
public VectorPacket256 Normals(Vector256 <int> things, VectorPacket256 pos) { VectorPacket256 norms = new VectorPacket256(1, 1, 1); for (int i = 0; i < Things.Length; i++) { Vector256 <float> mask = CompareEqual(things, Vector256.Create(i)).AsSingle(); var n = Things[i].Normals(pos); norms.Xs = BlendVariable(norms.Xs, n.Xs, mask); norms.Ys = BlendVariable(norms.Ys, n.Ys, mask); norms.Zs = BlendVariable(norms.Zs, n.Zs, mask); } return(norms); }
public static Int32RGBPacket256 ConvertToIntRGB(this VectorPacket256 colors) { var rsMask = Compare(colors.Xs, One, FloatComparisonMode.OrderedGreaterThanNonSignaling); var gsMask = Compare(colors.Ys, One, FloatComparisonMode.OrderedGreaterThanNonSignaling); var bsMask = Compare(colors.Zs, One, FloatComparisonMode.OrderedGreaterThanNonSignaling); var rs = BlendVariable(colors.Xs, One, rsMask); var gs = BlendVariable(colors.Ys, One, gsMask); var bs = BlendVariable(colors.Zs, One, bsMask); var rsInt = ConvertToVector256Int32(Multiply(rs, Max)); var gsInt = ConvertToVector256Int32(Multiply(gs, Max)); var bsInt = ConvertToVector256Int32(Multiply(bs, Max)); return(new Int32RGBPacket256(rsInt, gsInt, bsInt)); }
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 GetReflectionColor(Vector256 <int> things, VectorPacket256 pos, VectorPacket256 norms, VectorPacket256 rds, Scene scene, int depth) { return(scene.Reflect(things, pos) * TraceRay(new RayPacket256(pos, rds), scene, depth + 1)); }
private ColorPacket256 GetNaturalColor(Vector256 <int> things, VectorPacket256 pos, VectorPacket256 norms, VectorPacket256 rds, Scene scene) { var colors = ColorPacket256Helper.DefaultColor; for (int i = 0; i < scene.Lights.Length; i++) { var lights = scene.Lights[i]; var zero = Vector256 <float> .Zero; var colorPacket = lights.Colors; var ldis = lights.Positions - pos; var livec = ldis.Normalize(); var neatIsectDis = TestRay(new RayPacket256(pos, livec), scene); // is in shadow? var mask1 = Compare(neatIsectDis, ldis.Lengths, FloatComparisonMode.LessThanOrEqualOrderedNonSignaling); var mask2 = Compare(neatIsectDis, zero, FloatComparisonMode.NotEqualOrderedNonSignaling); var isInShadow = And(mask1, mask2); Vector256 <float> illum = VectorPacket256.DotProduct(livec, norms); Vector256 <float> illumGraterThanZero = Compare(illum, zero, FloatComparisonMode.GreaterThanOrderedNonSignaling); var tmpColor1 = illum * colorPacket; var defaultRGB = zero; Vector256 <float> lcolorR = BlendVariable(defaultRGB, tmpColor1.Xs, illumGraterThanZero); Vector256 <float> lcolorG = BlendVariable(defaultRGB, tmpColor1.Ys, illumGraterThanZero); Vector256 <float> lcolorB = BlendVariable(defaultRGB, tmpColor1.Zs, illumGraterThanZero); ColorPacket256 lcolor = new ColorPacket256(lcolorR, lcolorG, lcolorB); Vector256 <float> specular = VectorPacket256.DotProduct(livec, rds.Normalize()); Vector256 <float> specularGraterThanZero = Compare(specular, zero, FloatComparisonMode.GreaterThanOrderedNonSignaling); var difColor = new ColorPacket256(1, 1, 1); var splColor = new ColorPacket256(1, 1, 1); var roughness = Vector256.Create(1.0f); for (int j = 0; j < scene.Things.Length; j++) { Vector256 <float> thingMask = CompareEqual(things, Vector256.Create(j)).AsSingle(); Vector256 <float> rgh = Vector256.Create(scene.Things[j].Surface.Roughness); var dif = scene.Things[j].Surface.Diffuse(pos); var spl = scene.Things[j].Surface.Specular; roughness = BlendVariable(roughness, rgh, thingMask); difColor.Xs = BlendVariable(difColor.Xs, dif.Xs, thingMask); difColor.Ys = BlendVariable(difColor.Ys, dif.Ys, thingMask); difColor.Zs = BlendVariable(difColor.Zs, dif.Zs, thingMask); splColor.Xs = BlendVariable(splColor.Xs, spl.Xs, thingMask); splColor.Ys = BlendVariable(splColor.Ys, spl.Ys, thingMask); splColor.Zs = BlendVariable(splColor.Zs, spl.Zs, thingMask); } var tmpColor2 = VectorMath.Pow(specular, roughness) * colorPacket; Vector256 <float> scolorR = BlendVariable(defaultRGB, tmpColor2.Xs, specularGraterThanZero); Vector256 <float> scolorG = BlendVariable(defaultRGB, tmpColor2.Ys, specularGraterThanZero); Vector256 <float> scolorB = BlendVariable(defaultRGB, tmpColor2.Zs, specularGraterThanZero); ColorPacket256 scolor = new ColorPacket256(scolorR, scolorG, scolorB); var oldColor = colors; colors = colors + ColorPacket256Helper.Times(difColor, lcolor) + ColorPacket256Helper.Times(splColor, scolor); colors = new ColorPacket256(BlendVariable(colors.Xs, oldColor.Xs, isInShadow), BlendVariable(colors.Ys, oldColor.Ys, isInShadow), BlendVariable(colors.Zs, oldColor.Zs, isInShadow)); } return(colors); }
public LightPacket256(Vector pos, Color col) { Positions = new VectorPacket256(pos.X, pos.Y, pos.Z); Colors = new ColorPacket256(col.R, col.G, col.B); }
public RayPacket256(VectorPacket256 starts, VectorPacket256 dirs) { Starts = starts; Dirs = dirs; }
public override VectorPacket256 Normals(VectorPacket256 pos) { return((pos - Centers).Normalize()); }
public SpherePacket256(VectorPacket256 centers, Vector256 <float> radiuses, Surface surface) : base(surface) { Centers = centers; Radiuses = radiuses; }
public PlanePacket256(VectorPacket256 norms, Vector256 <float> offsets, Surface surface) : base(surface) { Norms = norms; Offsets = offsets; }
public override VectorPacket256 Normals(VectorPacket256 pos) { return(Norms); }
public static VectorPacket256 CrossProduct(VectorPacket256 left, VectorPacket256 right) { return(new VectorPacket256(Subtract(Multiply(left.Ys, right.Zs), Multiply(left.Zs, right.Ys)), Subtract(Multiply(left.Zs, right.Xs), Multiply(left.Xs, right.Zs)), Subtract(Multiply(left.Xs, right.Ys), Multiply(left.Ys, right.Xs)))); }
public abstract VectorPacket256 Normals(VectorPacket256 pos);