示例#1
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);
                    }
                }
            }
        }
示例#2
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);
             }
         }
     }
 }
示例#3
0
        private void locatePhotons(NearestPhotons np)
        {
            float[] dist1d2 = new float[log2n];
            int[]   chosen  = new int[log2n];
            int     i       = 1;
            int     level   = 0;
            int     cameFrom;

            while (true)
            {
                while (i < halfStoredPhotons)
                {
                    float dist1d = photons[i].getDist1(np.px, np.py, np.pz);
                    dist1d2[level] = dist1d * dist1d;
                    i += i;
                    if (dist1d > 0.0f)
                    {
                        i++;
                    }
                    chosen[level++] = i;
                }
                np.checkAddNearest(photons[i]);
                do
                {
                    cameFrom = i;
                    i      >>= 1;
                    level--;
                    if (i == 0)
                    {
                        return;
                    }
                } while ((dist1d2[level] >= np.dist2[0]) || (cameFrom != chosen[level]));
                np.checkAddNearest(photons[i]);
                i = chosen[level++] ^ 1;
            }
        }
示例#4
0
 private void locatePhotons(NearestPhotons np)
 {
     float[] dist1d2 = new float[log2n];
     int[] chosen = new int[log2n];
     int i = 1;
     int level = 0;
     int cameFrom;
     while (true)
     {
         while (i < halfStoredPhotons)
         {
             float dist1d = photons[i].getDist1(np.px, np.py, np.pz);
             dist1d2[level] = dist1d * dist1d;
             i += i;
             if (dist1d > 0.0f)
                 i++;
             chosen[level++] = i;
         }
         np.checkAddNearest(photons[i]);
         do
         {
             cameFrom = i;
             i >>= 1;
             level--;
             if (i == 0)
                 return;
         } while ((dist1d2[level] >= np.dist2[0]) || (cameFrom != chosen[level]));
         np.checkAddNearest(photons[i]);
         i = chosen[level++] ^ 1;
     }
 }
示例#5
0
        public void precomputeRadiance()
        {
            if (storedPhotons == 0)
                return;
            // precompute the radiance for all photons that are neither
            // leaves nor parents of leaves in the tree.
            int quadStoredPhotons = halfStoredPhotons / 2;
            Point3 p = new Point3();
            Vector3 n = new Vector3();
            Point3 ppos = new Point3();
            Vector3 pdir = new Vector3();
            Vector3 pvec = new Vector3();
            Color irr = new Color();
            Color pow = new Color();
            float maxDist2 = gatherRadius * gatherRadius;
            NearestPhotons np = new NearestPhotons(p, numGather, maxDist2);
            Photon[] temp = new Photon[quadStoredPhotons + 1];
            UI.taskStart("Precomputing radiance", 1, quadStoredPhotons);
            for (int i = 1; i <= quadStoredPhotons; i++)
            {
                UI.taskUpdate(i);
                Photon curr = photons[i];
                p.set(curr.x, curr.y, curr.z);
                Vector3.decode(curr.normal, n);
                irr.set(Color.BLACK);
                np.reset(p, maxDist2);
                locatePhotons(np);
                if (np.found < 8)
                {
                    curr.data = 0;
                    temp[i] = curr;
                    continue;
                }
                float invArea = 1.0f / ((float)Math.PI * np.dist2[0]);
                float maxNDist = np.dist2[0] * 0.05f;
                for (int j = 1; j <= np.found; j++)
                {
                    Photon phot = np.index[j];
                    Vector3.decode(phot.dir, pdir);
                    float cos = -Vector3.dot(pdir, n);
                    if (cos > 0.01f)
                    {
                        ppos.set(phot.x, phot.y, phot.z);
                        Point3.sub(ppos, p, pvec);
                        float pcos = Vector3.dot(pvec, n);
                        if ((pcos < maxNDist) && (pcos > -maxNDist))
                            irr.add(pow.setRGBE(phot.power));
                    }
                }
                irr.mul(invArea);
                // compute radiance
                irr.mul(new Color(curr.data)).mul(1.0f / (float)Math.PI);
                curr.data = irr.toRGBE();
                temp[i] = curr;
            }
            UI.taskStop();

            // resize photon map to only include irradiance photons
            numGather /= 4;
            maxRadius = 1.4f * (float)Math.Sqrt(maxPower * numGather);
            if (gatherRadius > maxRadius)
                gatherRadius = maxRadius;
            storedPhotons = quadStoredPhotons;
            halfStoredPhotons = storedPhotons / 2;
            log2n = (int)Math.Ceiling(Math.Log(storedPhotons) / Math.Log(2.0));
            photons = temp;
            hasRadiance = true;
        }
示例#6
0
        public void precomputeRadiance()
        {
            if (storedPhotons == 0)
            {
                return;
            }
            // precompute the radiance for all photons that are neither
            // leaves nor parents of leaves in the tree.
            int            quadStoredPhotons = halfStoredPhotons / 2;
            Point3         p        = new Point3();
            Vector3        n        = new Vector3();
            Point3         ppos     = new Point3();
            Vector3        pdir     = new Vector3();
            Vector3        pvec     = new Vector3();
            Color          irr      = new Color();
            Color          pow      = new Color();
            float          maxDist2 = gatherRadius * gatherRadius;
            NearestPhotons np       = new NearestPhotons(p, numGather, maxDist2);

            Photon[] temp = new Photon[quadStoredPhotons + 1];
            UI.taskStart("Precomputing radiance", 1, quadStoredPhotons);
            for (int i = 1; i <= quadStoredPhotons; i++)
            {
                UI.taskUpdate(i);
                Photon curr = photons[i];
                p.set(curr.x, curr.y, curr.z);
                Vector3.decode(curr.normal, n);
                irr.set(Color.BLACK);
                np.reset(p, maxDist2);
                locatePhotons(np);
                if (np.found < 8)
                {
                    curr.data = 0;
                    temp[i]   = curr;
                    continue;
                }
                float invArea  = 1.0f / ((float)Math.PI * np.dist2[0]);
                float maxNDist = np.dist2[0] * 0.05f;
                for (int j = 1; j <= np.found; j++)
                {
                    Photon phot = np.index[j];
                    Vector3.decode(phot.dir, pdir);
                    float cos = -Vector3.dot(pdir, n);
                    if (cos > 0.01f)
                    {
                        ppos.set(phot.x, phot.y, phot.z);
                        Point3.sub(ppos, p, pvec);
                        float pcos = Vector3.dot(pvec, n);
                        if ((pcos < maxNDist) && (pcos > -maxNDist))
                        {
                            irr.add(pow.setRGBE(phot.power));
                        }
                    }
                }
                irr.mul(invArea);
                // compute radiance
                irr.mul(new Color(curr.data)).mul(1.0f / (float)Math.PI);
                curr.data = irr.toRGBE();
                temp[i]   = curr;
            }
            UI.taskStop();

            // resize photon map to only include irradiance photons
            numGather /= 4;
            maxRadius  = 1.4f * (float)Math.Sqrt(maxPower * numGather);
            if (gatherRadius > maxRadius)
            {
                gatherRadius = maxRadius;
            }
            storedPhotons     = quadStoredPhotons;
            halfStoredPhotons = storedPhotons / 2;
            log2n             = (int)Math.Ceiling(Math.Log(storedPhotons) / Math.Log(2.0));
            photons           = temp;
            hasRadiance       = true;
        }