Beispiel #1
0
 public static Vector3 sub(Point3 p1, Point3 p2, Vector3 dest)
 {
     dest.x = p1.x - p2.x;
     dest.y = p1.y - p2.y;
     dest.z = p1.z - p2.z;
     return dest;
 }
Beispiel #2
0
 public void getPhoton(double randX1, double randY1, double randX2, double randY2, Point3 p, Vector3 dir, Color power)
 {
     double rnd = randX1 * totalArea;
     int j = areas.Length - 1;
     for (int i = 0; i < areas.Length; i++) {
         if (rnd < areas[i]) {
             j = i;
             break;
         }
         rnd -= areas[i]; // try next triangle
     }
     rnd /= areas[j];
     randX1 = rnd;
     double s = Math.Sqrt(1 - randX2);
     float u = (float) (randY2 * s);
     float v = (float) (1 - s);
     float w = 1 - u - v;
     int tri3 = j * 3;
     int index0 = 3 * triangles[tri3 + 0];
     int index1 = 3 * triangles[tri3 + 1];
     int index2 = 3 * triangles[tri3 + 2];
     p.x = w * points[index0 + 0] + u * points[index1 + 0] + v * points[index2 + 0];
     p.y = w * points[index0 + 1] + u * points[index1 + 1] + v * points[index2 + 1];
     p.z = w * points[index0 + 2] + u * points[index1 + 2] + v * points[index2 + 2];
     p.x += 0.001f * ngs[j].x;
     p.y += 0.001f * ngs[j].y;
     p.z += 0.001f * ngs[j].z;
     OrthoNormalBasis onb = OrthoNormalBasis.makeFromW(ngs[j]);
     u = (float) (2 * Math.PI * randX1);
     s = Math.Sqrt(randY1);
     onb.transform(new Vector3((float) (Math.Cos(u) * s), (float) (Math.Sin(u) * s), (float) (Math.Sqrt(1 - randY1))), dir);
     Color.mul((float) Math.PI * areas[j], radiance, power);
 }
Beispiel #3
0
 public static Point3 add(Point3 p, Vector3 v, Point3 dest)
 {
     dest.x = p.x + v.x;
     dest.y = p.y + v.y;
     dest.z = p.z + v.z;
     return dest;
 }
 public void getSamples(ShadingState state)
 {
     if (Vector3.dot(dir, state.getGeoNormal()) < 0 && Vector3.dot(dir, state.getNormal()) < 0)
     {
         // project point onto source plane
         float x = state.getPoint().x - src.x;
         float y = state.getPoint().y - src.y;
         float z = state.getPoint().z - src.z;
         float t = ((x * dir.x) + (y * dir.y) + (z * dir.z));
         if (t >= 0.0)
         {
             x -= (t * dir.x);
             y -= (t * dir.y);
             z -= (t * dir.z);
             if (((x * x) + (y * y) + (z * z)) <= r2)
             {
                 Point3 p = new Point3();
                 p.x = src.x + x;
                 p.y = src.y + y;
                 p.z = src.z + z;
                 LightSample dest = new LightSample();
                 dest.setShadowRay(new Ray(state.getPoint(), p));
                 dest.setRadiance(radiance, radiance);
                 dest.traceShadow(state);
                 state.addSample(dest);
             }
         }
     }
 }
Beispiel #5
0
 public static Point3 blend(Point3 p0, Point3 p1, float blend, Point3 dest)
 {
     dest.x = (1 - blend) * p0.x + blend * p1.x;
     dest.y = (1 - blend) * p0.y + blend * p1.y;
     dest.z = (1 - blend) * p0.z + blend * p1.z;
     return dest;
 }
Beispiel #6
0
 public static Point3 mid(Point3 p1, Point3 p2, Point3 dest)
 {
     dest.x = 0.5f * (p1.x + p2.x);
     dest.y = 0.5f * (p1.y + p2.y);
     dest.z = 0.5f * (p1.z + p2.z);
     return dest;
 }
Beispiel #7
0
 public SphereLight()
 {
     radiance = Color.WHITE;
     numSamples = 4;
     center = new Point3();
     radius = r2 = 1;
 }
Beispiel #8
0
 public Color getRadiance(ShadingState state)
 {
     Point3[] p = new Point3[3];
     if (!state.getTrianglePoints(p))
         return getFillColor(state);
     // transform points into camera space
     Point3 center = state.getPoint();
     Matrix4 w2c = state.getWorldToCamera();
     center = w2c.transformP(center);
     for (int i = 0; i < 3; i++)
         p[i] = w2c.transformP(state.getInstance().transformObjectToWorld(p[i]));
     float cn = 1.0f / (float)Math.Sqrt(center.x * center.x + center.y * center.y + center.z * center.z);
     for (int i = 0, i2 = 2; i < 3; i2 = i, i++)
     {
         // compute orthogonal projection of the shading point onto each
         // triangle edge as in:
         // http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
         float t = (center.x - p[i].x) * (p[i2].x - p[i].x);
         t += (center.y - p[i].y) * (p[i2].y - p[i].y);
         t += (center.z - p[i].z) * (p[i2].z - p[i].z);
         t /= p[i].distanceToSquared(p[i2]);
         float projx = (1 - t) * p[i].x + t * p[i2].x;
         float projy = (1 - t) * p[i].y + t * p[i2].y;
         float projz = (1 - t) * p[i].z + t * p[i2].z;
         float n = 1.0f / (float)Math.Sqrt(projx * projx + projy * projy + projz * projz);
         // check angular width
         float dot = projx * center.x + projy * center.y + projz * center.z;
         if (dot * n * cn >= cosWidth)
             return getLineColor(state);
     }
     return getFillColor(state);
 }
Beispiel #9
0
 public RealtimeBenchmark(bool showGUI, int threads)
 {
     IDisplay display = /*showGUI ? new FastDisplay() :*/ new FileDisplay(false);
     UI.printInfo(UI.Module.BENCH, "Preparing benchmarking scene ...");
     // settings
     parameter("threads", threads);
     // spawn regular priority threads
     parameter("threads.lowPriority", false);
     parameter("resolutionX", 512);
     parameter("resolutionY", 512);
     parameter("aa.min", -3);
     parameter("aa.max", 0);
     parameter("depths.diffuse", 1);
     parameter("depths.reflection", 1);
     parameter("depths.refraction", 0);
     parameter("bucket.order", "hilbert");
     parameter("bucket.size", 32);
     options(SunflowAPI.DEFAULT_OPTIONS);
     // camera
     Point3 eye = new Point3(30, 0, 10.967f);
     Point3 target = new Point3(0, 0, 5.4f);
     Vector3 up = new Vector3(0, 0, 1);
     parameter("transform", Matrix4.lookAt(eye, target, up));
     parameter("fov", 45.0f);
     camera("camera", "pinhole");
     parameter("camera", "camera");
     options(SunflowAPI.DEFAULT_OPTIONS);
     // geometry
     createGeometry();
     // this first render is not timed, it caches the acceleration data
     // structures and tesselations so they won't be
     // included in the main timing
     UI.printInfo(UI.Module.BENCH, "Rendering warmup frame ...");
     render(SunflowAPI.DEFAULT_OPTIONS, display);
     // now disable all output - and run the benchmark
     UI.set(null);
     Timer t = new Timer();
     t.start();
     float phi = 0;
     int frames = 0;
     while (phi < 4 * Math.PI)
     {
         eye.x = 30 * (float)Math.Cos(phi);
         eye.y = 30 * (float)Math.Sin(phi);
         phi += (float)(Math.PI / 30);
         frames++;
         // update camera
         parameter("transform", Matrix4.lookAt(eye, target, up));
         camera("camera", null);
         render(SunflowAPI.DEFAULT_OPTIONS, display);
     }
     t.end();
     UI.set(new ConsoleInterface());
     UI.printInfo(UI.Module.BENCH, "Benchmark results:");
     UI.printInfo(UI.Module.BENCH, "  * Average FPS:         {0,6:0.00", frames / t.seconds());
     UI.printInfo(UI.Module.BENCH, "  * Total time:          {0}", t);
 }
Beispiel #10
0
 public Photon(Point3 p, Vector3 dir, Color power)
 {
     x = p.x;
     y = p.y;
     z = p.z;
     this.dir = dir.encode();
     this.power = power.toRGBE();
     flags = 0;
 }
Beispiel #11
0
 public void getPhoton(double randX1, double randY1, double randX2, double randY2, Point3 p, Vector3 dir, Color power)
 {
     p.set(lightPoint);
     float phi = (float)(2 * Math.PI * randX1);
     float s = (float)Math.Sqrt(randY1 * (1.0f - randY1));
     dir.x = (float)Math.Cos(phi) * s;
     dir.y = (float)Math.Sin(phi) * s;
     dir.z = (float)(1 - 2 * randY1);
     power.set(this.power);
 }
 public DirectionalSpotlight()
 {
     src = new Point3(0, 0, 0);
     dir = new Vector3(0, 0, -1);
     dir.normalize();
     basis = OrthoNormalBasis.makeFromW(dir);
     r = 1;
     r2 = r * r;
     radiance = Color.WHITE;
 }
Beispiel #13
0
 public Photon(Point3 p, Vector3 n, Vector3 dir, Color power, Color diffuse)
 {
     x = p.x;
     y = p.y;
     z = p.z;
     this.dir = dir.encode();
     this.power = power.toRGBE();
     flags = 0;
     normal = n.encode();
     data = diffuse.toRGB();
 }
 public void getPhoton(double randX1, double randY1, double randX2, double randY2, Point3 p, Vector3 dir, Color power)
 {
     float phi = (float)(2 * Math.PI * randX1);
     float s = (float)Math.Sqrt(1.0f - randY1);
     dir.x = r * (float)Math.Cos(phi) * s;
     dir.y = r * (float)Math.Sin(phi) * s;
     dir.z = 0;
     basis.transform(dir);
     Point3.add(src, dir, p);
     dir.set(this.dir);
     power.set(radiance).mul((float)Math.PI * r2);
 }
Beispiel #15
0
 public static Vector3 normal(Point3 p0, Point3 p1, Point3 p2)
 {
     float edge1x = p1.x - p0.x;
     float edge1y = p1.y - p0.y;
     float edge1z = p1.z - p0.z;
     float edge2x = p2.x - p0.x;
     float edge2y = p2.y - p0.y;
     float edge2z = p2.z - p0.z;
     float nx = edge1y * edge2z - edge1z * edge2y;
     float ny = edge1z * edge2x - edge1x * edge2z;
     float nz = edge1x * edge2y - edge1y * edge2x;
     return new Vector3(nx, ny, nz);
 }
Beispiel #16
0
 public static Vector3 normal(Point3 p0, Point3 p1, Point3 p2, Vector3 dest)
 {
     float edge1x = p1.x - p0.x;
     float edge1y = p1.y - p0.y;
     float edge1z = p1.z - p0.z;
     float edge2x = p2.x - p0.x;
     float edge2y = p2.y - p0.y;
     float edge2z = p2.z - p0.z;
     dest.x = edge1y * edge2z - edge1z * edge2y;
     dest.y = edge1z * edge2x - edge1x * edge2z;
     dest.z = edge1x * edge2y - edge1y * edge2x;
     return dest;
 }
Beispiel #17
0
 /**
  * Creates a new ray that points from the given origin to the given
  * direction. The ray has infinite Length. The direction vector is
  * normalized.
  *
  * @param o ray origin
  * @param d ray direction (need not be normalized)
  */
 public Ray(Point3 o, Vector3 d)
 {
     ox = o.x;
     oy = o.y;
     oz = o.z;
     dx = d.x;
     dy = d.y;
     dz = d.z;
     float inf = 1.0f / (float)Math.Sqrt(dx * dx + dy * dy + dz * dz);
     dx *= inf;
     dy *= inf;
     dz *= inf;
     tMin = EPSILON;
     tMax = float.PositiveInfinity;
 }
Beispiel #18
0
 public void getPhoton(double randX1, double randY1, double randX2, double randY2, Point3 p, Vector3 dir, Color power)
 {
     float z = (float)(1 - 2 * randX2);
     float r = (float)Math.Sqrt(Math.Max(0, 1 - z * z));
     float phi = (float)(2 * Math.PI * randY2);
     float x = r * (float)Math.Cos(phi);
     float y = r * (float)Math.Sin(phi);
     p.x = center.x + x * radius;
     p.y = center.y + y * radius;
     p.z = center.z + z * radius;
     OrthoNormalBasis basis = OrthoNormalBasis.makeFromW(new Vector3(x, y, z));
     phi = (float)(2 * Math.PI * randX1);
     float cosPhi = (float)Math.Cos(phi);
     float sinPhi = (float)Math.Sin(phi);
     float sinTheta = (float)Math.Sqrt(randY1);
     float cosTheta = (float)Math.Sqrt(1 - randY1);
     dir.x = cosPhi * sinTheta;
     dir.y = sinPhi * sinTheta;
     dir.z = cosTheta;
     basis.transform(dir);
     power.set(radiance);
     power.mul((float)(Math.PI * Math.PI * 4 * r2));
 }
Beispiel #19
0
 public void getSamples(ShadingState state)
 {
     if (storedPhotons == 0)
         return;
     NearestPhotons np = new NearestPhotons(state.getPoint(), gatherNum, gatherRadius * gatherRadius);
     locatePhotons(np);
     if (np.found < 8)
         return;
     Point3 ppos = new Point3();
     Vector3 pdir = new Vector3();
     Vector3 pvec = new Vector3();
     float invArea = 1.0f / ((float)Math.PI * np.dist2[0]);
     float maxNDist = np.dist2[0] * 0.05f;
     float f2r2 = 1.0f / (filterValue * filterValue * np.dist2[0]);
     float fInv = 1.0f / (1.0f - 2.0f / (3.0f * filterValue));
     for (int i = 1; i <= np.found; i++)
     {
         Photon phot = np.index[i];
         Vector3.decode(phot.dir, pdir);
         float cos = -Vector3.dot(pdir, state.getNormal());
         if (cos > 0.001)
         {
             ppos.set(phot.x, phot.y, phot.z);
             Point3.sub(ppos, state.getPoint(), pvec);
             float pcos = Vector3.dot(pvec, state.getNormal());
             if ((pcos < maxNDist) && (pcos > -maxNDist))
             {
                 LightSample sample = new LightSample();
                 sample.setShadowRay(new Ray(state.getPoint(), pdir.negate()));
                 sample.setRadiance(new Color().setRGBE(np.index[i].power).mul(invArea / cos), Color.BLACK);
                 sample.getDiffuseRadiance().mul((1.0f - (float)Math.Sqrt(np.dist2[i] * f2r2)) * fInv);
                 state.addSample(sample);
             }
         }
     }
 }
Beispiel #20
0
 /**
  * Generate a ray from the origin of camera space toward the specified
  * point.
  *
  * @param p point in world space
  * @return ray from the origin of camera space to the specified point
  */
 public Ray getRay(Point3 p)
 {
     return new Ray(c2w == null ? new Point3(0, 0, 0) : c2w[0].transformP(new Point3(0, 0, 0)), p);
 }
Beispiel #21
0
 /**
  * Creates a bounding box centered around the origin.
  *
  * @param size half edge Length of the bounding box
  */
 public BoundingBox(float size)
 {
     minimum = new Point3(-size, -size, -size);
     maximum = new Point3(size, size, size);
 }
Beispiel #22
0
 /**
  * Creates an empty box. The minimum point will have all components set to
  * positive infinity, and the maximum will have all components set to
  * negative infinity.
  */
 public BoundingBox()
 {
     minimum = new Point3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
     maximum = new Point3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity);
 }
Beispiel #23
0
 /**
  * Checks to see if the specified {@link org.sunflow.math.Point3 point}is
  * inside the volume defined by this box. Returns <code>false</code> if
  * the parameter is <code>null</code>.
  *
  * @param p point to be tested for containment
  * @return <code>true</code> if the point is inside the box,
  *         <code>false</code> otherwise
  */
 public bool contains(Point3 p)
 {
     return((p != null) && (p.x >= minimum.x) && (p.x <= maximum.x) && (p.y >= minimum.y) && (p.y <= maximum.y) && (p.z >= minimum.z) && (p.z <= maximum.z));
 }
Beispiel #24
0
 /**
  * Creates a copy of the given box.
  *
  * @param b bounding box to copy
  */
 public BoundingBox(BoundingBox b)
 {
     minimum = new Point3(b.minimum);
     maximum = new Point3(b.maximum);
 }
Beispiel #25
0
 /**
  * Creates a bounding box containing only the specified point.
  *
  * @param x x coordinate of the point to include
  * @param y y coordinate of the point to include
  * @param z z coordinate of the point to include
  */
 public BoundingBox(float x, float y, float z)
 {
     minimum = new Point3(x, y, z);
     maximum = new Point3(x, y, z);
 }
Beispiel #26
0
 public NearestPhotons(Point3 p, int n, float maxDist2)
 {
     max = n;
     found = 0;
     gotHeap = false;
     px = p.x;
     py = p.y;
     pz = p.z;
     dist2 = new float[n + 1];
     index = new Photon[n + 1];
     dist2[0] = maxDist2;
 }
Beispiel #27
0
 public float distanceTo(Point3 p)
 {
     float dx = x - p.x;
     float dy = y - p.y;
     float dz = z - p.z;
     return (float)Math.Sqrt((dx * dx) + (dy * dy) + (dz * dz));
 }
Beispiel #28
0
 /**
  * Creates a bounding box containing only the specified point.
  *
  * @param p point to include
  */
 public BoundingBox(Point3 p)
     : this(p.x, p.y, p.z)
 {
 }
Beispiel #29
0
 /**
  * Gets the extents vector for the box. This vector is computed as (max -
  * min). Its coordinates are always positive and represent the dimensions of
  * the box along the three axes.
  *
  * @return a refreence to the extent vector
  * @see org.sunflow.math.Vector3#Length()
  */
 public Vector3 getExtents()
 {
     return(Point3.sub(maximum, minimum, new Vector3()));
 }
Beispiel #30
0
            public void Run()
            {
                ByteUtil.InitByteUtil();
                IntersectionState istate = new IntersectionState();
                for (int i = start; i < end; i++)
                {
                    lock (lockObj)
                    {
                        UI.taskUpdate(server.photonCounter);
                        server.photonCounter++;
                        if (UI.taskCanceled())
                            return;
                    }

                    int qmcI = i + seed;

                    double rand = QMC.halton(0, qmcI) * histogram[histogram.Length - 1];
                    int j = 0;
                    while (rand >= histogram[j] && j < histogram.Length)
                        j++;
                    // make sure we didn't pick a zero-probability light
                    if (j == histogram.Length)
                        continue;

                    double randX1 = (j == 0) ? rand / histogram[0] : (rand - histogram[j]) / (histogram[j] - histogram[j - 1]);
                    double randY1 = QMC.halton(1, qmcI);
                    double randX2 = QMC.halton(2, qmcI);
                    double randY2 = QMC.halton(3, qmcI);
                    Point3 pt = new Point3();
                    Vector3 dir = new Vector3();
                    Color power = new Color();
                    server.lights[j].getPhoton(randX1, randY1, randX2, randY2, pt, dir, power);
                    power.mul(scale);
                    Ray r = new Ray(pt, dir);
                    server.scene.trace(r, istate);
                    if (istate.hit())
                        server.shadePhoton(ShadingState.createPhotonState(r, istate, qmcI, map, server), power);
                }
            }
Beispiel #31
0
 public void getPhoton(double randX1, double randY1, double randX2, double randY2, Point3 p, Vector3 dir, Color power)
 {
 }
Beispiel #32
0
 public float distanceToSquared(Point3 p)
 {
     float dx = x - p.x;
     float dy = y - p.y;
     float dz = z - p.z;
     return (dx * dx) + (dy * dy) + (dz * dz);
 }
Beispiel #33
0
 void reset(Point3 p, float maxDist2)
 {
     found = 0;
     gotHeap = false;
     px = p.x;
     py = p.y;
     pz = p.z;
     dist2[0] = maxDist2;
 }
Beispiel #34
0
 public Point3 set(Point3 p)
 {
     x = p.x;
     y = p.y;
     z = p.z;
     return this;
 }
 public bool update(ParameterList pl, SunflowAPI api)
 {
     src = pl.getPoint("source", src);
     dir = pl.getVector("dir", dir);
     dir.normalize();
     r = pl.getFloat("radius", r);
     basis = OrthoNormalBasis.makeFromW(dir);
     r2 = r * r;
     radiance = pl.getColor("radiance", radiance);
     return true;
 }
Beispiel #36
0
 public Point3(Point3 p)
 {
     x = p.x;
     y = p.y;
     z = p.z;
 }
Beispiel #37
0
 private TriangleMesh generate(int[] tris, float[] verts, bool smoothNormals)
 {
     ParameterList pl = new ParameterList();
     pl.addIntegerArray("triangles", tris);
     pl.addPoints("points", ParameterList.InterpolationType.VERTEX, verts);
     if (smoothNormals)
     {
         float[] normals = new float[verts.Length]; // filled with 0's
         Point3 p0 = new Point3();
         Point3 p1 = new Point3();
         Point3 p2 = new Point3();
         Vector3 n = new Vector3();
         for (int i3 = 0; i3 < tris.Length; i3 += 3)
         {
             int v0 = tris[i3 + 0];
             int v1 = tris[i3 + 1];
             int v2 = tris[i3 + 2];
             p0.set(verts[3 * v0 + 0], verts[3 * v0 + 1], verts[3 * v0 + 2]);
             p1.set(verts[3 * v1 + 0], verts[3 * v1 + 1], verts[3 * v1 + 2]);
             p2.set(verts[3 * v2 + 0], verts[3 * v2 + 1], verts[3 * v2 + 2]);
             Point3.normal(p0, p1, p2, n); // compute normal
             // add face normal to each vertex
             // note that these are not normalized so this in fact weights
             // each normal by the area of the triangle
             normals[3 * v0 + 0] += n.x;
             normals[3 * v0 + 1] += n.y;
             normals[3 * v0 + 2] += n.z;
             normals[3 * v1 + 0] += n.x;
             normals[3 * v1 + 1] += n.y;
             normals[3 * v1 + 2] += n.z;
             normals[3 * v2 + 0] += n.x;
             normals[3 * v2 + 1] += n.y;
             normals[3 * v2 + 2] += n.z;
         }
         // normalize all the vectors
         for (int i3 = 0; i3 < normals.Length; i3 += 3)
         {
             n.set(normals[i3 + 0], normals[i3 + 1], normals[i3 + 2]);
             n.normalize();
             normals[i3 + 0] = n.x;
             normals[i3 + 1] = n.y;
             normals[i3 + 2] = n.z;
         }
         pl.addVectors("normals", ParameterList.InterpolationType.VERTEX, normals);
     }
     TriangleMesh m = new TriangleMesh();
     if (m.update(pl, null))
         return m;
     // something failed in creating the mesh, the error message will be
     // printed by the mesh itself - no need to repeat it here
     return null;
 }
Beispiel #38
0
 /**
  * Gets the center of the box, computed as (min + max) / 2.
  *
  * @return a reference to the center of the box
  */
 public Point3 getCenter()
 {
     return(Point3.mid(minimum, maximum, new Point3()));
 }