Search in sources :

Example 16 with Ray

use of org.sunflow.core.Ray in project joons-renderer by joonhyublee.

the class ShinyDiffuseShader method getRadiance.

public Color getRadiance(ShadingState state) {
    // make sure we are on the right side of the material
    state.faceforward();
    // direct lighting
    state.initLightSamples();
    state.initCausticSamples();
    Color d = getDiffuse(state);
    Color lr = state.diffuse(d);
    if (!state.includeSpecular()) {
        return lr;
    }
    float cos = state.getCosND();
    float dn = 2 * cos;
    Vector3 refDir = new Vector3();
    refDir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x;
    refDir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y;
    refDir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z;
    Ray refRay = new Ray(state.getPoint(), refDir);
    // compute Fresnel term
    cos = 1 - cos;
    float cos2 = cos * cos;
    float cos5 = cos2 * cos2 * cos;
    Color ret = Color.white();
    Color r = d.copy().mul(refl);
    ret.sub(r);
    ret.mul(cos5);
    ret.add(r);
    return lr.add(ret.mul(state.traceReflection(refRay, 0)));
}
Also used : Color(org.sunflow.image.Color) Vector3(org.sunflow.math.Vector3) Ray(org.sunflow.core.Ray)

Example 17 with Ray

use of org.sunflow.core.Ray 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 18 with Ray

use of org.sunflow.core.Ray in project joons-renderer by joonhyublee.

the class CornellBox method getSamples.

@Override
public void getSamples(ShadingState state) {
    if (lightBounds.contains(state.getPoint()) && state.getPoint().z < maxZ) {
        int n = state.getDiffuseDepth() > 0 ? 1 : samples;
        float a = area / n;
        for (int i = 0; i < n; i++) {
            // random offset on unit square
            double randX = state.getRandom(i, 0, n);
            double randY = state.getRandom(i, 1, n);
            Point3 p = new Point3();
            p.x = (float) (lxmin * (1 - randX) + lxmax * randX);
            p.y = (float) (lymin * (1 - randY) + lymax * randY);
            p.z = maxZ - 0.001f;
            LightSample dest = new LightSample();
            // prepare shadow ray to sampled point
            dest.setShadowRay(new Ray(state.getPoint(), p));
            // check that the direction of the sample is the same as the
            // normal
            float cosNx = dest.dot(state.getNormal());
            if (cosNx <= 0) {
                return;
            }
            // light source facing point ?
            // (need to check with light source's normal)
            float cosNy = dest.getShadowRay().dz;
            if (cosNy > 0) {
                // compute geometric attenuation and probability scale
                // factor
                float r = dest.getShadowRay().getMax();
                float g = cosNy / (r * r);
                float scale = g * a;
                // set final sample radiance
                dest.setRadiance(radiance, radiance);
                dest.getDiffuseRadiance().mul(scale);
                dest.getSpecularRadiance().mul(scale);
                dest.traceShadow(state);
                state.addSample(dest);
            }
        }
    }
}
Also used : Point3(org.sunflow.math.Point3) LightSample(org.sunflow.core.LightSample) Ray(org.sunflow.core.Ray)

Example 19 with Ray

use of org.sunflow.core.Ray 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)

Example 20 with Ray

use of org.sunflow.core.Ray in project joons-renderer by joonhyublee.

the class GlassShader method scatterPhoton.

public void scatterPhoton(ShadingState state, Color power) {
    Color refr = Color.mul(1 - f0, color);
    Color refl = Color.mul(f0, color);
    float avgR = refl.getAverage();
    float avgT = refr.getAverage();
    double rnd = state.getRandom(0, 0, 1);
    if (rnd < avgR) {
        state.faceforward();
        // don't reflect internally
        if (state.isBehind()) {
            return;
        }
        // photon is reflected
        float cos = state.getCosND();
        power.mul(refl).mul(1.0f / avgR);
        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 if (rnd < avgR + avgT) {
        state.faceforward();
        // photon is refracted
        float cos = state.getCosND();
        float neta = state.isBehind() ? eta : 1.0f / eta;
        power.mul(refr).mul(1.0f / avgT);
        float wK = -neta;
        float arg = 1 - (neta * neta * (1 - (cos * cos)));
        Vector3 dir = new Vector3();
        if (state.isBehind() && absorptionDistance > 0) {
            // this ray is inside the object and leaving it
            // compute attenuation that occured along the ray
            power.mul(Color.mul(-state.getRay().getMax() / absorptionDistance, absorptionColor.copy().opposite()).exp());
        }
        if (arg < 0) {
            // TIR
            float dn = 2 * cos;
            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 nK = (neta * cos) - (float) Math.sqrt(arg);
            dir.x = (-wK * state.getRay().dx) + (nK * state.getNormal().x);
            dir.y = (-wK * state.getRay().dy) + (nK * state.getNormal().y);
            dir.z = (-wK * state.getRay().dz) + (nK * state.getNormal().z);
            state.traceRefractionPhoton(new Ray(state.getPoint(), dir), power);
        }
    }
}
Also used : Color(org.sunflow.image.Color) Vector3(org.sunflow.math.Vector3) Ray(org.sunflow.core.Ray)

Aggregations

Ray (org.sunflow.core.Ray)27 Vector3 (org.sunflow.math.Vector3)25 Color (org.sunflow.image.Color)22 OrthoNormalBasis (org.sunflow.math.OrthoNormalBasis)13 LightSample (org.sunflow.core.LightSample)9 Point3 (org.sunflow.math.Point3)5 ShadingState (org.sunflow.core.ShadingState)3 Instance (org.sunflow.core.Instance)1 Shader (org.sunflow.core.Shader)1 XYZColor (org.sunflow.image.XYZColor)1