Search in sources :

Example 61 with Vector3

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

the class InstantGI method getGlobalRadiance.

@Override
public Color getGlobalRadiance(ShadingState state) {
    Point3 p = state.getPoint();
    Vector3 n = state.getNormal();
    int set = (int) (state.getRandom(0, 1, 1) * numSets);
    float maxAvgPow = 0;
    float minDist = 1;
    Color pow = null;
    for (PointLight vpl : virtualLights[set]) {
        maxAvgPow = Math.max(maxAvgPow, vpl.power.getAverage());
        if (Vector3.dot(n, vpl.n) > 0.9f) {
            float d = vpl.p.distanceToSquared(p);
            if (d < minDist) {
                pow = vpl.power;
                minDist = d;
            }
        }
    }
    return pow == null ? Color.BLACK : pow.copy().mul(1.0f / maxAvgPow);
}
Also used : Point3(org.sunflow.math.Point3) Color(org.sunflow.image.Color) Vector3(org.sunflow.math.Vector3)

Example 62 with Vector3

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

the class InstantGI method getIrradiance.

@Override
public Color getIrradiance(ShadingState state, Color diffuseReflectance) {
    float b = (float) Math.PI * c / diffuseReflectance.getMax();
    Color irr = Color.black();
    Point3 p = state.getPoint();
    Vector3 n = state.getNormal();
    int set = (int) (state.getRandom(0, 1, 1) * numSets);
    for (PointLight vpl : virtualLights[set]) {
        Ray r = new Ray(p, vpl.p);
        float dotNlD = -(r.dx * vpl.n.x + r.dy * vpl.n.y + r.dz * vpl.n.z);
        float dotND = r.dx * n.x + r.dy * n.y + r.dz * n.z;
        if (dotNlD > 0 && dotND > 0) {
            float r2 = r.getMax() * r.getMax();
            Color opacity = state.traceShadow(r);
            Color power = Color.blend(vpl.power, Color.BLACK, opacity);
            float g = (dotND * dotNlD) / r2;
            irr.madd(0.25f * Math.min(g, b), power);
        }
    }
    // bias compensation
    int nb = (state.getDiffuseDepth() == 0 || numBias <= 0) ? numBias : 1;
    if (nb <= 0) {
        return irr;
    }
    OrthoNormalBasis onb = state.getBasis();
    Vector3 w = new Vector3();
    float scale = (float) Math.PI / nb;
    for (int i = 0; i < nb; i++) {
        float xi = (float) state.getRandom(i, 0, nb);
        float xj = (float) state.getRandom(i, 1, nb);
        float phi = (float) (xi * 2 * Math.PI);
        float cosPhi = (float) Math.cos(phi);
        float sinPhi = (float) Math.sin(phi);
        float sinTheta = (float) Math.sqrt(xj);
        float cosTheta = (float) Math.sqrt(1.0f - xj);
        w.x = cosPhi * sinTheta;
        w.y = sinPhi * sinTheta;
        w.z = cosTheta;
        onb.transform(w);
        Ray r = new Ray(state.getPoint(), w);
        r.setMax((float) Math.sqrt(cosTheta / b));
        ShadingState temp = state.traceFinalGather(r, i);
        if (temp != null) {
            temp.getInstance().prepareShadingState(temp);
            if (temp.getShader() != null) {
                float dist = temp.getRay().getMax();
                float r2 = dist * dist;
                float cosThetaY = -Vector3.dot(w, temp.getNormal());
                if (cosThetaY > 0) {
                    float g = (cosTheta * cosThetaY) / r2;
                    // was this path accounted for yet?
                    if (g > b) {
                        irr.madd(scale * (g - b) / g, temp.getShader().getRadiance(temp));
                    }
                }
            }
        }
    }
    return irr;
}
Also used : Point3(org.sunflow.math.Point3) ShadingState(org.sunflow.core.ShadingState) Color(org.sunflow.image.Color) Vector3(org.sunflow.math.Vector3) Ray(org.sunflow.core.Ray) OrthoNormalBasis(org.sunflow.math.OrthoNormalBasis)

Example 63 with Vector3

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

the class PathTracingGIEngine method getIrradiance.

@Override
public Color getIrradiance(ShadingState state, Color diffuseReflectance) {
    if (samples <= 0) {
        return Color.BLACK;
    }
    // compute new sample
    Color irr = Color.black();
    OrthoNormalBasis onb = state.getBasis();
    Vector3 w = new Vector3();
    int n = state.getDiffuseDepth() == 0 ? samples : 1;
    for (int i = 0; i < n; i++) {
        float xi = (float) state.getRandom(i, 0, n);
        float xj = (float) state.getRandom(i, 1, n);
        float phi = (float) (xi * 2 * Math.PI);
        float cosPhi = (float) Math.cos(phi);
        float sinPhi = (float) Math.sin(phi);
        float sinTheta = (float) Math.sqrt(xj);
        float cosTheta = (float) Math.sqrt(1.0f - xj);
        w.x = cosPhi * sinTheta;
        w.y = sinPhi * sinTheta;
        w.z = cosTheta;
        onb.transform(w);
        ShadingState temp = state.traceFinalGather(new Ray(state.getPoint(), w), i);
        if (temp != null) {
            temp.getInstance().prepareShadingState(temp);
            if (temp.getShader() != null) {
                irr.add(temp.getShader().getRadiance(temp));
            }
        }
    }
    irr.mul((float) Math.PI / n);
    return irr;
}
Also used : ShadingState(org.sunflow.core.ShadingState) Color(org.sunflow.image.Color) Vector3(org.sunflow.math.Vector3) Ray(org.sunflow.core.Ray) OrthoNormalBasis(org.sunflow.math.OrthoNormalBasis)

Example 64 with Vector3

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

the class SphereLight method getPhoton.

public void getPhoton(double randX1, double randY1, double randX2, double randY2, Point3 p, Vector3 dir, Color power) {
    float z = (float) (1 - 2 * randX2);
    float r = (float) Math.sqrt(Math.max(0, 1 - z * z));
    float phi = (float) (2 * Math.PI * randY2);
    float x = r * (float) Math.cos(phi);
    float y = r * (float) Math.sin(phi);
    p.x = center.x + x * radius;
    p.y = center.y + y * radius;
    p.z = center.z + z * radius;
    OrthoNormalBasis basis = OrthoNormalBasis.makeFromW(new Vector3(x, y, z));
    phi = (float) (2 * Math.PI * randX1);
    float cosPhi = (float) Math.cos(phi);
    float sinPhi = (float) Math.sin(phi);
    float sinTheta = (float) Math.sqrt(randY1);
    float cosTheta = (float) Math.sqrt(1 - randY1);
    dir.x = cosPhi * sinTheta;
    dir.y = sinPhi * sinTheta;
    dir.z = cosTheta;
    basis.transform(dir);
    power.set(radiance);
    power.mul((float) (Math.PI * Math.PI * 4 * r2));
}
Also used : Vector3(org.sunflow.math.Vector3) OrthoNormalBasis(org.sunflow.math.OrthoNormalBasis)

Example 65 with Vector3

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

the class SphereLight method getSamples.

public void getSamples(ShadingState state) {
    if (getNumSamples() <= 0) {
        return;
    }
    Vector3 wc = Point3.sub(center, state.getPoint(), new Vector3());
    float l2 = wc.lengthSquared();
    if (l2 <= r2) {
        // inside the sphere?
        return;
    }
    // top of the sphere as viewed from the current shading point
    float topX = wc.x + state.getNormal().x * radius;
    float topY = wc.y + state.getNormal().y * radius;
    float topZ = wc.z + state.getNormal().z * radius;
    if (state.getNormal().dot(topX, topY, topZ) <= 0) {
        // top of the sphere is below the horizon
        return;
    }
    float cosThetaMax = (float) Math.sqrt(Math.max(0, 1 - r2 / Vector3.dot(wc, wc)));
    OrthoNormalBasis basis = OrthoNormalBasis.makeFromW(wc);
    int samples = state.getDiffuseDepth() > 0 ? 1 : getNumSamples();
    float scale = (float) (2 * Math.PI * (1 - cosThetaMax));
    Color c = Color.mul(scale / samples, radiance);
    for (int i = 0; i < samples; i++) {
        // random offset on unit square
        double randX = state.getRandom(i, 0, samples);
        double randY = state.getRandom(i, 1, samples);
        // cone sampling
        double cosTheta = (1 - randX) * cosThetaMax + randX;
        double sinTheta = Math.sqrt(1 - cosTheta * cosTheta);
        double phi = randY * 2 * Math.PI;
        Vector3 dir = new Vector3((float) (Math.cos(phi) * sinTheta), (float) (Math.sin(phi) * sinTheta), (float) cosTheta);
        basis.transform(dir);
        // check that the direction of the sample is the same as the
        // normal
        float cosNx = Vector3.dot(dir, state.getNormal());
        if (cosNx <= 0) {
            continue;
        }
        float ocx = state.getPoint().x - center.x;
        float ocy = state.getPoint().y - center.y;
        float ocz = state.getPoint().z - center.z;
        float qa = Vector3.dot(dir, dir);
        float qb = 2 * ((dir.x * ocx) + (dir.y * ocy) + (dir.z * ocz));
        float qc = ((ocx * ocx) + (ocy * ocy) + (ocz * ocz)) - r2;
        double[] t = Solvers.solveQuadric(qa, qb, qc);
        if (t == null) {
            continue;
        }
        LightSample dest = new LightSample();
        // compute shadow ray to the sampled point
        dest.setShadowRay(new Ray(state.getPoint(), dir));
        // FIXME: arbitrary bias, should handle as in other places
        dest.getShadowRay().setMax((float) t[0] - 1e-3f);
        // prepare sample
        dest.setRadiance(c, c);
        dest.traceShadow(state);
        state.addSample(dest);
    }
}
Also used : LightSample(org.sunflow.core.LightSample) Color(org.sunflow.image.Color) Vector3(org.sunflow.math.Vector3) Ray(org.sunflow.core.Ray) OrthoNormalBasis(org.sunflow.math.OrthoNormalBasis)

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