Search in sources :

Example 6 with OrthoNormalBasis

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

the class QuickGrayShader method scatterPhoton.

public void scatterPhoton(ShadingState state, Color power) {
    Color diffuse;
    // make sure we are on the right side of the material
    if (Vector3.dot(state.getNormal(), state.getRay().getDirection()) > 0.0) {
        state.getNormal().negate();
        state.getGeoNormal().negate();
    }
    diffuse = Color.GRAY;
    state.storePhoton(state.getRay().getDirection(), power, diffuse);
    float avg = diffuse.getAverage();
    double rnd = state.getRandom(0, 0, 1);
    if (rnd < avg) {
        // photon is scattered
        power.mul(diffuse).mul(1.0f / avg);
        OrthoNormalBasis onb = state.getBasis();
        double u = 2 * Math.PI * rnd / avg;
        double v = state.getRandom(0, 1, 1);
        float s = (float) Math.sqrt(v);
        float s1 = (float) Math.sqrt(1.0 - v);
        Vector3 w = new Vector3((float) Math.cos(u) * s, (float) Math.sin(u) * s, s1);
        w = onb.transform(w, new Vector3());
        state.traceDiffusePhoton(new Ray(state.getPoint(), w), power);
    }
}
Also used : Color(org.sunflow.image.Color) Vector3(org.sunflow.math.Vector3) Ray(org.sunflow.core.Ray) OrthoNormalBasis(org.sunflow.math.OrthoNormalBasis)

Example 7 with OrthoNormalBasis

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

the class AnisotropicWardShader method scatterPhoton.

public void scatterPhoton(ShadingState state, Color power) {
    // make sure we are on the right side of the material
    state.faceforward();
    Color d = getDiffuse(state);
    state.storePhoton(state.getRay().getDirection(), power, d);
    float avgD = d.getAverage();
    float avgS = rhoS.getAverage();
    double rnd = state.getRandom(0, 0, 1);
    if (rnd < avgD) {
        // photon is scattered diffusely
        power.mul(d).mul(1.0f / avgD);
        OrthoNormalBasis onb = state.getBasis();
        double u = 2 * Math.PI * rnd / avgD;
        double v = state.getRandom(0, 1, 1);
        float s = (float) Math.sqrt(v);
        float s1 = (float) Math.sqrt(1.0f - v);
        Vector3 w = new Vector3((float) Math.cos(u) * s, (float) Math.sin(u) * s, s1);
        w = onb.transform(w, new Vector3());
        state.traceDiffusePhoton(new Ray(state.getPoint(), w), power);
    } else if (rnd < avgD + avgS) {
        // photon is scattered specularly
        power.mul(rhoS).mul(1 / avgS);
        OrthoNormalBasis basis = state.getBasis();
        Vector3 in = state.getRay().getDirection().negate(new Vector3());
        double r1 = rnd / avgS;
        double r2 = state.getRandom(0, 1, 1);
        float alphaRatio = alphaY / alphaX;
        float phi = 0;
        if (r1 < 0.25) {
            double val = 4 * r1;
            phi = (float) Math.atan(alphaRatio * Math.tan(Math.PI / 2 * val));
        } else if (r1 < 0.5) {
            double val = 1 - 4 * (0.5 - r1);
            phi = (float) Math.atan(alphaRatio * Math.tan(Math.PI / 2 * val));
            phi = (float) Math.PI - phi;
        } else if (r1 < 0.75) {
            double val = 4 * (r1 - 0.5);
            phi = (float) Math.atan(alphaRatio * Math.tan(Math.PI / 2 * val));
            phi += Math.PI;
        } else {
            double val = 1 - 4 * (1 - r1);
            phi = (float) Math.atan(alphaRatio * Math.tan(Math.PI / 2 * val));
            phi = 2 * (float) Math.PI - phi;
        }
        float cosPhi = (float) Math.cos(phi);
        float sinPhi = (float) Math.sin(phi);
        float denom = (cosPhi * cosPhi) / (alphaX * alphaX) + (sinPhi * sinPhi) / (alphaY * alphaY);
        float theta = (float) Math.atan(Math.sqrt(-Math.log(1 - r2) / denom));
        float sinTheta = (float) Math.sin(theta);
        float cosTheta = (float) Math.cos(theta);
        Vector3 h = new Vector3();
        h.x = sinTheta * cosPhi;
        h.y = sinTheta * sinPhi;
        h.z = cosTheta;
        basis.transform(h);
        Vector3 o = new Vector3();
        float ih = Vector3.dot(h, in);
        o.x = 2 * ih * h.x - in.x;
        o.y = 2 * ih * h.y - in.y;
        o.z = 2 * ih * h.z - in.z;
        Ray r = new Ray(state.getPoint(), o);
        state.traceReflectionPhoton(r, power);
    }
}
Also used : Color(org.sunflow.image.Color) Vector3(org.sunflow.math.Vector3) Ray(org.sunflow.core.Ray) OrthoNormalBasis(org.sunflow.math.OrthoNormalBasis)

Example 8 with OrthoNormalBasis

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

the class DiffuseShader method scatterPhoton.

public void scatterPhoton(ShadingState state, Color power) {
    Color diffuse;
    // make sure we are on the right side of the material
    if (Vector3.dot(state.getNormal(), state.getRay().getDirection()) > 0.0) {
        state.getNormal().negate();
        state.getGeoNormal().negate();
    }
    diffuse = getDiffuse(state);
    state.storePhoton(state.getRay().getDirection(), power, diffuse);
    float avg = diffuse.getAverage();
    double rnd = state.getRandom(0, 0, 1);
    if (rnd < avg) {
        // photon is scattered
        power.mul(diffuse).mul(1.0f / avg);
        OrthoNormalBasis onb = state.getBasis();
        double u = 2 * Math.PI * rnd / avg;
        double v = state.getRandom(0, 1, 1);
        float s = (float) Math.sqrt(v);
        float s1 = (float) Math.sqrt(1.0 - v);
        Vector3 w = new Vector3((float) Math.cos(u) * s, (float) Math.sin(u) * s, s1);
        w = onb.transform(w, new Vector3());
        state.traceDiffusePhoton(new Ray(state.getPoint(), w), power);
    }
}
Also used : Color(org.sunflow.image.Color) Vector3(org.sunflow.math.Vector3) Ray(org.sunflow.core.Ray) OrthoNormalBasis(org.sunflow.math.OrthoNormalBasis)

Example 9 with OrthoNormalBasis

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

the class CornellBox method scatterPhoton.

@Override
public void scatterPhoton(ShadingState state, Color power) {
    int side = state.getPrimitiveID();
    Color kd = null;
    switch(side) {
        case 0:
            kd = left;
            break;
        case 1:
            kd = right;
            break;
        case 3:
            kd = back;
            break;
        case 4:
            kd = bottom;
            break;
        case 5:
            float lx = state.getPoint().x;
            float ly = state.getPoint().y;
            if (lx >= lxmin && lx < lxmax && ly >= lymin && ly < lymax && state.getRay().dz > 0) {
                return;
            }
            kd = top;
            break;
        default:
            assert false;
    }
    // make sure we are on the right side of the material
    if (Vector3.dot(state.getNormal(), state.getRay().getDirection()) > 0) {
        state.getNormal().negate();
        state.getGeoNormal().negate();
    }
    state.storePhoton(state.getRay().getDirection(), power, kd);
    double avg = kd.getAverage();
    double rnd = state.getRandom(0, 0, 1);
    if (rnd < avg) {
        // photon is scattered
        power.mul(kd).mul(1 / (float) avg);
        OrthoNormalBasis onb = OrthoNormalBasis.makeFromW(state.getNormal());
        double u = 2 * Math.PI * rnd / avg;
        double v = state.getRandom(0, 1, 1);
        float s = (float) Math.sqrt(v);
        float s1 = (float) Math.sqrt(1.0 - v);
        Vector3 w = new Vector3((float) Math.cos(u) * s, (float) Math.sin(u) * s, s1);
        w = onb.transform(w, new Vector3());
        state.traceDiffusePhoton(new Ray(state.getPoint(), w), power);
    }
}
Also used : Color(org.sunflow.image.Color) Vector3(org.sunflow.math.Vector3) Ray(org.sunflow.core.Ray) OrthoNormalBasis(org.sunflow.math.OrthoNormalBasis)

Example 10 with OrthoNormalBasis

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

the class UberShader method scatterPhoton.

public void scatterPhoton(ShadingState state, Color power) {
    Color diffuse, specular;
    // make sure we are on the right side of the material
    state.faceforward();
    diffuse = getDiffuse(state);
    specular = getSpecular(state);
    state.storePhoton(state.getRay().getDirection(), power, diffuse);
    float d = diffuse.getAverage();
    float r = specular.getAverage();
    double rnd = state.getRandom(0, 0, 1);
    if (rnd < d) {
        // photon is scattered
        power.mul(diffuse).mul(1.0f / d);
        OrthoNormalBasis onb = state.getBasis();
        double u = 2 * Math.PI * rnd / d;
        double v = state.getRandom(0, 1, 1);
        float s = (float) Math.sqrt(v);
        float s1 = (float) Math.sqrt(1.0 - v);
        Vector3 w = new Vector3((float) Math.cos(u) * s, (float) Math.sin(u) * s, s1);
        w = onb.transform(w, new Vector3());
        state.traceDiffusePhoton(new Ray(state.getPoint(), w), power);
    } else if (rnd < d + r) {
        if (glossyness == 0) {
            float cos = -Vector3.dot(state.getNormal(), state.getRay().getDirection());
            power.mul(diffuse).mul(1.0f / d);
            // photon is reflected
            float dn = 2 * cos;
            Vector3 dir = new Vector3();
            dir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x;
            dir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y;
            dir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z;
            state.traceReflectionPhoton(new Ray(state.getPoint(), dir), power);
        } else {
            float dn = 2.0f * state.getCosND();
            // reflected direction
            Vector3 refDir = new Vector3();
            refDir.x = (dn * state.getNormal().x) + state.getRay().dx;
            refDir.y = (dn * state.getNormal().y) + state.getRay().dy;
            refDir.z = (dn * state.getNormal().z) + state.getRay().dz;
            power.mul(spec).mul(1.0f / r);
            OrthoNormalBasis onb = state.getBasis();
            double u = 2 * Math.PI * (rnd - r) / r;
            double v = state.getRandom(0, 1, 1);
            float s = (float) Math.pow(v, 1 / ((1.0f / glossyness) + 1));
            float s1 = (float) Math.sqrt(1 - s * s);
            Vector3 w = new Vector3((float) Math.cos(u) * s1, (float) Math.sin(u) * s1, s);
            w = onb.transform(w, new Vector3());
            state.traceReflectionPhoton(new Ray(state.getPoint(), w), power);
        }
    }
}
Also used : Color(org.sunflow.image.Color) Vector3(org.sunflow.math.Vector3) Ray(org.sunflow.core.Ray) 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