Search in sources :

Example 56 with Vector3

use of org.sunflow.math.Vector3 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 57 with Vector3

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

Example 58 with Vector3

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

the class GlassShader method getRadiance.

public Color getRadiance(ShadingState state) {
    if (!state.includeSpecular()) {
        return Color.BLACK;
    }
    Vector3 reflDir = new Vector3();
    Vector3 refrDir = new Vector3();
    state.faceforward();
    float cos = state.getCosND();
    boolean inside = state.isBehind();
    float neta = inside ? eta : 1.0f / eta;
    float dn = 2 * cos;
    reflDir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x;
    reflDir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y;
    reflDir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z;
    // refracted ray
    float arg = 1 - (neta * neta * (1 - (cos * cos)));
    boolean tir = arg < 0;
    if (tir) {
        refrDir.x = refrDir.y = refrDir.z = 0;
    } else {
        float nK = (neta * cos) - (float) Math.sqrt(arg);
        refrDir.x = (neta * state.getRay().dx) + (nK * state.getNormal().x);
        refrDir.y = (neta * state.getRay().dy) + (nK * state.getNormal().y);
        refrDir.z = (neta * state.getRay().dz) + (nK * state.getNormal().z);
    }
    // compute Fresnel terms
    float cosTheta1 = Vector3.dot(state.getNormal(), reflDir);
    float cosTheta2 = -Vector3.dot(state.getNormal(), refrDir);
    float pPara = (cosTheta1 - eta * cosTheta2) / (cosTheta1 + eta * cosTheta2);
    float pPerp = (eta * cosTheta1 - cosTheta2) / (eta * cosTheta1 + cosTheta2);
    float kr = 0.5f * (pPara * pPara + pPerp * pPerp);
    float kt = 1 - kr;
    Color absorbtion = null;
    if (inside && absorptionDistance > 0) {
        // this ray is inside the object and leaving it
        // compute attenuation that occured along the ray
        absorbtion = Color.mul(-state.getRay().getMax() / absorptionDistance, absorptionColor.copy().opposite()).exp();
        if (absorbtion.isBlack()) {
            // nothing goes through
            return Color.BLACK;
        }
    }
    // refracted ray
    Color ret = Color.black();
    if (!tir) {
        ret.madd(kt, state.traceRefraction(new Ray(state.getPoint(), refrDir), 0)).mul(color);
    }
    if (!inside || tir) {
        ret.add(Color.mul(kr, state.traceReflection(new Ray(state.getPoint(), reflDir), 0)).mul(color));
    }
    return absorbtion != null ? ret.mul(absorbtion) : ret;
}
Also used : Color(org.sunflow.image.Color) Vector3(org.sunflow.math.Vector3) Ray(org.sunflow.core.Ray)

Example 59 with Vector3

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

the class FileMesh method generate.

private TriangleMesh generate(int[] tris, float[] verts, boolean smoothNormals) {
    ParameterList pl = new ParameterList();
    pl.addIntegerArray("triangles", tris);
    pl.addPoints("points", InterpolationType.VERTEX, verts);
    if (smoothNormals) {
        // filled with 0's
        float[] normals = new float[verts.length];
        Point3 p0 = new Point3();
        Point3 p1 = new Point3();
        Point3 p2 = new Point3();
        Vector3 n = new Vector3();
        for (int i3 = 0; i3 < tris.length; i3 += 3) {
            int v0 = tris[i3 + 0];
            int v1 = tris[i3 + 1];
            int v2 = tris[i3 + 2];
            p0.set(verts[3 * v0 + 0], verts[3 * v0 + 1], verts[3 * v0 + 2]);
            p1.set(verts[3 * v1 + 0], verts[3 * v1 + 1], verts[3 * v1 + 2]);
            p2.set(verts[3 * v2 + 0], verts[3 * v2 + 1], verts[3 * v2 + 2]);
            // compute normal
            Point3.normal(p0, p1, p2, n);
            // add face normal to each vertex
            // note that these are not normalized so this in fact weights
            // each normal by the area of the triangle
            normals[3 * v0 + 0] += n.x;
            normals[3 * v0 + 1] += n.y;
            normals[3 * v0 + 2] += n.z;
            normals[3 * v1 + 0] += n.x;
            normals[3 * v1 + 1] += n.y;
            normals[3 * v1 + 2] += n.z;
            normals[3 * v2 + 0] += n.x;
            normals[3 * v2 + 1] += n.y;
            normals[3 * v2 + 2] += n.z;
        }
        // normalize all the vectors
        for (int i3 = 0; i3 < normals.length; i3 += 3) {
            n.set(normals[i3 + 0], normals[i3 + 1], normals[i3 + 2]);
            n.normalize();
            normals[i3 + 0] = n.x;
            normals[i3 + 1] = n.y;
            normals[i3 + 2] = n.z;
        }
        pl.addVectors("normals", InterpolationType.VERTEX, normals);
    }
    TriangleMesh m = new TriangleMesh();
    if (m.update(pl, null)) {
        return m;
    }
    // printed by the mesh itself - no need to repeat it here
    return null;
}
Also used : Point3(org.sunflow.math.Point3) TriangleMesh(org.sunflow.core.primitive.TriangleMesh) ParameterList(org.sunflow.core.ParameterList) Vector3(org.sunflow.math.Vector3)

Example 60 with Vector3

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

the class BezierMesh method tesselate.

public PrimitiveList tesselate() {
    float[] vertices = new float[patches.length * (subdivs + 1) * (subdivs + 1) * 3];
    float[] normals = smooth ? new float[patches.length * (subdivs + 1) * (subdivs + 1) * 3] : null;
    float[] uvs = new float[patches.length * (subdivs + 1) * (subdivs + 1) * 2];
    int[] indices = new int[patches.length * subdivs * subdivs * (quads ? 4 : (2 * 3))];
    int vidx = 0, pidx = 0;
    float step = 1.0f / subdivs;
    int vstride = subdivs + 1;
    Point3 p = new Point3();
    Vector3 n = smooth ? new Vector3() : null;
    for (float[] patch : patches) {
        // create patch vertices
        for (int i = 0, voff = 0; i <= subdivs; i++) {
            float u = i * step;
            float[] bu = bernstein(u);
            float[] bdu = bernsteinDeriv(u);
            for (int j = 0; j <= subdivs; j++, voff += 3) {
                float v = j * step;
                float[] bv = bernstein(v);
                float[] bdv = bernsteinDeriv(v);
                getPatchPoint(u, v, patch, bu, bv, bdu, bdv, p, n);
                vertices[vidx + voff + 0] = p.x;
                vertices[vidx + voff + 1] = p.y;
                vertices[vidx + voff + 2] = p.z;
                if (smooth) {
                    normals[vidx + voff + 0] = n.x;
                    normals[vidx + voff + 1] = n.y;
                    normals[vidx + voff + 2] = n.z;
                }
                uvs[(vidx + voff) / 3 * 2 + 0] = u;
                uvs[(vidx + voff) / 3 * 2 + 1] = v;
            }
        }
        // generate patch triangles
        for (int i = 0, vbase = vidx / 3; i < subdivs; i++) {
            for (int j = 0; j < subdivs; j++) {
                int v00 = (i + 0) * vstride + (j + 0);
                int v10 = (i + 1) * vstride + (j + 0);
                int v01 = (i + 0) * vstride + (j + 1);
                int v11 = (i + 1) * vstride + (j + 1);
                if (quads) {
                    indices[pidx + 0] = vbase + v01;
                    indices[pidx + 1] = vbase + v00;
                    indices[pidx + 2] = vbase + v10;
                    indices[pidx + 3] = vbase + v11;
                    pidx += 4;
                } else {
                    // add 2 triangles
                    indices[pidx + 0] = vbase + v00;
                    indices[pidx + 1] = vbase + v10;
                    indices[pidx + 2] = vbase + v01;
                    indices[pidx + 3] = vbase + v10;
                    indices[pidx + 4] = vbase + v11;
                    indices[pidx + 5] = vbase + v01;
                    pidx += 6;
                }
            }
        }
        vidx += vstride * vstride * 3;
    }
    ParameterList pl = new ParameterList();
    pl.addPoints("points", InterpolationType.VERTEX, vertices);
    if (quads) {
        pl.addIntegerArray("quads", indices);
    } else {
        pl.addIntegerArray("triangles", indices);
    }
    pl.addTexCoords("uvs", InterpolationType.VERTEX, uvs);
    if (smooth) {
        pl.addVectors("normals", InterpolationType.VERTEX, normals);
    }
    PrimitiveList m = quads ? new QuadMesh() : new TriangleMesh();
    m.update(pl, null);
    pl.clear(true);
    return m;
}
Also used : QuadMesh(org.sunflow.core.primitive.QuadMesh) Point3(org.sunflow.math.Point3) PrimitiveList(org.sunflow.core.PrimitiveList) TriangleMesh(org.sunflow.core.primitive.TriangleMesh) ParameterList(org.sunflow.core.ParameterList) Vector3(org.sunflow.math.Vector3)

Aggregations

Vector3 (org.sunflow.math.Vector3)75 Color (org.sunflow.image.Color)34 Point3 (org.sunflow.math.Point3)27 Ray (org.sunflow.core.Ray)25 OrthoNormalBasis (org.sunflow.math.OrthoNormalBasis)17 Instance (org.sunflow.core.Instance)11 LightSample (org.sunflow.core.LightSample)8 ShadingState (org.sunflow.core.ShadingState)3 ParameterList (org.sunflow.core.ParameterList)2 TriangleMesh (org.sunflow.core.primitive.TriangleMesh)2 XYZColor (org.sunflow.image.XYZColor)2 Timer (org.sunflow.system.Timer)2 File (java.io.File)1 FileInputStream (java.io.FileInputStream)1 FileNotFoundException (java.io.FileNotFoundException)1 IOException (java.io.IOException)1 FloatBuffer (java.nio.FloatBuffer)1 MappedByteBuffer (java.nio.MappedByteBuffer)1 ReentrantReadWriteLock (java.util.concurrent.locks.ReentrantReadWriteLock)1 PrimitiveList (org.sunflow.core.PrimitiveList)1