Search in sources :

Example 1 with OrthoNormalBasis

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

the class TriangleMeshLight method getPhoton.

public void getPhoton(double randX1, double randY1, double randX2, double randY2, Point3 p, Vector3 dir, Color power) {
    double rnd = randX1 * totalArea;
    int j = areas.length - 1;
    for (int i = 0; i < areas.length; i++) {
        if (rnd < areas[i]) {
            j = i;
            break;
        }
        // try next triangle
        rnd -= areas[i];
    }
    rnd /= areas[j];
    randX1 = rnd;
    double s = Math.sqrt(1 - randX2);
    float u = (float) (randY2 * s);
    float v = (float) (1 - s);
    float w = 1 - u - v;
    int tri3 = j * 3;
    int index0 = 3 * triangles[tri3 + 0];
    int index1 = 3 * triangles[tri3 + 1];
    int index2 = 3 * triangles[tri3 + 2];
    p.x = w * points[index0 + 0] + u * points[index1 + 0] + v * points[index2 + 0];
    p.y = w * points[index0 + 1] + u * points[index1 + 1] + v * points[index2 + 1];
    p.z = w * points[index0 + 2] + u * points[index1 + 2] + v * points[index2 + 2];
    p.x += 0.001f * ngs[j].x;
    p.y += 0.001f * ngs[j].y;
    p.z += 0.001f * ngs[j].z;
    OrthoNormalBasis onb = OrthoNormalBasis.makeFromW(ngs[j]);
    u = (float) (2 * Math.PI * randX1);
    s = Math.sqrt(randY1);
    onb.transform(new Vector3((float) (Math.cos(u) * s), (float) (Math.sin(u) * s), (float) (Math.sqrt(1 - randY1))), dir);
    Color.mul((float) Math.PI * areas[j], radiance, power);
}
Also used : Vector3(org.sunflow.math.Vector3) OrthoNormalBasis(org.sunflow.math.OrthoNormalBasis)

Example 2 with OrthoNormalBasis

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

the class AmbientOcclusionGIEngine method getIrradiance.

@Override
public Color getIrradiance(ShadingState state, Color diffuseReflectance) {
    OrthoNormalBasis onb = state.getBasis();
    Vector3 w = new Vector3();
    Color result = Color.black();
    for (int i = 0; i < samples; i++) {
        float xi = (float) state.getRandom(i, 0, samples);
        float xj = (float) state.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(state.getPoint(), w);
        r.setMax(maxDist);
        result.add(Color.blend(bright, dark, state.traceShadow(r)));
    }
    return result.mul((float) Math.PI / samples);
}
Also used : Color(org.sunflow.image.Color) Vector3(org.sunflow.math.Vector3) Ray(org.sunflow.core.Ray) OrthoNormalBasis(org.sunflow.math.OrthoNormalBasis)

Example 3 with OrthoNormalBasis

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

Example 4 with OrthoNormalBasis

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

the class ShinyDiffuseShader method scatterPhoton.

public void scatterPhoton(ShadingState state, Color power) {
    Color diffuse;
    // make sure we are on the right side of the material
    state.faceforward();
    diffuse = getDiffuse(state);
    state.storePhoton(state.getRay().getDirection(), power, diffuse);
    float d = diffuse.getAverage();
    float r = d * refl;
    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) {
        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);
    }
}
Also used : Color(org.sunflow.image.Color) Vector3(org.sunflow.math.Vector3) Ray(org.sunflow.core.Ray) OrthoNormalBasis(org.sunflow.math.OrthoNormalBasis)

Example 5 with OrthoNormalBasis

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

the class PhongShader 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 = spec.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
        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 / avgS);
        OrthoNormalBasis onb = state.getBasis();
        double u = 2 * Math.PI * (rnd - avgD) / avgS;
        double v = state.getRandom(0, 1, 1);
        float s = (float) Math.pow(v, 1 / (this.power + 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