Search in sources :

Example 1 with LightSample

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

the class DirectionalSpotlight method getSamples.

public void getSamples(ShadingState state) {
    if (Vector3.dot(dir, state.getGeoNormal()) < 0 && Vector3.dot(dir, state.getNormal()) < 0) {
        // project point onto source plane
        float x = state.getPoint().x - src.x;
        float y = state.getPoint().y - src.y;
        float z = state.getPoint().z - src.z;
        float t = ((x * dir.x) + (y * dir.y) + (z * dir.z));
        if (t >= 0.0) {
            x -= (t * dir.x);
            y -= (t * dir.y);
            z -= (t * dir.z);
            if (((x * x) + (y * y) + (z * z)) <= r2) {
                Point3 p = new Point3();
                p.x = src.x + x;
                p.y = src.y + y;
                p.z = src.z + z;
                LightSample dest = new LightSample();
                dest.setShadowRay(new Ray(state.getPoint(), p));
                dest.setRadiance(radiance, radiance);
                dest.traceShadow(state);
                state.addSample(dest);
            }
        }
    }
}
Also used : Point3(org.sunflow.math.Point3) LightSample(org.sunflow.core.LightSample) Ray(org.sunflow.core.Ray)

Example 2 with LightSample

use of org.sunflow.core.LightSample 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 3 with LightSample

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

the class Hair method getRadiance.

@Override
public Color getRadiance(ShadingState state) {
    // don't use these - gather lights for sphere of directions
    // gather lights
    state.initLightSamples();
    state.initCausticSamples();
    Vector3 v = state.getRay().getDirection();
    v.negate();
    Vector3 h = new Vector3();
    Vector3 t = state.getBasis().transform(new Vector3(0, 1, 0));
    Color diff = Color.black();
    Color spec = Color.black();
    for (LightSample ls : state) {
        Vector3 l = ls.getShadowRay().getDirection();
        float dotTL = Vector3.dot(t, l);
        float sinTL = (float) Math.sqrt(1 - dotTL * dotTL);
        // float dotVL = Vector3.dot(v, l);
        diff.madd(sinTL, ls.getDiffuseRadiance());
        Vector3.add(v, l, h);
        h.normalize();
        float dotTH = Vector3.dot(t, h);
        float sinTH = (float) Math.sqrt(1 - dotTH * dotTH);
        float s = (float) Math.pow(sinTH, 10.0f);
        spec.madd(s, ls.getSpecularRadiance());
    }
    Color c = Color.add(diff, spec, new Color());
    // transparency
    return Color.blend(c, state.traceTransparency(), state.getV(), new Color());
}
Also used : LightSample(org.sunflow.core.LightSample) Color(org.sunflow.image.Color) Vector3(org.sunflow.math.Vector3)

Example 4 with LightSample

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

the class ImageBasedLight method getSamples.

public void getSamples(ShadingState state) {
    if (samples == null) {
        int n = state.getDiffuseDepth() > 0 ? 1 : numSamples;
        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 dir = getDirection(su, sv);
            basis.transform(dir);
            if (Vector3.dot(dir, state.getGeoNormal()) > 0) {
                LightSample dest = new LightSample();
                dest.setShadowRay(new Ray(state.getPoint(), dir));
                dest.getShadowRay().setMax(Float.MAX_VALUE);
                Color radiance = texture.getPixel(su, sv);
                dest.setRadiance(radiance, radiance);
                dest.getDiffuseRadiance().mul(invP);
                dest.getSpecularRadiance().mul(invP);
                dest.traceShadow(state);
                state.addSample(dest);
            }
        }
    } else {
        if (state.getDiffuseDepth() > 0) {
            for (int i = 0; i < numLowSamples; i++) {
                if (Vector3.dot(lowSamples[i], state.getGeoNormal()) > 0 && Vector3.dot(lowSamples[i], state.getNormal()) > 0) {
                    LightSample dest = new LightSample();
                    dest.setShadowRay(new Ray(state.getPoint(), lowSamples[i]));
                    dest.getShadowRay().setMax(Float.MAX_VALUE);
                    dest.setRadiance(lowColors[i], lowColors[i]);
                    dest.traceShadow(state);
                    state.addSample(dest);
                }
            }
        } else {
            for (int i = 0; i < numSamples; i++) {
                if (Vector3.dot(samples[i], state.getGeoNormal()) > 0 && Vector3.dot(samples[i], state.getNormal()) > 0) {
                    LightSample dest = new LightSample();
                    dest.setShadowRay(new Ray(state.getPoint(), samples[i]));
                    dest.getShadowRay().setMax(Float.MAX_VALUE);
                    dest.setRadiance(colors[i], colors[i]);
                    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)

Example 5 with LightSample

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

the class AnisotropicWardShader method getRadiance.

public Color getRadiance(ShadingState state) {
    // make sure we are on the right side of the material
    state.faceforward();
    OrthoNormalBasis onb = state.getBasis();
    // direct lighting and caustics
    state.initLightSamples();
    state.initCausticSamples();
    Color lr = Color.black();
    // compute specular contribution
    if (state.includeSpecular()) {
        Vector3 in = state.getRay().getDirection().negate(new Vector3());
        for (LightSample sample : state) {
            float cosNL = sample.dot(state.getNormal());
            float fr = brdf(in, sample.getShadowRay().getDirection(), onb);
            lr.madd(cosNL * fr, sample.getSpecularRadiance());
        }
        // indirect lighting - specular
        if (numRays > 0) {
            int n = state.getDepth() == 0 ? numRays : 1;
            for (int i = 0; i < n; i++) {
                // specular indirect lighting
                double r1 = state.getRandom(i, 0, n);
                double r2 = state.getRandom(i, 1, n);
                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;
                onb.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;
                float no = onb.untransformZ(o);
                float ni = onb.untransformZ(in);
                float w = ih * cosTheta * cosTheta * cosTheta * (float) Math.sqrt(Math.abs(no / ni));
                Ray r = new Ray(state.getPoint(), o);
                lr.madd(w / n, state.traceGlossy(r, i));
            }
        }
        lr.mul(rhoS);
    }
    // add diffuse contribution
    lr.add(state.diffuse(getDiffuse(state)));
    return lr;
}
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

LightSample (org.sunflow.core.LightSample)11 Ray (org.sunflow.core.Ray)9 Color (org.sunflow.image.Color)8 Vector3 (org.sunflow.math.Vector3)8 Point3 (org.sunflow.math.Point3)4 OrthoNormalBasis (org.sunflow.math.OrthoNormalBasis)2 XYZColor (org.sunflow.image.XYZColor)1