Beispiel #1
0
        // Lambertian! Replace with general BSDF.
        public virtual void  radianceEstimatePrecomputed(RGBColor rad, Vector3D position, Vector3D normal, float initialDist, float maxDist)
        {
            NearestPhotons np;

            // locate the nearest photon
            float r = initialDist;

            do
            {
                np = new NearestPhotons(1, r, position);

                locatePhotonsPrecomputed(normal, np, 1);

                r = (float)(r * 2.0);
            }while (np.found == 0 && r < maxDist);

            if (np.found > 0)
            {
                Photon p = getPhoton(np.indices[1]);

                rad.set(p.accumPower);
            }
            else
            {
                rad.set(0.0f);
            }
        }
Beispiel #2
0
        // Lambertian! Replace with general BSDF.
        public virtual void  radianceEstimate(RGBColor rad, 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);

            rad.set(0.0f);

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

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

            Vector3D direction = new Vector3D();

            //float mittrs = MBETA / (2.0f * (float) np.dist2[0]);
            float kdenom = (float)(1.0 / (1.1 * Math.Sqrt(np.dist2[0])));

            // sum irrandiance from all photons
            for (int i = 1; i <= np.found; i++)
            {
                float cosNL;

                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);

                cosNL = (float)direction.dot(normal);
                //cosNL = -1.0f;

                if (cosNL < 0.0)
                {
                    //float gaussWeight = 1.0f - (1.0f - (float) System.Math.Exp((float) p.position.distanceSqr(position) * mittrs)) * DENOMFACTOR;
                    float coneWeight = 1.0f - (float)(p.position.distance(position) * kdenom);

                    //rad.add(p.power.scaleNew((- cosNL) * gaussWeight));
                    //rad.add(p.power.scaleNew((- cosNL)));
                    rad.add(p.power.scaleNew(coneWeight));
                }
            }

            // estimate of density
            //rad.scale(ALPHA / (float) (System.Math.PI * np.dist2[0]));
            //rad.scale(1.0f / (float) (System.Math.PI * np.dist2[0]));
            rad.scale(1.0f / (float)((1.0f - 2.0f / (3.0f * 1.1f)) * System.Math.PI * np.dist2[0]));
        }
Beispiel #3
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 #4
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];
                }
            }
        }