Example #1
0
 public void intersectPrimitive(Ray r, int primID, IntersectionState state)
 {
     if (primID < instances.Length)
         instances[primID].intersect(r, state);
     else
         lights[primID - instances.Length].intersect(r, state);
 }
Example #2
0
 public void intersectPrimitive(Ray r, int primID, IntersectionState state)
 {
     // intersect in local space
     float rd2x = r.dx * r.dx;
     float rd2y = r.dy * r.dy;
     float rd2z = r.dz * r.dz;
     float ro2x = r.ox * r.ox;
     float ro2y = r.oy * r.oy;
     float ro2z = r.oz * r.oz;
     // setup the quartic coefficients
     // some common terms could probably be shared across these
     double A = (rd2y * rd2y + rd2z * rd2z + rd2x * rd2x);
     double B = 4 * (r.oy * rd2y * r.dy + r.oz * r.dz * rd2z + r.ox * r.dx * rd2x);
     double C = (-rd2x - rd2y - rd2z + 6 * (ro2y * rd2y + ro2z * rd2z + ro2x * rd2x));
     double D = 2 * (2 * ro2z * r.oz * r.dz - r.oz * r.dz + 2 * ro2x * r.ox * r.dx + 2 * ro2y * r.oy * r.dy - r.ox * r.dx - r.oy * r.dy);
     double E = 3.0f / 8.0f + (-ro2z + ro2z * ro2z - ro2y + ro2y * ro2y - ro2x + ro2x * ro2x);
     // solve equation
     double[] t = Solvers.solveQuartic(A, B, C, D, E);
     if (t != null)
     {
         // early rejection
         if (t[0] >= r.getMax() || t[t.Length - 1] <= r.getMin())
             return;
         // find first intersection in front of the ray
         for (int i = 0; i < t.Length; i++)
         {
             if (t[i] > r.getMin())
             {
                 r.setMax((float)t[i]);
                 state.setIntersection(0, 0, 0);
                 return;
             }
         }
     }
 }
Example #3
0
 private ShadingState(ShadingState previous, IntersectionState istate, Ray r, int i, int d)
 {
     this.r           = r;
     this.istate      = istate;
     this.i           = i;
     this.d           = d;
     this.instance    = istate.instance; // local copy
     this.primitiveID = istate.id;
     this.hitU        = istate.u;
     this.hitV        = istate.v;
     if (previous == null)
     {
         diffuseDepth    = 0;
         reflectionDepth = 0;
         refractionDepth = 0;
     }
     else
     {
         diffuseDepth    = previous.diffuseDepth;
         reflectionDepth = previous.reflectionDepth;
         refractionDepth = previous.refractionDepth;
         this.server     = previous.server;
         this.map        = previous.map;
         this.rx         = previous.rx;
         this.ry         = previous.ry;
         this.i         += previous.i;
         this.d         += previous.d;
     }
     behind        = false;
     cosND         = float.NaN;
     includeLights = includeSpecular = true;
     qmcD0I        = QMC.halton(this.d, this.i);
     qmcD1I        = QMC.halton(this.d + 1, this.i);
     result        = null;
 }
Example #4
0
 /**
  * Get the radiance seen through a particular pixel
  *
  * @param istate intersection state for ray tracing
  * @param rx pixel x coordinate
  * @param ry pixel y coordinate
  * @param lensU DOF sampling variable
  * @param lensV DOF sampling variable
  * @param time motion blur sampling variable
  * @param instance QMC instance seed
  * @return a shading state for the intersected primitive, or
  *         <code>null</code> if nothing is seen through the specifieFd
  *         point
  */
 public ShadingState getRadiance(IntersectionState istate, float rx, float ry, double lensU, double lensV, double time, int instance)
 {
     if (bakingPrimitives == null)
     {
         Ray r = camera.getRay(rx, ry, imageWidth, imageHeight, lensU, lensV, time);
         return(r != null?lightServer.getRadiance(rx, ry, instance, r, istate) : null);
     }
     else
     {
         Ray r = new Ray(rx / imageWidth, ry / imageHeight, -1, 0, 0, 1);
         traceBake(r, istate);
         if (!istate.hit())
         {
             return(null);
         }
         ShadingState state = ShadingState.createState(istate, rx, ry, r, instance, lightServer);
         bakingPrimitives.prepareShadingState(state);
         if (bakingViewDependent)
         {
             state.setRay(camera.getRay(state.getPoint()));
         }
         else
         {
             Point3  p = state.getPoint();
             Vector3 n = state.getNormal();
             // create a ray coming from directly above the point being
             // shaded
             Ray incoming = new Ray(p.x + n.x, p.y + n.y, p.z + n.z, -n.x, -n.y, -n.z);
             incoming.setMax(1);
             state.setRay(incoming);
         }
         lightServer.shadeBakeResult(state);
         return(state);
     }
 }
Example #5
0
 void traceBake(Ray r, IntersectionState state)
 {
     // set the instance as if tracing a regular instanced object
     state.current = bakingInstance;
     // reset object
     state.instance = null;
     bakingAccel.intersect(r, state);
 }
Example #6
0
        public static ShadingState createPhotonState(Ray r, IntersectionState istate, int i, PhotonStore map, LightServer server)
        {
            ShadingState s = new ShadingState(null, istate, r, i, 4);

            s.server = server;
            s.map    = map;
            return(s);
        }
Example #7
0
 public void accumulate(IntersectionState state)
 {
     numEyeRays += state.numEyeRays;
     numShadowRays += state.numShadowRays;
     numReflectionRays += state.numReflectionRays;
     numGlossyRays += state.numGlossyRays;
     numRefractionRays += state.numRefractionRays;
     numRays += state.numRays;
 }
Example #8
0
        public void intersect(Ray r, IntersectionState state)
        {
            Ray localRay = r.transform(w2o.sample(state.time));

            state.current = this;
            geometry.intersect(localRay, state);
            // FIXME: transfer max distance to current ray
            r.setMax(localRay.getMax());
        }
Example #9
0
 public void accumulate(IntersectionState state)
 {
     numEyeRays        += state.numEyeRays;
     numShadowRays     += state.numShadowRays;
     numReflectionRays += state.numReflectionRays;
     numGlossyRays     += state.numGlossyRays;
     numRefractionRays += state.numRefractionRays;
     numRays           += state.numRays;
 }
Example #10
0
        public static ShadingState createState(IntersectionState istate, float rx, float ry, Ray r, int i, LightServer server)
        {
            ShadingState s = new ShadingState(null, istate, r, i, 4);

            s.server = server;
            s.rx     = rx;
            s.ry     = ry;
            return(s);
        }
Example #11
0
        public ShadingState traceFinalGather(ShadingState previous, Ray r, int i)
        {
            if (previous.getDiffuseDepth() >= maxDiffuseDepth)
            {
                return(null);
            }
            IntersectionState istate = previous.getIntersectionState();

            scene.trace(r, istate);
            return(istate.hit() ? ShadingState.createFinalGatherState(previous, r, i) : null);
        }
Example #12
0
 public void intersectPrimitive(Ray r, int primID, IntersectionState state)
 {
     if (primID < instances.Length)
     {
         instances[primID].intersect(r, state);
     }
     else
     {
         lights[primID - instances.Length].intersect(r, state);
     }
 }
Example #13
0
 public void intersect(Ray r, IntersectionState state)
 {
     if (builtTess == 0)
     {
         tesselate();
     }
     if (builtAccel == 0)
     {
         build();
     }
     accel.intersect(r, state);
 }
Example #14
0
        public Color traceRefraction(ShadingState previous, Ray r, int i)
        {
            // limit path depth and disable caustic paths
            if (previous.getRefractionDepth() >= maxRefractionDepth || previous.getDiffuseDepth() > 0)
            {
                return(Color.BLACK);
            }
            IntersectionState istate = previous.getIntersectionState();

            scene.trace(r, istate);
            return(istate.hit() ? shadeHit(ShadingState.createRefractionBounceState(previous, r, i)) : Color.BLACK);
        }
Example #15
0
 public void trace(Ray r, IntersectionState state)
 {
     // reset object
     state.instance = null;
     state.current  = null;
     for (int i = 0; i < infiniteInstanceList.getNumPrimitives(); i++)
     {
         infiniteInstanceList.intersectPrimitive(r, i, state);
     }
     // reset for next accel structure
     state.current = null;
     intAccel.intersect(r, state);
 }
Example #16
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);
                    }
                }
            }
Example #17
0
        public void traceRefractionPhoton(ShadingState previous, Ray r, Color power)
        {
            if (previous.getRefractionDepth() >= maxRefractionDepth)
            {
                return;
            }
            IntersectionState istate = previous.getIntersectionState();

            scene.trace(r, istate);
            if (previous.getIntersectionState().hit())
            {
                // create a new shading context
                ShadingState state = ShadingState.createRefractionBounceState(previous, r, 0);
                shadePhoton(state, power);
            }
        }
Example #18
0
 public void run()
 {
     IntersectionState istate = new IntersectionState();
     while (true)
     {
         uint bx, by;
         lock (renderer)//synchronized (SimpleRenderer.this) {
         {
             if (renderer.bucketCounter >= renderer.numBuckets)
                 return;
             by = renderer.bucketCounter / renderer.numBucketsX;
             bx = renderer.bucketCounter % renderer.numBucketsX;
             renderer.bucketCounter++;
         }
         renderer.renderBucket(bx, by, istate);
     }
 }
Example #19
0
 public void intersectPrimitive(Ray r, int primID, IntersectionState state)
 {
     // intersect in local space
     float qa = r.dx * r.dx + r.dy * r.dy + r.dz * r.dz;
     float qb = 2 * ((r.dx * r.ox) + (r.dy * r.oy) + (r.dz * r.oz));
     float qc = ((r.ox * r.ox) + (r.oy * r.oy) + (r.oz * r.oz)) - 1;
     double[] t = Solvers.solveQuadric(qa, qb, qc);
     if (t != null)
     {
         // early rejection
         if (t[0] >= r.getMax() || t[1] <= r.getMin())
             return;
         if (t[0] > r.getMin())
             r.setMax((float)t[0]);
         else
             r.setMax((float)t[1]);
         state.setIntersection(0, 0, 0);
     }
 }
Example #20
0
        private ShadingState(ShadingState previous, IntersectionState istate, Ray r, int i, int d)
        {
            this.r      = r;
            this.istate = istate;
            this.i      = i;
            this.d      = d;
            time        = istate.time;
            instance    = istate.instance; // local copy
            primitiveID = istate.id;
            hitU        = istate.u;
            hitV        = istate.v;
            hitW        = istate.w;
            // get matrices for current time
            o2w = instance.getObjectToWorld(time);
            w2o = instance.getWorldToObject(time);

            if (previous == null)
            {
                diffuseDepth    = 0;
                reflectionDepth = 0;
                refractionDepth = 0;
            }
            else
            {
                diffuseDepth    = previous.diffuseDepth;
                reflectionDepth = previous.reflectionDepth;
                refractionDepth = previous.refractionDepth;
                server          = previous.server;
                map             = previous.map;
                rx      = previous.rx;
                ry      = previous.ry;
                this.i += previous.i;
                this.d += previous.d;
            }
            behind        = false;
            cosND         = float.NaN;
            includeLights = includeSpecular = true;
            qmcD0I        = QMC.halton(this.d, this.i);
            qmcD1I        = QMC.halton(this.d + 1, this.i);
            result        = null;
            bias          = 0.001f;
        }
Example #21
0
 public void intersectPrimitive(Ray r, int primID, IntersectionState state)
 {
     int i3 = primID * 3;
     float ocx = r.ox - particles[i3 + 0];
     float ocy = r.oy - particles[i3 + 1];
     float ocz = r.oz - particles[i3 + 2];
     float qa = r.dx * r.dx + r.dy * r.dy + r.dz * r.dz;
     float qb = 2 * ((r.dx * ocx) + (r.dy * ocy) + (r.dz * ocz));
     float qc = ((ocx * ocx) + (ocy * ocy) + (ocz * ocz)) - r2;
     double[] t = Solvers.solveQuadric(qa, qb, qc);
     if (t != null)
     {
         // early rejection
         if (t[0] >= r.getMax() || t[1] <= r.getMin())
             return;
         if (t[0] > r.getMin())
             r.setMax((float)t[0]);
         else
             r.setMax((float)t[1]);
         state.setIntersection(primID);
     }
 }
Example #22
0
 public void intersectPrimitive(Ray r, int primID, IntersectionState state)
 {
     // intersect in local space
     float rd2x = r.dx * r.dx;
     float rd2y = r.dy * r.dy;
     float rd2z = r.dz * r.dz;
     float ro2x = r.ox * r.ox;
     float ro2y = r.oy * r.oy;
     float ro2z = r.oz * r.oz;
     // compute some common factors
     double alpha = rd2x + rd2y + rd2z;
     double beta = 2 * (r.ox * r.dx + r.oy * r.dy + r.oz * r.dz);
     double gamma = (ro2x + ro2y + ro2z) - ri2 - ro2;
     // setup quartic coefficients
     double A = alpha * alpha;
     double B = 2 * alpha * beta;
     double C = beta * beta + 2 * alpha * gamma + 4 * ro2 * rd2z;
     double D = 2 * beta * gamma + 8 * ro2 * r.oz * r.dz;
     double E = gamma * gamma + 4 * ro2 * ro2z - 4 * ro2 * ri2;
     // solve equation
     double[] t = Solvers.solveQuartic(A, B, C, D, E);
     if (t != null)
     {
         // early rejection
         if (t[0] >= r.getMax() || t[t.Length - 1] <= r.getMin())
             return;
         // find first intersection in front of the ray
         for (int i = 0; i < t.Length; i++)
         {
             if (t[i] > r.getMin())
             {
                 r.setMax((float)t[i]);
                 state.setIntersection(0, 0, 0);
                 return;
             }
         }
     }
 }
Example #23
0
 public ShadingState getRadiance(float rx, float ry, int i, Ray r, IntersectionState istate)
 {
     lock (lockObj)
     {
         scene.trace(r, istate);
         if (istate.hit())
         {
             ShadingState state = ShadingState.createState(istate, rx, ry, r, i, this);
             state.getInstance().prepareShadingState(state);
             IShader shader = getShader(state);
             if (shader == null)
             {
                 state.setResult(Color.BLACK);
                 return(state);
             }
             if (_shadingCache != null)
             {
                 Color c = lookupShadingCache(state, shader);
                 if (c != null)
                 {
                     state.setResult(c);
                     return(state);
                 }
             }
             state.setResult(shader.getRadiance(state));
             if (_shadingCache != null)
             {
                 addShadingCache(state, shader, state.getResult());
             }
             return(state);
         }
         else
         {
             return(null);
         }
     }
 }
Example #24
0
        public void intersectPrimitiveRobust(Ray r, int primID, IntersectionState state)
        {
            // ray-triangle intersection here
            int tri = 3 * primID;
            int a = 3 * triangles[tri + 0];
            int b = 3 * triangles[tri + 1];
            int c = 3 * triangles[tri + 2];
            float[] stack = state.getRobustStack();
            for (int i = 0, i3 = 0; i < 3; i++, i3 += 3)
            {
                stack[i3 + 0] = points[a + i];
                stack[i3 + 1] = points[b + i];
                stack[i3 + 2] = points[c + i];
            }
            stack[9] = float.PositiveInfinity;
            int stackpos = 0;
            float orgX = r.ox;
            float dirX = r.dx, invDirX = 1 / dirX;
            float orgY = r.oy;
            float dirY = r.dy, invDirY = 1 / dirY;
            float orgZ = r.oz;
            float dirZ = r.dz, invDirZ = 1 / dirZ;
            float t1, t2;
            float minx, maxx;
            float miny, maxy;
            float minz, maxz;
            float mint = r.getMin();
            float maxt = r.getMax();
            while (stackpos >= 0)
            {
                float intervalMin = mint;
                float intervalMax = maxt;
                float p0x = stack[stackpos + 0];
                float p1x = stack[stackpos + 1];
                float p2x = stack[stackpos + 2];
                t1 = ((minx = MathUtils.min(p0x, p1x, p2x)) - orgX) * invDirX;
                t2 = ((maxx = MathUtils.max(p0x, p1x, p2x)) - orgX) * invDirX;
                if (invDirX > 0)
                {
                    if (t1 > intervalMin)
                        intervalMin = t1;
                    if (t2 < intervalMax)
                        intervalMax = t2;
                }
                else
                {
                    if (t2 > intervalMin)
                        intervalMin = t2;
                    if (t1 < intervalMax)
                        intervalMax = t1;
                }
                if (intervalMin > intervalMax)
                {
                    stackpos -= 10;
                    continue;
                }
                float p0y = stack[stackpos + 3];
                float p1y = stack[stackpos + 4];
                float p2y = stack[stackpos + 5];
                t1 = ((miny = MathUtils.min(p0y, p1y, p2y)) - orgY) * invDirY;
                t2 = ((maxy = MathUtils.max(p0y, p1y, p2y)) - orgY) * invDirY;
                if (invDirY > 0)
                {
                    if (t1 > intervalMin)
                        intervalMin = t1;
                    if (t2 < intervalMax)
                        intervalMax = t2;
                }
                else
                {
                    if (t2 > intervalMin)
                        intervalMin = t2;
                    if (t1 < intervalMax)
                        intervalMax = t1;
                }
                if (intervalMin > intervalMax)
                {
                    stackpos -= 10;
                    continue;
                }
                float p0z = stack[stackpos + 6];
                float p1z = stack[stackpos + 7];
                float p2z = stack[stackpos + 8];
                t1 = ((minz = MathUtils.min(p0z, p1z, p2z)) - orgZ) * invDirZ;
                t2 = ((maxz = MathUtils.max(p0z, p1z, p2z)) - orgZ) * invDirZ;
                if (invDirZ > 0)
                {
                    if (t1 > intervalMin)
                        intervalMin = t1;
                    if (t2 < intervalMax)
                        intervalMax = t2;
                }
                else
                {
                    if (t2 > intervalMin)
                        intervalMin = t2;
                    if (t1 < intervalMax)
                        intervalMax = t1;
                }
                if (intervalMin > intervalMax)
                {
                    stackpos -= 10;
                    continue;
                }
                // intersection was found - keep going
                float size = (maxx - minx) + (maxy - miny) + (maxz - minz);
                if (ByteUtil.floatToRawIntBits(stack[stackpos + 9]) == ByteUtil.floatToRawIntBits(size))
                {
                    // L1 norm is 0, we are done
                    r.setMax(intervalMin);
                    triaccel[primID].intersectBox(r, p0x, p0y, p0z, primID, state);
                    return; // safe to return, only one intersection per primitive
                }
                // not small enough yet - subdivide
                float p01x = (p0x + p1x) * 0.5f;
                float p01y = (p0y + p1y) * 0.5f;
                float p01z = (p0z + p1z) * 0.5f;

                float p12x = (p1x + p2x) * 0.5f;
                float p12y = (p1y + p2y) * 0.5f;
                float p12z = (p1z + p2z) * 0.5f;

                float p20x = (p2x + p0x) * 0.5f;
                float p20y = (p2y + p0y) * 0.5f;
                float p20z = (p2z + p0z) * 0.5f;

                // triangle 0
                stack[stackpos + 0] = p0x;
                stack[stackpos + 1] = p01x;
                stack[stackpos + 2] = p20x;
                stack[stackpos + 3] = p0y;
                stack[stackpos + 4] = p01y;
                stack[stackpos + 5] = p20y;
                stack[stackpos + 6] = p0z;
                stack[stackpos + 7] = p01z;
                stack[stackpos + 8] = p20z;
                stack[stackpos + 9] = size;
                stackpos += 10;
                // triangle 1
                stack[stackpos + 0] = p1x;
                stack[stackpos + 1] = p12x;
                stack[stackpos + 2] = p01x;
                stack[stackpos + 3] = p1y;
                stack[stackpos + 4] = p12y;
                stack[stackpos + 5] = p01y;
                stack[stackpos + 6] = p1z;
                stack[stackpos + 7] = p12z;
                stack[stackpos + 8] = p01z;
                stack[stackpos + 9] = size;
                stackpos += 10;
                // triangle 2
                stack[stackpos + 0] = p2x;
                stack[stackpos + 1] = p20x;
                stack[stackpos + 2] = p12x;
                stack[stackpos + 3] = p2y;
                stack[stackpos + 4] = p20y;
                stack[stackpos + 5] = p12y;
                stack[stackpos + 6] = p2z;
                stack[stackpos + 7] = p20z;
                stack[stackpos + 8] = p12z;
                stack[stackpos + 9] = size;
                stackpos += 10;
                // triangle 4
                stack[stackpos + 0] = p20x;
                stack[stackpos + 1] = p12x;
                stack[stackpos + 2] = p01x;
                stack[stackpos + 3] = p20y;
                stack[stackpos + 4] = p12y;
                stack[stackpos + 5] = p01y;
                stack[stackpos + 6] = p20z;
                stack[stackpos + 7] = p12z;
                stack[stackpos + 8] = p01z;
                stack[stackpos + 9] = size;
            }
        }
Example #25
0
 public void intersect(Ray r, IntersectionState state)
 {
     Ray localRay = r.transform(w2o.sample(state.time));
     state.current = this;
     geometry.intersect(localRay, state);
     // FIXME: transfer max distance to current ray
     r.setMax(localRay.getMax());
 }
Example #26
0
 public ShadingState getRadiance(float rx, float ry, float time, int i, int d, Ray r, IntersectionState istate, ShadingCache cache)
 {
     istate.time = time;
     scene.trace(r, istate);
     if (istate.hit())
     {
         ShadingState state = ShadingState.createState(istate, rx, ry, time, r, i, d, this);
         state.getInstance().prepareShadingState(state);
         IShader shader = getShader(state);
         if (shader == null)
         {
             state.setResult(Color.BLACK);
             return(state);
         }
         if (cache != null)
         {
             Color c = cache.lookup(state, shader);
             if (c != null)
             {
                 state.setResult(c);
                 return(state);
             }
         }
         state.setResult(shader.GetRadiance(state));
         if (cache != null)
         {
             cache.add(state, shader, state.getResult());
         }
         checkNanInf(state.getResult());
         return(state);
     }
     else
     {
         return(null);
     }
 }
Example #27
0
 public void accumulateStats(IntersectionState state)
 {
     stats.accumulate(state);
 }
Example #28
0
 public void intersect(Ray r, IntersectionState state)
 {
     float intervalMin = r.getMin();
     float intervalMax = r.getMax();
     float orgX = r.ox;
     float dirX = r.dx, invDirX = 1 / dirX;
     float t1, t2;
     t1 = (bounds.getMinimum().x - orgX) * invDirX;
     t2 = (bounds.getMaximum().x - orgX) * invDirX;
     if (invDirX > 0)
     {
         if (t1 > intervalMin)
             intervalMin = t1;
         if (t2 < intervalMax)
             intervalMax = t2;
     }
     else
     {
         if (t2 > intervalMin)
             intervalMin = t2;
         if (t1 < intervalMax)
             intervalMax = t1;
     }
     if (intervalMin > intervalMax)
         return;
     float orgY = r.oy;
     float dirY = r.dy, invDirY = 1 / dirY;
     t1 = (bounds.getMinimum().y - orgY) * invDirY;
     t2 = (bounds.getMaximum().y - orgY) * invDirY;
     if (invDirY > 0)
     {
         if (t1 > intervalMin)
             intervalMin = t1;
         if (t2 < intervalMax)
             intervalMax = t2;
     }
     else
     {
         if (t2 > intervalMin)
             intervalMin = t2;
         if (t1 < intervalMax)
             intervalMax = t1;
     }
     if (intervalMin > intervalMax)
         return;
     float orgZ = r.oz;
     float dirZ = r.dz, invDirZ = 1 / dirZ;
     t1 = (bounds.getMinimum().z - orgZ) * invDirZ;
     t2 = (bounds.getMaximum().z - orgZ) * invDirZ;
     if (invDirZ > 0)
     {
         if (t1 > intervalMin)
             intervalMin = t1;
         if (t2 < intervalMax)
             intervalMax = t2;
     }
     else
     {
         if (t2 > intervalMin)
             intervalMin = t2;
         if (t1 < intervalMax)
             intervalMax = t1;
     }
     if (intervalMin > intervalMax)
         return;
     // box is hit at [intervalMin, intervalMax]
     orgX += intervalMin * dirX;
     orgY += intervalMin * dirY;
     orgZ += intervalMin * dirZ;
     // locate starting point inside the grid
     // and set up 3D-DDA vars
     int indxX, indxY, indxZ;
     int stepX, stepY, stepZ;
     int stopX, stopY, stopZ;
     float deltaX, deltaY, deltaZ;
     float tnextX, tnextY, tnextZ;
     // stepping factors along X
     indxX = (int)((orgX - bounds.getMinimum().x) * invVoxelwx);
     if (indxX < 0)
         indxX = 0;
     else if (indxX >= nx)
         indxX = nx - 1;
     if (Math.Abs(dirX) < 1e-6f)
     {
         stepX = 0;
         stopX = indxX;
         deltaX = 0;
         tnextX = float.PositiveInfinity;
     }
     else if (dirX > 0)
     {
         stepX = 1;
         stopX = nx;
         deltaX = voxelwx * invDirX;
         tnextX = intervalMin + ((indxX + 1) * voxelwx + bounds.getMinimum().x - orgX) * invDirX;
     }
     else
     {
         stepX = -1;
         stopX = -1;
         deltaX = -voxelwx * invDirX;
         tnextX = intervalMin + (indxX * voxelwx + bounds.getMinimum().x - orgX) * invDirX;
     }
     // stepping factors along Y
     indxY = (int)((orgY - bounds.getMinimum().y) * invVoxelwy);
     if (indxY < 0)
         indxY = 0;
     else if (indxY >= ny)
         indxY = ny - 1;
     if (Math.Abs(dirY) < 1e-6f)
     {
         stepY = 0;
         stopY = indxY;
         deltaY = 0;
         tnextY = float.PositiveInfinity;
     }
     else if (dirY > 0)
     {
         stepY = 1;
         stopY = ny;
         deltaY = voxelwy * invDirY;
         tnextY = intervalMin + ((indxY + 1) * voxelwy + bounds.getMinimum().y - orgY) * invDirY;
     }
     else
     {
         stepY = -1;
         stopY = -1;
         deltaY = -voxelwy * invDirY;
         tnextY = intervalMin + (indxY * voxelwy + bounds.getMinimum().y - orgY) * invDirY;
     }
     // stepping factors along Z
     indxZ = (int)((orgZ - bounds.getMinimum().z) * invVoxelwz);
     if (indxZ < 0)
         indxZ = 0;
     else if (indxZ >= nz)
         indxZ = nz - 1;
     if (Math.Abs(dirZ) < 1e-6f)
     {
         stepZ = 0;
         stopZ = indxZ;
         deltaZ = 0;
         tnextZ = float.PositiveInfinity;
     }
     else if (dirZ > 0)
     {
         stepZ = 1;
         stopZ = nz;
         deltaZ = voxelwz * invDirZ;
         tnextZ = intervalMin + ((indxZ + 1) * voxelwz + bounds.getMinimum().z - orgZ) * invDirZ;
     }
     else
     {
         stepZ = -1;
         stopZ = -1;
         deltaZ = -voxelwz * invDirZ;
         tnextZ = intervalMin + (indxZ * voxelwz + bounds.getMinimum().z - orgZ) * invDirZ;
     }
     int cellstepX = stepX;
     int cellstepY = stepY * nx;
     int cellstepZ = stepZ * ny * nx;
     int cell = indxX + indxY * nx + indxZ * ny * nx;
     // trace through the grid
     for (; ; )
     {
         if (tnextX < tnextY && tnextX < tnextZ)
         {
             if (cells[cell] != null)
             {
                 foreach (int i in cells[cell])
                     primitives.intersectPrimitive(r, i, state);
                 if (state.hit() && (r.getMax() < tnextX && r.getMax() < intervalMax))
                     return;
             }
             intervalMin = tnextX;
             if (intervalMin > intervalMax)
                 return;
             indxX += stepX;
             if (indxX == stopX)
                 return;
             tnextX += deltaX;
             cell += cellstepX;
         }
         else if (tnextY < tnextZ)
         {
             if (cells[cell] != null)
             {
                 foreach (int i in cells[cell])
                     primitives.intersectPrimitive(r, i, state);
                 if (state.hit() && (r.getMax() < tnextY && r.getMax() < intervalMax))
                     return;
             }
             intervalMin = tnextY;
             if (intervalMin > intervalMax)
                 return;
             indxY += stepY;
             if (indxY == stopY)
                 return;
             tnextY += deltaY;
             cell += cellstepY;
         }
         else
         {
             if (cells[cell] != null)
             {
                 foreach (int i in cells[cell])
                     primitives.intersectPrimitive(r, i, state);
                 if (state.hit() && (r.getMax() < tnextZ && r.getMax() < intervalMax))
                     return;
             }
             intervalMin = tnextZ;
             if (intervalMin > intervalMax)
                 return;
             indxZ += stepZ;
             if (indxZ == stopZ)
                 return;
             tnextZ += deltaZ;
             cell += cellstepZ;
         }
     }
 }
Example #29
0
            public BucketThread(int threadID, BucketRenderer renderer)
            {
                this.threadID = threadID;
				istate = new IntersectionState();
                this.renderer = renderer;
                thread = new Thread(new ThreadStart(run));
                thread.IsBackground = true;
            }
Example #30
0
 public void intersect(Ray r, IntersectionState state)
 {
     if (builtTess == 0)
         tesselate();
     if (builtAccel == 0)
         build();
     accel.intersect(r, state);
 }
Example #31
0
 private void intersectTriangleKensler(Ray r, int primID, IntersectionState state)
 {
     int tri = 3 * primID;
     int a = 3 * triangles[tri + 0];
     int b = 3 * triangles[tri + 1];
     int c = 3 * triangles[tri + 2];
     float edge0x = points[b + 0] - points[a + 0];
     float edge0y = points[b + 1] - points[a + 1];
     float edge0z = points[b + 2] - points[a + 2];
     float edge1x = points[a + 0] - points[c + 0];
     float edge1y = points[a + 1] - points[c + 1];
     float edge1z = points[a + 2] - points[c + 2];
     float nx = edge0y * edge1z - edge0z * edge1y;
     float ny = edge0z * edge1x - edge0x * edge1z;
     float nz = edge0x * edge1y - edge0y * edge1x;
     float v = r.dot(nx, ny, nz);
     float iv = 1 / v;
     float edge2x = points[a + 0] - r.ox;
     float edge2y = points[a + 1] - r.oy;
     float edge2z = points[a + 2] - r.oz;
     float va = nx * edge2x + ny * edge2y + nz * edge2z;
     float t = iv * va;
     if (!r.isInside(t))
         return;
     float ix = edge2y * r.dz - edge2z * r.dy;
     float iy = edge2z * r.dx - edge2x * r.dz;
     float iz = edge2x * r.dy - edge2y * r.dx;
     float v1 = ix * edge1x + iy * edge1y + iz * edge1z;
     float beta = iv * v1;
     if (beta < 0)
         return;
     float v2 = ix * edge0x + iy * edge0y + iz * edge0z;
     if ((v1 + v2) * v > v * v)
         return;
     float gamma = iv * v2;
     if (gamma < 0)
         return;
     r.setMax(t);
     state.setIntersection(primID, beta, gamma);
 }
Example #32
0
 public void intersectBox(Ray r, float hx, float hy, float hz, int primID, IntersectionState state)
 {
     switch (k)
     {
         case 0:
             {
                 float hu = hy;
                 float hv = hz;
                 float u = hu * bnu + hv * bnv + bnd;
                 if (u < 0.0f)
                     u = 0;
                 float v = hu * cnu + hv * cnv + cnd;
                 if (v < 0.0f)
                     v = 0;
                 state.setIntersection(primID, u, v);
                 return;
             }
         case 1:
             {
                 float hu = hz;
                 float hv = hx;
                 float u = hu * bnu + hv * bnv + bnd;
                 if (u < 0.0f)
                     u = 0;
                 float v = hu * cnu + hv * cnv + cnd;
                 if (v < 0.0f)
                     v = 0;
                 state.setIntersection(primID, u, v);
                 return;
             }
         case 2:
             {
                 float hu = hx;
                 float hv = hy;
                 float u = hu * bnu + hv * bnv + bnd;
                 if (u < 0.0f)
                     u = 0;
                 float v = hu * cnu + hv * cnv + cnd;
                 if (v < 0.0f)
                     v = 0;
                 state.setIntersection(primID, u, v);
                 return;
             }
     }
 }
Example #33
0
            public void intersectPrimitive(Ray r, int primID, IntersectionState state)
            {
                float uv00 = 0, uv01 = 0, uv10 = 0, uv11 = 0, uv20 = 0, uv21 = 0;
                switch (triangleMesh.uvs.interp)
                {
                    case ParameterList.InterpolationType.NONE:
                    case ParameterList.InterpolationType.FACE:
                    default:
                        return;
                    case ParameterList.InterpolationType.VERTEX:
                        {
                            int tri = 3 * primID;
                            int index0 = triangleMesh.triangles[tri + 0];
                            int index1 = triangleMesh.triangles[tri + 1];
                            int index2 = triangleMesh.triangles[tri + 2];
                            int i20 = 2 * index0;
                            int i21 = 2 * index1;
                            int i22 = 2 * index2;
                            float[] uvs = triangleMesh.uvs.data;
                            uv00 = uvs[i20 + 0];
                            uv01 = uvs[i20 + 1];
                            uv10 = uvs[i21 + 0];
                            uv11 = uvs[i21 + 1];
                            uv20 = uvs[i22 + 0];
                            uv21 = uvs[i22 + 1];
                            break;

                        }
                    case ParameterList.InterpolationType.FACEVARYING:
                        {
                            int idx = (3 * primID) << 1;
                            float[] uvs = triangleMesh.uvs.data;
                            uv00 = uvs[idx + 0];
                            uv01 = uvs[idx + 1];
                            uv10 = uvs[idx + 2];
                            uv11 = uvs[idx + 3];
                            uv20 = uvs[idx + 4];
                            uv21 = uvs[idx + 5];
                            break;
                        }
                }

                double edge1x = uv10 - uv00;
                double edge1y = uv11 - uv01;
                double edge2x = uv20 - uv00;
                double edge2y = uv21 - uv01;
                double pvecx = r.dy * 0 - r.dz * edge2y;
                double pvecy = r.dz * edge2x - r.dx * 0;
                double pvecz = r.dx * edge2y - r.dy * edge2x;
                double qvecx, qvecy, qvecz;
                double u, v;
                double det = edge1x * pvecx + edge1y * pvecy + 0 * pvecz;
                if (det > 0)
                {
                    double tvecx = r.ox - uv00;
                    double tvecy = r.oy - uv01;
                    double tvecz = r.oz;
                    u = (tvecx * pvecx + tvecy * pvecy + tvecz * pvecz);
                    if (u < 0.0 || u > det)
                        return;
                    qvecx = tvecy * 0 - tvecz * edge1y;
                    qvecy = tvecz * edge1x - tvecx * 0;
                    qvecz = tvecx * edge1y - tvecy * edge1x;
                    v = (r.dx * qvecx + r.dy * qvecy + r.dz * qvecz);
                    if (v < 0.0 || u + v > det)
                        return;
                }
                else if (det < 0)
                {
                    double tvecx = r.ox - uv00;
                    double tvecy = r.oy - uv01;
                    double tvecz = r.oz;
                    u = (tvecx * pvecx + tvecy * pvecy + tvecz * pvecz);
                    if (u > 0.0 || u < det)
                        return;
                    qvecx = tvecy * 0 - tvecz * edge1y;
                    qvecy = tvecz * edge1x - tvecx * 0;
                    qvecz = tvecx * edge1y - tvecy * edge1x;
                    v = (r.dx * qvecx + r.dy * qvecy + r.dz * qvecz);
                    if (v > 0.0 || u + v < det)
                        return;
                }
                else
                    return;
                double inv_det = 1.0 / det;
                float t = (float)((edge2x * qvecx + edge2y * qvecy + 0 * qvecz) * inv_det);
                if (r.isInside(t))
                {
                    r.setMax(t);
                    state.setIntersection(primID, (float)(u * inv_det), (float)(v * inv_det));
                }
            }
Example #34
0
 public void intersect(Ray r, IntersectionState state)
 {
     for (int i = 0; i < n; i++)
         primitives.intersectPrimitive(r, i, state);
 }
Example #35
0
 public void intersectPrimitive(Ray r, int primID, IntersectionState state)
 {
     instances[primID].intersect(r, state);
 }
Example #36
0
        public void renderBucket(uint bx, uint by, IntersectionState istate)
        {
            // pixel sized extents
            int x0 = (int)(bx * 32);
            int y0 = (int)(by * 32);
            int bw = Math.Min(32, imageWidth - x0);
            int bh = Math.Min(32, imageHeight - y0);

            Color[] bucketRGB = new Color[bw * bh];

            for (int y = 0, i = 0; y < bh; y++)
            {
                for (int x = 0; x < bw; x++, i++)
                {
                    ShadingState state = scene.getRadiance(istate, x0 + x, imageHeight - 1 - (y0 + y), 0.0, 0.0, 0.0, 0);
                    bucketRGB[i] = (state != null) ? state.getResult() : Color.BLACK;
                }
            }
            // update pixels
            display.imageUpdate(x0, y0, bw, bh, bucketRGB);
        }
Example #37
0
        public void intersectPrimitive(Ray r, int primID, IntersectionState state)
        {
            // alternative test -- disabled for now
            // intersectPrimitiveRobust(r, primID, state);

            if (triaccel != null)
            {
                // optional fast intersection method
                triaccel[primID].intersect(r, primID, state);
                return;
            }
            intersectTriangleKensler(r, primID, state);
        }
Example #38
0
        public void intersect(Ray r, IntersectionState state)
        {
            float intervalMin = r.getMin();
            float intervalMax = r.getMax();
            float orgX = r.ox;
            float dirX = r.dx, invDirX = 1 / dirX;
            float t1, t2;

                t1 = (bounds.getMinimum ().x - orgX) * invDirX;
                t2 = (bounds.getMaximum ().x - orgX) * invDirX;
                if (invDirX > 0) {
                    if (t1 > intervalMin)
                        intervalMin = t1;
                    if (t2 < intervalMax)
                        intervalMax = t2;
                } else {
                    if (t2 > intervalMin)
                        intervalMin = t2;
                    if (t1 < intervalMax)
                        intervalMax = t1;
                }
                if (intervalMin > intervalMax)
                    return;
                float orgY = r.oy;
                float dirY = r.dy, invDirY = 1 / dirY;
                t1 = (bounds.getMinimum ().y - orgY) * invDirY;
                t2 = (bounds.getMaximum ().y - orgY) * invDirY;
                if (invDirY > 0) {
                    if (t1 > intervalMin)
                        intervalMin = t1;
                    if (t2 < intervalMax)
                        intervalMax = t2;
                } else {
                    if (t2 > intervalMin)
                        intervalMin = t2;
                    if (t1 < intervalMax)
                        intervalMax = t1;
                }
                if (intervalMin > intervalMax)
                    return;
                float orgZ = r.oz;
                float dirZ = r.dz, invDirZ = 1 / dirZ;
                t1 = (bounds.getMinimum ().z - orgZ) * invDirZ;
                t2 = (bounds.getMaximum ().z - orgZ) * invDirZ;
                if (invDirZ > 0) {
                    if (t1 > intervalMin)
                        intervalMin = t1;
                    if (t2 < intervalMax)
                        intervalMax = t2;
                } else {
                    if (t2 > intervalMin)
                        intervalMin = t2;
                    if (t1 < intervalMax)
                        intervalMax = t1;
                }
                if (intervalMin > intervalMax)
                    return;

                // compute custom offsets from direction sign bit
                int offsetXFront = (int)((uint)(ByteUtil.floatToRawIntBits (dirX) & (1 << 31)) >> 30);//>>>
                int offsetYFront = (int)((uint)(ByteUtil.floatToRawIntBits (dirY) & (1 << 31)) >> 30);//>>>
                int offsetZFront = (int)((uint)(ByteUtil.floatToRawIntBits (dirZ) & (1 << 31)) >> 30);//>>>

                int offsetXBack = offsetXFront ^ 2;
                int offsetYBack = offsetYFront ^ 2;
                int offsetZBack = offsetZFront ^ 2;

                IntersectionState.StackNode[] stack = state.getStack ();
                int stackPos = 0;
                int node = 0;

                while (true) {
                    int tn = tree [node];
                    int axis = tn & (3 << 30);
                    int offset = tn & ~(3 << 30);
                    switch (axis) {
                    case 0:
                        {
                            float d = (ByteUtil.intBitsToFloat (tree [node + 1]) - orgX) * invDirX;
                            int back = offset + offsetXBack;
                            node = back;
                            if (d < intervalMin)
                                continue;
                            node = offset + offsetXFront; // front
                            if (d > intervalMax)
                                continue;
                            // push back node
                            stack [stackPos].node = back;
                            stack [stackPos].near = (d >= intervalMin) ? d : intervalMin;
                            stack [stackPos].far = intervalMax;
                            stackPos++;
                            // update ray interval for front node
                            intervalMax = (d <= intervalMax) ? d : intervalMax;
                            continue;
                        }
                    case 1 << 30:
                        {
                            // y axis
                            float d = (ByteUtil.intBitsToFloat (tree [node + 1]) - orgY) * invDirY;
                            int back = offset + offsetYBack;
                            node = back;
                            if (d < intervalMin)
                                continue;
                            node = offset + offsetYFront; // front
                            if (d > intervalMax)
                                continue;
                            // push back node
                            stack [stackPos].node = back;
                            stack [stackPos].near = (d >= intervalMin) ? d : intervalMin;
                            stack [stackPos].far = intervalMax;
                            stackPos++;
                            // update ray interval for front node
                            intervalMax = (d <= intervalMax) ? d : intervalMax;
                            continue;
                        }
                    case 2 << 30:
                        {
                            // z axis
                            float d = (ByteUtil.intBitsToFloat (tree [node + 1]) - orgZ) * invDirZ;
                            int back = offset + offsetZBack;
                            node = back;
                            if (d < intervalMin)
                                continue;
                            node = offset + offsetZFront; // front
                            if (d > intervalMax)
                                continue;
                            // push back node
                            stack [stackPos].node = back;
                            stack [stackPos].near = (d >= intervalMin) ? d : intervalMin;
                            stack [stackPos].far = intervalMax;
                            stackPos++;
                            // update ray interval for front node
                            intervalMax = (d <= intervalMax) ? d : intervalMax;
                            continue;
                        }
                    default:
                        {
                            // leaf - test some objects
                            int n = tree [node + 1];
                            while (n > 0) {
                                primitiveList.intersectPrimitive (r, primitives [offset], state);
                                n--;
                                offset++;
                            }
                            if (r.getMax () < intervalMax)
                                return;
                            do {
                                // stack is empty?
                                if (stackPos == 0)
                                    return;
                                // move back up the stack
                                stackPos--;
                                intervalMin = stack [stackPos].near;
                                if (r.getMax () < intervalMin)
                                    continue;
                                node = stack [stackPos].node;
                                intervalMax = stack [stackPos].far;
                                break;
                            } while (true);
                            break;
                        }
                    } // switch
                } // traversal loop
        }
Example #39
0
 public void intersect(Ray r, int primID, IntersectionState state)
 {
     switch (k)
     {
         case 0:
             {
                 float det = 1.0f / (r.dx + nu * r.dy + nv * r.dz);
                 float t = (nd - r.ox - nu * r.oy - nv * r.oz) * det;
                 if (!r.isInside(t))
                     return;
                 float hu = r.oy + t * r.dy;
                 float hv = r.oz + t * r.dz;
                 float u = hu * bnu + hv * bnv + bnd;
                 if (u < 0.0f)
                     return;
                 float v = hu * cnu + hv * cnv + cnd;
                 if (v < 0.0f)
                     return;
                 if (u + v > 1.0f)
                     return;
                 r.setMax(t);
                 state.setIntersection(primID, u, v);
                 return;
             }
         case 1:
             {
                 float det = 1.0f / (r.dy + nu * r.dz + nv * r.dx);
                 float t = (nd - r.oy - nu * r.oz - nv * r.ox) * det;
                 if (!r.isInside(t))
                     return;
                 float hu = r.oz + t * r.dz;
                 float hv = r.ox + t * r.dx;
                 float u = hu * bnu + hv * bnv + bnd;
                 if (u < 0.0f)
                     return;
                 float v = hu * cnu + hv * cnv + cnd;
                 if (v < 0.0f)
                     return;
                 if (u + v > 1.0f)
                     return;
                 r.setMax(t);
                 state.setIntersection(primID, u, v);
                 return;
             }
         case 2:
             {
                 float det = 1.0f / (r.dz + nu * r.dx + nv * r.dy);
                 float t = (nd - r.oz - nu * r.ox - nv * r.oy) * det;
                 if (!r.isInside(t))
                     return;
                 float hu = r.ox + t * r.dx;
                 float hv = r.oy + t * r.dy;
                 float u = hu * bnu + hv * bnv + bnd;
                 if (u < 0.0f)
                     return;
                 float v = hu * cnu + hv * cnv + cnd;
                 if (v < 0.0f)
                     return;
                 if (u + v > 1.0f)
                     return;
                 r.setMax(t);
                 state.setIntersection(primID, u, v);
                 return;
             }
     }
 }
Example #40
0
 public ShadingState getRadiance(float rx, float ry, int i, Ray r, IntersectionState istate)
 {
     lock (lockObj)
     {
         scene.trace(r, istate);
         if (istate.hit())
         {
             ShadingState state = ShadingState.createState(istate, rx, ry, r, i, this);
             state.getInstance().prepareShadingState(state);
             IShader shader = getShader(state);
             if (shader == null)
             {
                 state.setResult(Color.BLACK);
                 return state;
             }
             if (_shadingCache != null)
             {
                 Color c = lookupShadingCache(state, shader);
                 if (c != null)
                 {
                     state.setResult(c);
                     return state;
                 }
             }
             state.setResult(shader.getRadiance(state));
             if (_shadingCache != null)
                 addShadingCache(state, shader, state.getResult());
             return state;
         }
         else
             return null;
     }
 }
Example #41
0
 public void intersectPrimitive(Ray r, int primID, IntersectionState state)
 {
     float intervalMin = r.getMin();
     float intervalMax = r.getMax();
     float orgX = r.ox;
     float orgY = r.oy;
     float orgZ = r.oz;
     float dirX = r.dx, invDirX = 1 / dirX;
     float dirY = r.dy, invDirY = 1 / dirY;
     float dirZ = r.dz, invDirZ = 1 / dirZ;
     float t1, t2;
     t1 = (-1 - orgX) * invDirX;
     t2 = (+1 - orgX) * invDirX;
     int curr = -1;
     if (invDirX > 0)
     {
         if (t1 > intervalMin)
         {
             intervalMin = t1;
             curr = 0;
         }
         if (t2 < intervalMax)
             intervalMax = t2;
         if (intervalMin > intervalMax)
             return;
     }
     else
     {
         if (t2 > intervalMin)
         {
             intervalMin = t2;
             curr = 1;
         }
         if (t1 < intervalMax)
             intervalMax = t1;
         if (intervalMin > intervalMax)
             return;
     }
     t1 = (-1 - orgY) * invDirY;
     t2 = (+1 - orgY) * invDirY;
     if (invDirY > 0)
     {
         if (t1 > intervalMin)
         {
             intervalMin = t1;
             curr = 2;
         }
         if (t2 < intervalMax)
             intervalMax = t2;
         if (intervalMin > intervalMax)
             return;
     }
     else
     {
         if (t2 > intervalMin)
         {
             intervalMin = t2;
             curr = 3;
         }
         if (t1 < intervalMax)
             intervalMax = t1;
         if (intervalMin > intervalMax)
             return;
     }
     t1 = (-1 - orgZ) * invDirZ;
     t2 = (+1 - orgZ) * invDirZ;
     if (invDirZ > 0)
     {
         if (t1 > intervalMin)
         {
             intervalMin = t1;
             curr = 4;
         }
         if (t2 < intervalMax)
             intervalMax = t2;
         if (intervalMin > intervalMax)
             return;
     }
     else
     {
         if (t2 > intervalMin)
         {
             intervalMin = t2;
             curr = 5;
         }
         if (t1 < intervalMax)
             intervalMax = t1;
         if (intervalMin > intervalMax)
             return;
     }
     // box is hit at [intervalMin, intervalMax]
     orgX += intervalMin * dirX;
     orgY += intervalMin * dirY;
     orgZ += intervalMin * dirZ;
     // locate starting point inside the grid
     // and set up 3D-DDA vars
     int indxX, indxY, indxZ;
     int stepX, stepY, stepZ;
     int stopX, stopY, stopZ;
     float deltaX, deltaY, deltaZ;
     float tnextX, tnextY, tnextZ;
     // stepping factors along X
     indxX = (int)((orgX + 1) * invVoxelwx);
     if (indxX < 0)
         indxX = 0;
     else if (indxX >= nx)
         indxX = nx - 1;
     if (Math.Abs(dirX) < 1e-6f)
     {
         stepX = 0;
         stopX = indxX;
         deltaX = 0;
         tnextX = float.PositiveInfinity;
     }
     else if (dirX > 0)
     {
         stepX = 1;
         stopX = nx;
         deltaX = voxelwx * invDirX;
         tnextX = intervalMin + ((indxX + 1) * voxelwx - 1 - orgX) * invDirX;
     }
     else
     {
         stepX = -1;
         stopX = -1;
         deltaX = -voxelwx * invDirX;
         tnextX = intervalMin + (indxX * voxelwx - 1 - orgX) * invDirX;
     }
     // stepping factors along Y
     indxY = (int)((orgY + 1) * invVoxelwy);
     if (indxY < 0)
         indxY = 0;
     else if (indxY >= ny)
         indxY = ny - 1;
     if (Math.Abs(dirY) < 1e-6f)
     {
         stepY = 0;
         stopY = indxY;
         deltaY = 0;
         tnextY = float.PositiveInfinity;
     }
     else if (dirY > 0)
     {
         stepY = 1;
         stopY = ny;
         deltaY = voxelwy * invDirY;
         tnextY = intervalMin + ((indxY + 1) * voxelwy - 1 - orgY) * invDirY;
     }
     else
     {
         stepY = -1;
         stopY = -1;
         deltaY = -voxelwy * invDirY;
         tnextY = intervalMin + (indxY * voxelwy - 1 - orgY) * invDirY;
     }
     // stepping factors along Z
     indxZ = (int)((orgZ + 1) * invVoxelwz);
     if (indxZ < 0)
         indxZ = 0;
     else if (indxZ >= nz)
         indxZ = nz - 1;
     if (Math.Abs(dirZ) < 1e-6f)
     {
         stepZ = 0;
         stopZ = indxZ;
         deltaZ = 0;
         tnextZ = float.PositiveInfinity;
     }
     else if (dirZ > 0)
     {
         stepZ = 1;
         stopZ = nz;
         deltaZ = voxelwz * invDirZ;
         tnextZ = intervalMin + ((indxZ + 1) * voxelwz - 1 - orgZ) * invDirZ;
     }
     else
     {
         stepZ = -1;
         stopZ = -1;
         deltaZ = -voxelwz * invDirZ;
         tnextZ = intervalMin + (indxZ * voxelwz - 1 - orgZ) * invDirZ;
     }
     // are we starting inside the cube
     bool isInside = inside(indxX, indxY, indxZ) && bounds.contains(r.ox, r.oy, r.oz);
     // trace through the grid
     for (; ; )
     {
         if (inside(indxX, indxY, indxZ) != isInside)
         {
             // we hit a boundary
             r.setMax(intervalMin);
             // if we are inside, the last bit needs to be flipped
             if (isInside)
                 curr ^= 1;
             state.setIntersection(curr);
             return;
         }
         if (tnextX < tnextY && tnextX < tnextZ)
         {
             curr = dirX > 0 ? 0 : 1;
             intervalMin = tnextX;
             if (intervalMin > intervalMax)
                 return;
             indxX += stepX;
             if (indxX == stopX)
                 return;
             tnextX += deltaX;
         }
         else if (tnextY < tnextZ)
         {
             curr = dirY > 0 ? 2 : 3;
             intervalMin = tnextY;
             if (intervalMin > intervalMax)
                 return;
             indxY += stepY;
             if (indxY == stopY)
                 return;
             tnextY += deltaY;
         }
         else
         {
             curr = dirZ > 0 ? 4 : 5;
             intervalMin = tnextZ;
             if (intervalMin > intervalMax)
                 return;
             indxZ += stepZ;
             if (indxZ == stopZ)
                 return;
             tnextZ += deltaZ;
         }
     }
 }
Example #42
0
 public ShadingState getRadiance(float rx, float ry, float time, int i, int d, Ray r, IntersectionState istate, ShadingCache cache)
 {
     istate.time = time;
     scene.trace(r, istate);
     if (istate.hit()) {
         ShadingState state = ShadingState.createState(istate, rx, ry, time, r, i, d, this);
         state.getInstance().prepareShadingState(state);
         IShader shader = getShader(state);
         if (shader == null) {
             state.setResult(Color.BLACK);
             return state;
         }
         if (cache != null) {
             Color c = cache.lookup(state, shader);
             if (c != null) {
                 state.setResult(c);
                 return state;
             }
         }
         state.setResult(shader.GetRadiance(state));
         if (cache != null)
             cache.add(state, shader, state.getResult());
         checkNanInf(state.getResult());
         return state;
     } else
         return null;
 }
Example #43
0
 public void intersectPrimitive(Ray r, int primID, IntersectionState state)
 {
     float intervalMin = float.NegativeInfinity;
     float intervalMax = float.PositiveInfinity;
     float orgX = r.ox;
     float invDirX = 1 / r.dx;
     float t1, t2;
     t1 = (minX - orgX) * invDirX;
     t2 = (maxX - orgX) * invDirX;
     int sideIn = -1, sideOut = -1;
     if (invDirX > 0)
     {
         if (t1 > intervalMin)
         {
             intervalMin = t1;
             sideIn = 0;
         }
         if (t2 < intervalMax)
         {
             intervalMax = t2;
             sideOut = 1;
         }
     }
     else
     {
         if (t2 > intervalMin)
         {
             intervalMin = t2;
             sideIn = 1;
         }
         if (t1 < intervalMax)
         {
             intervalMax = t1;
             sideOut = 0;
         }
     }
     if (intervalMin > intervalMax)
         return;
     float orgY = r.oy;
     float invDirY = 1 / r.dy;
     t1 = (minY - orgY) * invDirY;
     t2 = (maxY - orgY) * invDirY;
     if (invDirY > 0)
     {
         if (t1 > intervalMin)
         {
             intervalMin = t1;
             sideIn = 2;
         }
         if (t2 < intervalMax)
         {
             intervalMax = t2;
             sideOut = 3;
         }
     }
     else
     {
         if (t2 > intervalMin)
         {
             intervalMin = t2;
             sideIn = 3;
         }
         if (t1 < intervalMax)
         {
             intervalMax = t1;
             sideOut = 2;
         }
     }
     if (intervalMin > intervalMax)
         return;
     float orgZ = r.oz;
     float invDirZ = 1 / r.dz;
     t1 = (minZ - orgZ) * invDirZ; // no front wall
     t2 = (maxZ - orgZ) * invDirZ;
     if (invDirZ > 0)
     {
         if (t1 > intervalMin)
         {
             intervalMin = t1;
             sideIn = 4;
         }
         if (t2 < intervalMax)
         {
             intervalMax = t2;
             sideOut = 5;
         }
     }
     else
     {
         if (t2 > intervalMin)
         {
             intervalMin = t2;
             sideIn = 5;
         }
         if (t1 < intervalMax)
         {
             intervalMax = t1;
             sideOut = 4;
         }
     }
     if (intervalMin > intervalMax)
         return;
     if (r.isInside(intervalMin))
     {
         r.setMax(intervalMin);
         state.setIntersection(sideIn, 0, 0);
     }
     else if (r.isInside(intervalMax))
     {
         r.setMax(intervalMax);
         state.setIntersection(sideOut, 0, 0);
     }
 }
Example #44
0
 public void intersectPrimitive(Ray r, int primID, IntersectionState state)
 {
     instances[primID].intersect(r, state);
 }
Example #45
0
        private void renderBucket(IDisplay display, int bx, int by, int threadID, IntersectionState istate)
        {
            // pixel sized extents
            int x0 = bx * bucketSize;
            int y0 = by * bucketSize;
            int bw = Math.Min(bucketSize, imageWidth - x0);
            int bh = Math.Min(bucketSize, imageHeight - y0);

            // prepare bucket
            display.imagePrepare(x0, y0, bw, bh, threadID);

            Color[] bucketRGB = new Color[bw * bh];
			float[] bucketAlpha = new float[bw * bh];

            // subpixel extents
            int sx0 = x0 * subPixelSize - fs;
            int sy0 = y0 * subPixelSize - fs;
            int sbw = bw * subPixelSize + fs * 2;
            int sbh = bh * subPixelSize + fs * 2;

            // round up to align with maximum step size
            sbw = (sbw + (maxStepSize - 1)) & (~(maxStepSize - 1));
            sbh = (sbh + (maxStepSize - 1)) & (~(maxStepSize - 1));
            // extra padding as needed
            if (maxStepSize > 1)
            {
                sbw++;
                sbh++;
            }
            // allocate bucket memory
            ImageSample[] samples = new ImageSample[sbw * sbh];
            // allocate samples and compute jitter offsets
            float invSubPixelSize = 1.0f / subPixelSize;
            for (int y = 0, index = 0; y < sbh; y++)
            {
                for (int x = 0; x < sbw; x++, index++)
                {
                    int sx = sx0 + x;
                    int sy = sy0 + y;
					int j = sx & (sigmaLength - 1);
					int k = sy & (sigmaLength - 1);
					int i = (j << sigmaOrder) + QMC.sigma(k, sigmaOrder);
					float dx = useJitter ? (float) QMC.halton(0, k) : 0.5f;
					float dy = useJitter ? (float) QMC.halton(0, j) : 0.5f;
                    float rx = (sx + dx) * invSubPixelSize;
                    float ry = (sy + dy) * invSubPixelSize;
                    ry = imageHeight - ry;
                    samples[index] = new ImageSample(rx, ry, i);
                }
            }
            for (int x = 0; x < sbw - 1; x += maxStepSize)
                for (int y = 0; y < sbh - 1; y += maxStepSize)
                    refineSamples(samples, sbw, x, y, maxStepSize, thresh, istate);
            if (dumpBuckets)
            {
                UI.printInfo(UI.Module.BCKT, "Dumping bucket [{0}, {1}] to file ...", bx, by);
				GenericBitmap bitmap = new GenericBitmap(sbw, sbh);
				for (int y = sbh - 1, index = 0; y >= 0; y--)
                    for (int x = 0; x < sbw; x++, index++)
						bitmap.writePixel(x, y, samples[index].c, samples[index].alpha);
                bitmap.save(string.Format("bucket_{0}_{1}.png", bx, by));
            }
            if (displayAA)
            {
                // color coded image of what is visible
                float invArea = invSubPixelSize * invSubPixelSize;
                for (int y = 0, index = 0; y < bh; y++)
                {
                    for (int x = 0; x < bw; x++, index++)
                    {
                        int sampled = 0;
                        for (int i = 0; i < subPixelSize; i++)
                        {
                            for (int j = 0; j < subPixelSize; j++)
                            {
                                int sx = x * subPixelSize + fs + i;
                                int sy = y * subPixelSize + fs + j;
                                int s = sx + sy * sbw;
                                sampled += samples[s].sampled() ? 1 : 0;
                            }
                        }
                        bucketRGB[index] = new Color(sampled * invArea);
						bucketAlpha[index] = 1.0f;
                    }
                }
            }
            else
            {
                // filter samples into pixels
                float cy = imageHeight - (y0 + 0.5f);
                for (int y = 0, index = 0; y < bh; y++, cy--)
                {
                    float cx = x0 + 0.5f;
                    for (int x = 0; x < bw; x++, index++, cx++)
                    {
                        Color c = Color.black();
						float a = 0.0f;
                        float weight = 0.0f;
                        for (int j = -fs, sy = y * subPixelSize; j <= fs; j++, sy++)
                        {
                            for (int i = -fs, sx = x * subPixelSize, s = sx + sy * sbw; i <= fs; i++, sx++, s++)
                            {
                                float dx = samples[s].rx - cx;
                                if (Math.Abs(dx) > fhs)
                                    continue;
                                float dy = samples[s].ry - cy;
                                if (Math.Abs(dy) > fhs)
                                    continue;
                                float f = filter.get(dx, dy);
                                c.madd(f, samples[s].c);
								a += f * samples[s].alpha;
                                weight += f;
                            }
                        }
						float invWeight = 1.0f / weight;
						c.mul(invWeight);
						a *= invWeight;
                        bucketRGB[index] = c;
						bucketAlpha[index] = a;
					}
                }
            }
            // update pixels
            display.imageUpdate(x0, y0, bw, bh, bucketRGB, bucketAlpha);
        }
Example #46
0
 public Color traceShadow(Ray r, IntersectionState state)
 {
     state.numShadowRays++;
     trace(r, state);
     return(state.hit() ? Color.WHITE : Color.BLACK);
 }
Example #47
0
 public void intersectPrimitive(Ray r, int primID, IntersectionState state)
 {
     if (r.getMax() == float.PositiveInfinity)
         state.setIntersection(0, 0, 0);
 }
Example #48
0
 private void computeSubPixel(ImageSample sample, IntersectionState istate)
 {
     float x = sample.rx;
     float y = sample.ry;
     double q0 = QMC.halton(1, sample.i);
     double q1 = QMC.halton(2, sample.i);
     double q2 = QMC.halton(3, sample.i);
     if (superSampling > 1)
     {
         // multiple sampling
         sample.add(scene.getRadiance(istate, x, y, q1, q2, q0, sample.i, 4, null));
         for (int i = 1; i < superSampling; i++)
         {
             double time = QMC.mod1(q0 + i * invSuperSampling);
             double lensU = QMC.mod1(q1 + QMC.halton(0, i));
             double lensV = QMC.mod1(q2 + QMC.halton(1, i));
             sample.add(scene.getRadiance(istate, x, y, lensU, lensV, time, sample.i + i, 4, null));
         }
         sample.scale((float)invSuperSampling);
     }
     else
     {
         // single sample
         sample.set(scene.getRadiance(istate, x, y, q1, q2, q0, sample.i, 4, null));
     }
 }
Example #49
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);
                }
            }
Example #50
0
        private void refineSamples(ImageSample[] samples, int sbw, int x, int y, int stepSize, float thresh, IntersectionState istate)
        {
            int dx = stepSize;
            int dy = stepSize * sbw;
            int i00 = x + y * sbw;
            ImageSample s00 = samples[i00];
            ImageSample s01 = samples[i00 + dy];
            ImageSample s10 = samples[i00 + dx];
            ImageSample s11 = samples[i00 + dx + dy];
            if (!s00.sampled())
                computeSubPixel(s00, istate);
            if (!s01.sampled())
                computeSubPixel(s01, istate);
            if (!s10.sampled())
                computeSubPixel(s10, istate);
            if (!s11.sampled())
                computeSubPixel(s11, istate);
            if (stepSize > minStepSize)
            {
                if (s00.isDifferent(s01, thresh) || s00.isDifferent(s10, thresh) || s00.isDifferent(s11, thresh) || s01.isDifferent(s11, thresh) || s10.isDifferent(s11, thresh) || s01.isDifferent(s10, thresh))
                {
                    stepSize >>= 1;
                    thresh *= 2;
                    refineSamples(samples, sbw, x, y, stepSize, thresh, istate);
                    refineSamples(samples, sbw, x + stepSize, y, stepSize, thresh, istate);
                    refineSamples(samples, sbw, x, y + stepSize, stepSize, thresh, istate);
                    refineSamples(samples, sbw, x + stepSize, y + stepSize, stepSize, thresh, istate);
                    return;
                }
            }

            // interpolate remaining samples
            float ds = 1.0f / stepSize;
            for (int i = 0; i <= stepSize; i++)
                for (int j = 0; j <= stepSize; j++)
                    if (!samples[x + i + (y + j) * sbw].processed())
                        ImageSample.bilerp(samples[x + i + (y + j) * sbw], s00, s01, s10, s11, i * ds, j * ds);
        }