Beispiel #1
0
        public virtual void  irradianceEstimate(RGBColor irrad, Vector3D position, Vector3D normal, float maxDist, int noPhotons)
        {
            float ALPHA       = 0.918f;
            float MBETA       = -1.953f;
            float DENOMFACTOR = 1.0f / (1.0f - (float)System.Math.Exp(MBETA));

            NearestPhotons np = new NearestPhotons(noPhotons, maxDist, position);

            irrad.set(0.0f);

            // locate the nearest photons
            locatePhotons(np, 1);

            // if less than MINPHOTONS return
            if (np.found < RaytracerPhotonmapping.SceneConstants.MIN_PHOTONS)
            {
                return;
            }

            Vector3D direction = new Vector3D();

            float mittrs = MBETA / (2.0f * (float)np.dist2[0]);

            // sum irrandiance from all photons
            for (int i = 1; i <= np.found; i++)
            {
                Photon p = getPhoton(np.indices[i]);

                // the toCartesian call and following if can be omitted (for speed)
                // if the scene does not have any thin surfaces
                p.toCartesian(direction);

                if (direction.dot(normal) < 0.0)
                {
                    float gaussWeight = 1.0f - (1.0f - (float)System.Math.Exp((float)p.position.distanceSqr(position) * mittrs)) * DENOMFACTOR;

                    irrad.add(p.power.scaleNew(gaussWeight));
                }
            }

            // estimate of density
            irrad.scale(ALPHA / (float)(System.Math.PI * np.dist2[0]));
        }
Beispiel #2
0
        public virtual Photon store(RGBColor power, Vector3D position, Vector3D direction, Vector3D surfaceNormal)
        {
            storedPhotons_++;

            Photon photon = new Photon();

            photon.precomputedIrradiance = false;

            photon.power    = new RGBColor(power);
            photon.position = new Vector3D(position);

            photon.number = storedPhotons_;

            photon.toSpherical(direction);
            photon.surfaceToSpherical(surfaceNormal);

            position.updateMinMax(bboxMin, bboxMax);

            photons.Add(photon);

            return(photon);
        }
Beispiel #3
0
            public void ThreadProc()
            {
                Vector3D surfaceDirection = new Vector3D();

                for (int i = start; i <= stop; i++)
                {
                    Photon p = mainInstance.getPhoton(i);

                    p.accumPower = new RGBColor();
                    p.surfaceToCartesian(surfaceDirection);

                    mainInstance.radianceEstimate(p.accumPower, p.position, surfaceDirection, maxDist, noPhotons);

                    p.precomputedIrradiance = true;
                }

                // signal!
                lock (this)
                {
                    done = true;
                }
            }
Beispiel #4
0
        public virtual void  balance()
        {
            if (storedPhotons_ > 1)
            {
                Photon[] pa1;
                Photon[] pa2;

                pa1 = new Photon[storedPhotons_ + 1];
                pa2 = new Photon[storedPhotons_ + 1];

                for (int i = 0; i <= storedPhotons_; i++)
                {
                    pa2[i] = getPhoton(i);
                }

                balanceSegment(pa1, pa2, 1, 1, storedPhotons_);

                // reorganise balance kd-tree (make a heap)
                int foo = 1;
                int j   = 1;
                int d;

                Photon fooPhoton = getPhoton(j);

                for (int i = 1; i <= storedPhotons_; i++)
                {
                    d      = pa1[j].number;
                    pa1[j] = null;

                    if (d != foo)
                    {
                        photons[j] = getPhoton(d);
                        getPhoton(d);
                    }
                    else
                    {
                        photons[j] = fooPhoton;
                        System.Object generatedAux = fooPhoton;

                        if (i < storedPhotons_)
                        {
                            for (; foo <= storedPhotons_; foo++)
                            {
                                if (pa1[foo] != null)
                                {
                                    break;
                                }
                            }

                            fooPhoton = getPhoton(foo);

                            j = foo;
                        }

                        continue;
                    }

                    j = d;
                }
            }

            halfStoredPhotons = (storedPhotons_ / 2) - 1;
        }
Beispiel #5
0
        public virtual void  locatePhotonsPrecomputed(Vector3D normal, NearestPhotons np, int index)
        {
            double dist1, dist2;
            Photon p = getPhoton(index);

            if (index < halfStoredPhotons)
            {
                dist1 = np.position.get(p.plane) - p.position.get(p.plane);

                if (dist1 > 0.0)
                {
                    // if dist1 is positive search right plane
                    locatePhotonsPrecomputed(normal, np, (2 * index) + 1);

                    if (dist1 * dist1 < np.dist2[0])
                    {
                        locatePhotonsPrecomputed(normal, np, (2 * index));
                    }
                }
                else
                {
                    // dist1 is negative search left first
                    locatePhotonsPrecomputed(normal, np, (2 * index));

                    if (dist1 * dist1 < np.dist2[0])
                    {
                        locatePhotonsPrecomputed(normal, np, (2 * index) + 1);
                    }
                }
            }

            // compute squared distance between current photon and np.position
            dist2 = p.position.distanceSqr(np.position);

            //assert(p.precomputedIrradiance);
            //assert(np.max == 1);

            Vector3D surfaceDirection = new Vector3D();

            p.surfaceToCartesian(surfaceDirection);

            //System.out.println(normal.dot(surfaceDirection));

            if (dist2 < np.dist2[0] && normal.dot(surfaceDirection) > 0.0)
            {
                // we found a photon :) Insert it in the candidate list

                if (np.found < 1)
                {
                    // heap is not full; use array
                    np.found++;
                    np.dist2[np.found]   = dist2;
                    np.indices[np.found] = index;
                }
                else
                {
                    // exchange element if necessary

                    if (np.dist2[0] > dist2)
                    {
                        np.dist2[1]   = dist2;
                        np.indices[1] = index;

                        np.dist2[0] = dist2;
                    }
                }
            }
        }
Beispiel #6
0
        public virtual void  locatePhotons(NearestPhotons np, int index)
        {
            double dist1, dist2;
            Photon p = getPhoton(index);

            if (index < halfStoredPhotons)
            {
                dist1 = np.position.get(p.plane) - p.position.get(p.plane);

                if (dist1 > 0.0)
                {
                    // if dist1 is positive search right plane
                    locatePhotons(np, (2 * index) + 1);

                    if (dist1 * dist1 < np.dist2[0])
                    {
                        locatePhotons(np, (2 * index));
                    }
                }
                else
                {
                    // dist1 is negative search left first
                    locatePhotons(np, (2 * index));

                    if (dist1 * dist1 < np.dist2[0])
                    {
                        locatePhotons(np, (2 * index) + 1);
                    }
                }
            }

            // compute squared distance between current photon and np.position
            dist2 = p.position.distanceSqr(np.position);

            if (dist2 < np.dist2[0])
            {
                // we found a photon :) Insert it in the candidate list

                if (np.found < np.max)
                {
                    // heap is not full; use array
                    np.found++;
                    np.dist2[np.found]   = dist2;
                    np.indices[np.found] = index;
                }
                else
                {
                    int j, parent;

                    if (!np.gotHeap)
                    {
                        // build heap
                        int    halfFound;
                        int    photIndex;
                        double tempDist;

                        halfFound = np.found >> 1;

                        for (int k = halfFound; k >= 1; k--)
                        {
                            parent = k;

                            photIndex = np.indices[k];
                            tempDist  = np.dist2[k];

                            while (parent < halfFound)
                            {
                                j = parent + parent;

                                if (j < np.found && np.dist2[j] < np.dist2[j + 1])
                                {
                                    j++;
                                }
                                if (tempDist >= np.dist2[j])
                                {
                                    break;
                                }

                                np.dist2[parent]   = np.dist2[j];
                                np.indices[parent] = np.indices[j];
                                parent             = j;
                            }

                            np.dist2[parent]   = tempDist;
                            np.indices[parent] = photIndex;
                        }

                        np.gotHeap = true;
                    }

                    // insert new photon into max heap
                    // delete largest element, insert new, and reorder the heap

                    parent = 1;
                    j      = 2;

                    while (j <= np.found)
                    {
                        if (j < np.found && np.dist2[j] < np.dist2[j + 1])
                        {
                            j++;
                        }
                        if (dist2 > np.dist2[j])
                        {
                            break;
                        }

                        np.dist2[parent]   = np.dist2[j];
                        np.indices[parent] = np.indices[j];

                        parent = j;
                        j     += j;
                    }

                    //!!!
                    if (dist2 < np.dist2[parent])
                    {
                        np.dist2[parent]   = dist2;
                        np.indices[parent] = index;
                    }

                    np.dist2[0] = np.dist2[1];
                }
            }
        }