Search in sources :

Example 1 with Point3

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

the class TriangleMesh method prepareShadingState.

@Override
public void prepareShadingState(ShadingState state) {
    state.init();
    Instance parent = state.getInstance();
    int primID = state.getPrimitiveID();
    float u = state.getU();
    float v = state.getV();
    float w = 1 - u - v;
    state.getRay().getPoint(state.getPoint());
    int tri = 3 * primID;
    int index0 = triangles[tri + 0];
    int index1 = triangles[tri + 1];
    int index2 = triangles[tri + 2];
    Point3 v0p = getPoint(index0);
    Point3 v1p = getPoint(index1);
    Point3 v2p = getPoint(index2);
    Vector3 ng = Point3.normal(v0p, v1p, v2p);
    ng = state.transformNormalObjectToWorld(ng);
    ng.normalize();
    state.getGeoNormal().set(ng);
    switch(normals.interp) {
        case NONE:
        case FACE:
            {
                state.getNormal().set(ng);
                break;
            }
        case VERTEX:
            {
                int i30 = 3 * index0;
                int i31 = 3 * index1;
                int i32 = 3 * index2;
                float[] normalsu = this.normals.data;
                state.getNormal().x = w * normalsu[i30 + 0] + u * normalsu[i31 + 0] + v * normalsu[i32 + 0];
                state.getNormal().y = w * normalsu[i30 + 1] + u * normalsu[i31 + 1] + v * normalsu[i32 + 1];
                state.getNormal().z = w * normalsu[i30 + 2] + u * normalsu[i31 + 2] + v * normalsu[i32 + 2];
                state.getNormal().set(state.transformNormalObjectToWorld(state.getNormal()));
                state.getNormal().normalize();
                break;
            }
        case FACEVARYING:
            {
                int idx = 3 * tri;
                float[] normalsu = this.normals.data;
                state.getNormal().x = w * normalsu[idx + 0] + u * normalsu[idx + 3] + v * normalsu[idx + 6];
                state.getNormal().y = w * normalsu[idx + 1] + u * normalsu[idx + 4] + v * normalsu[idx + 7];
                state.getNormal().z = w * normalsu[idx + 2] + u * normalsu[idx + 5] + v * normalsu[idx + 8];
                state.getNormal().set(state.transformNormalObjectToWorld(state.getNormal()));
                state.getNormal().normalize();
                break;
            }
    }
    float uv00 = 0, uv01 = 0, uv10 = 0, uv11 = 0, uv20 = 0, uv21 = 0;
    switch(uvs.interp) {
        case NONE:
        case FACE:
            {
                state.getUV().x = 0;
                state.getUV().y = 0;
                break;
            }
        case VERTEX:
            {
                int i20 = 2 * index0;
                int i21 = 2 * index1;
                int i22 = 2 * index2;
                float[] uvsu = this.uvs.data;
                uv00 = uvsu[i20 + 0];
                uv01 = uvsu[i20 + 1];
                uv10 = uvsu[i21 + 0];
                uv11 = uvsu[i21 + 1];
                uv20 = uvsu[i22 + 0];
                uv21 = uvsu[i22 + 1];
                break;
            }
        case FACEVARYING:
            {
                int idx = tri << 1;
                float[] uvsu = this.uvs.data;
                uv00 = uvsu[idx + 0];
                uv01 = uvsu[idx + 1];
                uv10 = uvsu[idx + 2];
                uv11 = uvsu[idx + 3];
                uv20 = uvsu[idx + 4];
                uv21 = uvsu[idx + 5];
                break;
            }
    }
    if (uvs.interp != InterpolationType.NONE) {
        // get exact uv coords and compute tangent vectors
        state.getUV().x = w * uv00 + u * uv10 + v * uv20;
        state.getUV().y = w * uv01 + u * uv11 + v * uv21;
        float du1 = uv00 - uv20;
        float du2 = uv10 - uv20;
        float dv1 = uv01 - uv21;
        float dv2 = uv11 - uv21;
        Vector3 dp1 = Point3.sub(v0p, v2p, new Vector3()), dp2 = Point3.sub(v1p, v2p, new Vector3());
        float determinant = du1 * dv2 - dv1 * du2;
        if (determinant == 0.0f) {
            // create basis in world space
            state.setBasis(OrthoNormalBasis.makeFromW(state.getNormal()));
        } else {
            float invdet = 1.f / determinant;
            // Vector3 dpdu = new Vector3();
            // dpdu.x = (dv2 * dp1.x - dv1 * dp2.x) * invdet;
            // dpdu.y = (dv2 * dp1.y - dv1 * dp2.y) * invdet;
            // dpdu.z = (dv2 * dp1.z - dv1 * dp2.z) * invdet;
            Vector3 dpdv = new Vector3();
            dpdv.x = (-du2 * dp1.x + du1 * dp2.x) * invdet;
            dpdv.y = (-du2 * dp1.y + du1 * dp2.y) * invdet;
            dpdv.z = (-du2 * dp1.z + du1 * dp2.z) * invdet;
            dpdv = state.transformVectorObjectToWorld(dpdv);
            // create basis in world space
            state.setBasis(OrthoNormalBasis.makeFromWV(state.getNormal(), dpdv));
        }
    } else {
        state.setBasis(OrthoNormalBasis.makeFromW(state.getNormal()));
    }
    int shaderIndex = faceShaders == null ? 0 : (faceShaders[primID] & 0xFF);
    state.setShader(parent.getShader(shaderIndex));
    state.setModifier(parent.getModifier(shaderIndex));
}
Also used : Point3(org.sunflow.math.Point3) Instance(org.sunflow.core.Instance) Vector3(org.sunflow.math.Vector3)

Example 2 with Point3

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

the class CausticPhotonMap method store.

@Override
public void store(ShadingState state, Vector3 dir, Color power, Color diffuse) {
    if (((state.getDiffuseDepth() == 0) && (state.getReflectionDepth() > 0 || state.getRefractionDepth() > 0))) {
        // this is a caustic photon
        Photon p = new Photon(state.getPoint(), dir, power);
        synchronized (this) {
            storedPhotons++;
            photonList.add(p);
            bounds.include(new Point3(p.x, p.y, p.z));
            maxPower = Math.max(maxPower, power.getMax());
        }
    }
}
Also used : Point3(org.sunflow.math.Point3)

Example 3 with Point3

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

the class SCParser method parseCameraMatrix.

private void parseCameraMatrix(int index, SunflowAPIInterface api) throws IOException, ParserException {
    String offset = index < 0 ? "" : String.format("[%d]", index);
    if (p.peekNextToken(TRANSFORM)) {
        // advanced camera
        api.parameter(String.format("transform%s", offset), parseMatrix());
    } else {
        if (index >= 0) {
            p.checkNextToken("{");
        }
        // regular camera specification
        p.checkNextToken("eye");
        Point3 eye = parsePoint();
        p.checkNextToken("target");
        Point3 target = parsePoint();
        p.checkNextToken("up");
        Vector3 up = parseVector();
        api.parameter(String.format("transform%s", offset), Matrix4.lookAt(eye, target, up));
        if (index >= 0) {
            p.checkNextToken("}");
        }
    }
}
Also used : Point3(org.sunflow.math.Point3) Vector3(org.sunflow.math.Vector3)

Example 4 with Point3

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

the class GlobalPhotonMap method precomputeRadiance.

public void precomputeRadiance() {
    if (storedPhotons == 0) {
        return;
    }
    // precompute the radiance for all photons that are neither
    // leaves nor parents of leaves in the tree.
    int quadStoredPhotons = halfStoredPhotons / 2;
    Point3 p = new Point3();
    Vector3 n = new Vector3();
    Point3 ppos = new Point3();
    Vector3 pdir = new Vector3();
    Vector3 pvec = new Vector3();
    Color irr = new Color();
    Color pow = new Color();
    float maxDist2 = gatherRadius * gatherRadius;
    NearestPhotons np = new NearestPhotons(p, numGather, maxDist2);
    Photon[] temp = new Photon[quadStoredPhotons + 1];
    UI.taskStart("Precomputing radiance", 1, quadStoredPhotons);
    for (int i = 1; i <= quadStoredPhotons; i++) {
        UI.taskUpdate(i);
        Photon curr = photons[i];
        p.set(curr.x, curr.y, curr.z);
        Vector3.decode(curr.normal, n);
        irr.set(Color.BLACK);
        np.reset(p, maxDist2);
        locatePhotons(np);
        if (np.found < 8) {
            curr.data = 0;
            temp[i] = curr;
            continue;
        }
        float invArea = 1.0f / ((float) Math.PI * np.dist2[0]);
        float maxNDist = np.dist2[0] * 0.05f;
        for (int j = 1; j <= np.found; j++) {
            Photon phot = np.index[j];
            Vector3.decode(phot.dir, pdir);
            float cos = -Vector3.dot(pdir, n);
            if (cos > 0.01f) {
                ppos.set(phot.x, phot.y, phot.z);
                Point3.sub(ppos, p, pvec);
                float pcos = Vector3.dot(pvec, n);
                if ((pcos < maxNDist) && (pcos > -maxNDist)) {
                    irr.add(pow.setRGBE(phot.power));
                }
            }
        }
        irr.mul(invArea);
        // compute radiance
        irr.mul(new Color(curr.data)).mul(1.0f / (float) Math.PI);
        curr.data = irr.toRGBE();
        temp[i] = curr;
    }
    UI.taskStop();
    // resize photon map to only include irradiance photons
    numGather /= 4;
    maxRadius = 1.4f * (float) Math.sqrt(maxPower * numGather);
    if (gatherRadius > maxRadius) {
        gatherRadius = maxRadius;
    }
    storedPhotons = quadStoredPhotons;
    halfStoredPhotons = storedPhotons / 2;
    log2n = (int) Math.ceil(Math.log(storedPhotons) / Math.log(2.0));
    photons = temp;
    hasRadiance = true;
}
Also used : Point3(org.sunflow.math.Point3) Color(org.sunflow.image.Color) Vector3(org.sunflow.math.Vector3)

Example 5 with Point3

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

Aggregations

Point3 (org.sunflow.math.Point3)39 Vector3 (org.sunflow.math.Vector3)27 Instance (org.sunflow.core.Instance)9 Color (org.sunflow.image.Color)7 Ray (org.sunflow.core.Ray)5 LightSample (org.sunflow.core.LightSample)4 TriangleMesh (org.sunflow.core.primitive.TriangleMesh)3 ParameterList (org.sunflow.core.ParameterList)2 Matrix4 (org.sunflow.math.Matrix4)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 PrimitiveList (org.sunflow.core.PrimitiveList)1 SceneParser (org.sunflow.core.SceneParser)1 ShadingState (org.sunflow.core.ShadingState)1 QuadMesh (org.sunflow.core.primitive.QuadMesh)1 BoundingBox (org.sunflow.math.BoundingBox)1