Search in sources :

Example 6 with Vector3

use of org.sunflow.math.Vector3 in project joons-renderer by joonhyublee.

the class GlobalPhotonMap method precomputeRadiance.

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.ceil(Math.log(storedPhotons) / Math.log(2.0));
    photons = temp;
    hasRadiance = true;
}
Also used : Point3(org.sunflow.math.Point3) Color(org.sunflow.image.Color) Vector3(org.sunflow.math.Vector3)

Example 7 with Vector3

use of org.sunflow.math.Vector3 in project joons-renderer by joonhyublee.

the class GlobalPhotonMap method getRadiance.

@Override
public Color getRadiance(Point3 p, Vector3 n) {
    if (!hasRadiance || (storedPhotons == 0)) {
        return Color.BLACK;
    }
    float px = p.x;
    float py = p.y;
    float pz = p.z;
    int i = 1;
    int level = 0;
    int cameFrom;
    float dist2;
    float maxDist2 = gatherRadius * gatherRadius;
    Photon nearest = null;
    Photon curr;
    Vector3 photN = new Vector3();
    float[] dist1d2 = new float[log2n];
    int[] chosen = new int[log2n];
    while (true) {
        while (i < halfStoredPhotons) {
            float dist1d = photons[i].getDist1(px, py, pz);
            dist1d2[level] = dist1d * dist1d;
            i += i;
            if (dist1d > 0) {
                i++;
            }
            chosen[level++] = i;
        }
        curr = photons[i];
        dist2 = curr.getDist2(px, py, pz);
        if (dist2 < maxDist2) {
            Vector3.decode(curr.normal, photN);
            float currentDotN = Vector3.dot(photN, n);
            if (currentDotN > 0.9f) {
                nearest = curr;
                maxDist2 = dist2;
            }
        }
        do {
            cameFrom = i;
            i >>= 1;
            level--;
            if (i == 0) {
                return (nearest == null) ? Color.BLACK : new Color().setRGBE(nearest.data);
            }
        } while ((dist1d2[level] >= maxDist2) || (cameFrom != chosen[level]));
        curr = photons[i];
        dist2 = curr.getDist2(px, py, pz);
        if (dist2 < maxDist2) {
            Vector3.decode(curr.normal, photN);
            float currentDotN = Vector3.dot(photN, n);
            if (currentDotN > 0.9f) {
                nearest = curr;
                maxDist2 = dist2;
            }
        }
        i = chosen[level++] ^ 1;
    }
}
Also used : Color(org.sunflow.image.Color) Vector3(org.sunflow.math.Vector3)

Example 8 with Vector3

use of org.sunflow.math.Vector3 in project joons-renderer by joonhyublee.

the class SunSkyLight method getSamples.

public void getSamples(ShadingState state) {
    if (Vector3.dot(sunDirWorld, state.getGeoNormal()) > 0 && Vector3.dot(sunDirWorld, state.getNormal()) > 0) {
        LightSample dest = new LightSample();
        dest.setShadowRay(new Ray(state.getPoint(), sunDirWorld));
        dest.getShadowRay().setMax(Float.MAX_VALUE);
        dest.setRadiance(sunColor, sunColor);
        dest.traceShadow(state);
        state.addSample(dest);
    }
    int n = state.getDiffuseDepth() > 0 ? 1 : numSkySamples;
    for (int i = 0; i < n; i++) {
        // random offset on unit square, we use the infinite version of
        // getRandom because the light sampling is adaptive
        double randX = state.getRandom(i, 0, n);
        double randY = state.getRandom(i, 1, n);
        int x = 0;
        while (randX >= colHistogram[x] && x < colHistogram.length - 1) {
            x++;
        }
        float[] rowHistogram = imageHistogram[x];
        int y = 0;
        while (randY >= rowHistogram[y] && y < rowHistogram.length - 1) {
            y++;
        }
        // sample from (x, y)
        float u = (float) ((x == 0) ? (randX / colHistogram[0]) : ((randX - colHistogram[x - 1]) / (colHistogram[x] - colHistogram[x - 1])));
        float v = (float) ((y == 0) ? (randY / rowHistogram[0]) : ((randY - rowHistogram[y - 1]) / (rowHistogram[y] - rowHistogram[y - 1])));
        float px = ((x == 0) ? colHistogram[0] : (colHistogram[x] - colHistogram[x - 1]));
        float py = ((y == 0) ? rowHistogram[0] : (rowHistogram[y] - rowHistogram[y - 1]));
        float su = (x + u) / colHistogram.length;
        float sv = (y + v) / rowHistogram.length;
        float invP = (float) Math.sin(sv * Math.PI) * jacobian / (n * px * py);
        Vector3 localDir = getDirection(su, sv);
        Vector3 dir = basis.transform(localDir, new Vector3());
        if (Vector3.dot(dir, state.getGeoNormal()) > 0 && Vector3.dot(dir, state.getNormal()) > 0) {
            LightSample dest = new LightSample();
            dest.setShadowRay(new Ray(state.getPoint(), dir));
            dest.getShadowRay().setMax(Float.MAX_VALUE);
            Color radiance = getSkyRGB(localDir);
            dest.setRadiance(radiance, radiance);
            dest.getDiffuseRadiance().mul(invP);
            dest.getSpecularRadiance().mul(invP);
            dest.traceShadow(state);
            state.addSample(dest);
        }
    }
}
Also used : LightSample(org.sunflow.core.LightSample) Color(org.sunflow.image.Color) XYZColor(org.sunflow.image.XYZColor) Vector3(org.sunflow.math.Vector3) Ray(org.sunflow.core.Ray)

Example 9 with Vector3

use of org.sunflow.math.Vector3 in project joons-renderer by joonhyublee.

the class SunSkyLight method getDirection.

private Vector3 getDirection(float u, float v) {
    Vector3 dest = new Vector3();
    double phi = 0, theta = 0;
    theta = u * 2 * Math.PI;
    phi = v * Math.PI;
    double sin_phi = Math.sin(phi);
    dest.x = (float) (-sin_phi * Math.cos(theta));
    dest.y = (float) Math.cos(phi);
    dest.z = (float) (sin_phi * Math.sin(theta));
    return dest;
}
Also used : Vector3(org.sunflow.math.Vector3)

Example 10 with Vector3

use of org.sunflow.math.Vector3 in project joons-renderer by joonhyublee.

the class PerlinModifier method modify.

@Override
public void modify(ShadingState state) {
    Point3 p = state.transformWorldToObject(state.getPoint());
    p.x *= size;
    p.y *= size;
    p.z *= size;
    Vector3 normal = state.transformNormalWorldToObject(state.getNormal());
    double f0 = f(p.x, p.y, p.z);
    double fx = f(p.x + .0001, p.y, p.z);
    double fy = f(p.x, p.y + .0001, p.z);
    double fz = f(p.x, p.y, p.z + .0001);
    normal.x -= scale * (fx - f0) / .0001;
    normal.y -= scale * (fy - f0) / .0001;
    normal.z -= scale * (fz - f0) / .0001;
    normal.normalize();
    state.getNormal().set(state.transformNormalObjectToWorld(normal));
    state.getNormal().normalize();
    state.setBasis(OrthoNormalBasis.makeFromW(state.getNormal()));
}
Also used : Point3(org.sunflow.math.Point3) Vector3(org.sunflow.math.Vector3)

Aggregations

Vector3 (org.sunflow.math.Vector3)75 Color (org.sunflow.image.Color)34 Point3 (org.sunflow.math.Point3)27 Ray (org.sunflow.core.Ray)25 OrthoNormalBasis (org.sunflow.math.OrthoNormalBasis)17 Instance (org.sunflow.core.Instance)11 LightSample (org.sunflow.core.LightSample)8 ShadingState (org.sunflow.core.ShadingState)3 ParameterList (org.sunflow.core.ParameterList)2 TriangleMesh (org.sunflow.core.primitive.TriangleMesh)2 XYZColor (org.sunflow.image.XYZColor)2 Timer (org.sunflow.system.Timer)2 File (java.io.File)1 FileInputStream (java.io.FileInputStream)1 FileNotFoundException (java.io.FileNotFoundException)1 IOException (java.io.IOException)1 FloatBuffer (java.nio.FloatBuffer)1 MappedByteBuffer (java.nio.MappedByteBuffer)1 ReentrantReadWriteLock (java.util.concurrent.locks.ReentrantReadWriteLock)1 PrimitiveList (org.sunflow.core.PrimitiveList)1