Search in sources :

Example 11 with OrthoNormalBasis

use of org.sunflow.math.OrthoNormalBasis 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 12 with OrthoNormalBasis

use of org.sunflow.math.OrthoNormalBasis 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 13 with OrthoNormalBasis

use of org.sunflow.math.OrthoNormalBasis 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 14 with OrthoNormalBasis

use of org.sunflow.math.OrthoNormalBasis 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)

Example 15 with OrthoNormalBasis

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

the class ShadingState method occlusion.

/**
 * Ambient occlusion routine, returns a value between bright and dark
 * depending on the amount of geometric occlusion in the scene.
 *
 * @param samples number of sample rays
 * @param maxDist maximum length of the rays
 * @param bright color when nothing is occluded
 * @param dark color when fully occluded
 * @return occlusion color
 */
public final Color occlusion(int samples, float maxDist, Color bright, Color dark) {
    if (n == null) {
        // in case we got called on a geometry without orientation
        return bright;
    }
    // make sure we are on the right side of the material
    faceforward();
    OrthoNormalBasis onb = getBasis();
    Vector3 w = new Vector3();
    Color result = Color.black();
    for (int i = 0; i < samples; i++) {
        float xi = (float) getRandom(i, 0, samples);
        float xj = (float) getRandom(i, 1, samples);
        float phi = (float) (2 * Math.PI * xi);
        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(p, w);
        r.setMax(maxDist);
        result.add(Color.blend(bright, dark, traceShadow(r)));
    }
    return result.mul(1.0f / samples);
}
Also used : Color(org.sunflow.image.Color) Vector3(org.sunflow.math.Vector3) OrthoNormalBasis(org.sunflow.math.OrthoNormalBasis)

Aggregations

OrthoNormalBasis (org.sunflow.math.OrthoNormalBasis)17 Vector3 (org.sunflow.math.Vector3)17 Color (org.sunflow.image.Color)15 Ray (org.sunflow.core.Ray)13 ShadingState (org.sunflow.core.ShadingState)3 LightSample (org.sunflow.core.LightSample)2 Point3 (org.sunflow.math.Point3)1