Search in sources :

Example 41 with Color

use of org.sunflow.image.Color in project joons-renderer by joonhyublee.

the class ShadingState method occlusion.

/**
 * Ambient occlusion routine, returns a value between bright and dark
 * depending on the amount of geometric occlusion in the scene.
 *
 * @param samples number of sample rays
 * @param maxDist maximum length of the rays
 * @param bright color when nothing is occluded
 * @param dark color when fully occluded
 * @return occlusion color
 */
public final Color occlusion(int samples, float maxDist, Color bright, Color dark) {
    if (n == null) {
        // in case we got called on a geometry without orientation
        return bright;
    }
    // make sure we are on the right side of the material
    faceforward();
    OrthoNormalBasis onb = getBasis();
    Vector3 w = new Vector3();
    Color result = Color.black();
    for (int i = 0; i < samples; i++) {
        float xi = (float) getRandom(i, 0, samples);
        float xj = (float) 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(p, w);
        r.setMax(maxDist);
        result.add(Color.blend(bright, dark, traceShadow(r)));
    }
    return result.mul(1.0f / samples);
}
Also used : Color(org.sunflow.image.Color) Vector3(org.sunflow.math.Vector3) OrthoNormalBasis(org.sunflow.math.OrthoNormalBasis)

Example 42 with Color

use of org.sunflow.image.Color in project joons-renderer by joonhyublee.

the class ShadingState method specularPhong.

/**
 * Computes a phong specular response to the current light samples and
 * global illumination.
 *
 * @param spec specular color
 * @param power phong exponent
 * @param numRays number of glossy rays to trace
 * @return shaded color
 */
public final Color specularPhong(Color spec, float power, int numRays) {
    // integrate a phong specular function
    Color lr = Color.black();
    if (!includeSpecular || spec.isBlack()) {
        return lr;
    }
    // reflected direction
    float dn = 2 * cosND;
    Vector3 refDir = new Vector3();
    refDir.x = (dn * n.x) + r.dx;
    refDir.y = (dn * n.y) + r.dy;
    refDir.z = (dn * n.z) + r.dz;
    // direct lighting
    for (LightSample sample : this) {
        float cosNL = sample.dot(n);
        float cosLR = sample.dot(refDir);
        if (cosLR > 0) {
            lr.madd(cosNL * (float) Math.pow(cosLR, power), sample.getSpecularRadiance());
        }
    }
    // indirect lighting
    if (numRays > 0) {
        int numSamples = getDepth() == 0 ? numRays : 1;
        OrthoNormalBasis onb = OrthoNormalBasis.makeFromW(refDir);
        float mul = (2.0f * (float) Math.PI / (power + 1)) / numSamples;
        for (int i = 0; i < numSamples; i++) {
            // specular indirect lighting
            double r1 = getRandom(i, 0, numSamples);
            double r2 = getRandom(i, 1, numSamples);
            double u = 2 * Math.PI * r1;
            double s = (float) Math.pow(r2, 1 / (power + 1));
            double s1 = (float) Math.sqrt(1 - s * s);
            Vector3 w = new Vector3((float) (Math.cos(u) * s1), (float) (Math.sin(u) * s1), (float) s);
            w = onb.transform(w, new Vector3());
            float wn = Vector3.dot(w, n);
            if (wn > 0) {
                lr.madd(wn * mul, traceGlossy(new Ray(p, w), i));
            }
        }
    }
    lr.mul(spec).mul((power + 2) / (2.0f * (float) Math.PI));
    return lr;
}
Also used : Color(org.sunflow.image.Color) Vector3(org.sunflow.math.Vector3) OrthoNormalBasis(org.sunflow.math.OrthoNormalBasis)

Example 43 with Color

use of org.sunflow.image.Color in project joons-renderer by joonhyublee.

the class KDTree method build.

@Override
public void build(PrimitiveList primitives) {
    UI.printDetailed(Module.ACCEL, "KDTree settings");
    UI.printDetailed(Module.ACCEL, "  * Max Leaf Size:  %d", maxPrims);
    UI.printDetailed(Module.ACCEL, "  * Max Depth:      %d", MAX_DEPTH);
    UI.printDetailed(Module.ACCEL, "  * Traversal cost: %.2f", TRAVERSAL_COST);
    UI.printDetailed(Module.ACCEL, "  * Intersect cost: %.2f", INTERSECT_COST);
    UI.printDetailed(Module.ACCEL, "  * Empty bonus:    %.2f", EMPTY_BONUS);
    UI.printDetailed(Module.ACCEL, "  * Dump leaves:    %s", dump ? "enabled" : "disabled");
    Timer total = new Timer();
    total.start();
    primitiveList = primitives;
    // get the object space bounds
    bounds = primitives.getWorldBounds(null);
    int nPrim = primitiveList.getNumPrimitives(), nSplits = 0;
    BuildTask task = new BuildTask(nPrim);
    Timer prepare = new Timer();
    prepare.start();
    for (int i = 0; i < nPrim; i++) {
        for (int axis = 0; axis < 3; axis++) {
            float ls = primitiveList.getPrimitiveBound(i, 2 * axis + 0);
            float rs = primitiveList.getPrimitiveBound(i, 2 * axis + 1);
            if (ls == rs) {
                // flat in this dimension
                task.splits[nSplits] = pack(ls, PLANAR, axis, i);
                nSplits++;
            } else {
                task.splits[nSplits + 0] = pack(ls, OPENED, axis, i);
                task.splits[nSplits + 1] = pack(rs, CLOSED, axis, i);
                nSplits += 2;
            }
        }
    }
    task.n = nSplits;
    prepare.end();
    Timer t = new Timer();
    IntArray tempTree = new IntArray();
    IntArray tempList = new IntArray();
    tempTree.add(0);
    tempTree.add(1);
    t.start();
    // sort it
    Timer sorting = new Timer();
    sorting.start();
    radix12(task.splits, task.n);
    sorting.end();
    // build the actual tree
    BuildStats stats = new BuildStats();
    buildTree(bounds.getMinimum().x, bounds.getMaximum().x, bounds.getMinimum().y, bounds.getMaximum().y, bounds.getMinimum().z, bounds.getMaximum().z, task, 1, tempTree, 0, tempList, stats);
    t.end();
    // write out final arrays
    // free some memory
    task = null;
    tree = tempTree.trim();
    tempTree = null;
    this.primitives = tempList.trim();
    tempList = null;
    total.end();
    // display some extra info
    stats.printStats();
    UI.printDetailed(Module.ACCEL, "  * Node memory:    %s", Memory.sizeof(tree));
    UI.printDetailed(Module.ACCEL, "  * Object memory:  %s", Memory.sizeof(this.primitives));
    UI.printDetailed(Module.ACCEL, "  * Prepare time:   %s", prepare);
    UI.printDetailed(Module.ACCEL, "  * Sorting time:   %s", sorting);
    UI.printDetailed(Module.ACCEL, "  * Tree creation:  %s", t);
    UI.printDetailed(Module.ACCEL, "  * Build time:     %s", total);
    if (dump) {
        try {
            UI.printInfo(Module.ACCEL, "Dumping mtls to %s.mtl ...", dumpPrefix);
            FileWriter mtlFile = new FileWriter(dumpPrefix + ".mtl");
            int maxN = stats.maxObjects;
            for (int n = 0; n <= maxN; n++) {
                float blend = (float) n / (float) maxN;
                Color nc;
                if (blend < 0.25) {
                    nc = Color.blend(Color.BLUE, Color.GREEN, blend / 0.25f);
                } else if (blend < 0.5) {
                    nc = Color.blend(Color.GREEN, Color.YELLOW, (blend - 0.25f) / 0.25f);
                } else if (blend < 0.75) {
                    nc = Color.blend(Color.YELLOW, Color.RED, (blend - 0.50f) / 0.25f);
                } else {
                    nc = Color.MAGENTA;
                }
                mtlFile.write(String.format("newmtl mtl%d\n", n));
                float[] rgb = nc.getRGB();
                mtlFile.write("Ka 0.1 0.1 0.1\n");
                mtlFile.write(String.format("Kd %.12g %.12g %.12g\n", rgb[0], rgb[1], rgb[2]));
                mtlFile.write("illum 1\n\n");
            }
            FileWriter objFile = new FileWriter(dumpPrefix + ".obj");
            UI.printInfo(Module.ACCEL, "Dumping tree to %s.obj ...", dumpPrefix);
            dumpObj(0, 0, maxN, new BoundingBox(bounds), objFile, mtlFile);
            objFile.close();
            mtlFile.close();
        } catch (IOException e) {
            Logger.getLogger(KDTree.class.getName()).log(Level.SEVERE, null, e);
        }
    }
}
Also used : Timer(org.sunflow.system.Timer) IntArray(org.sunflow.util.IntArray) FileWriter(java.io.FileWriter) Color(org.sunflow.image.Color) BoundingBox(org.sunflow.math.BoundingBox) IOException(java.io.IOException)

Example 44 with Color

use of org.sunflow.image.Color in project joons-renderer by joonhyublee.

the class SunSkyLight method initSunSky.

private void initSunSky() {
    // perform all the required initialization of constants
    sunDirWorld.normalize();
    sunDir = basis.untransform(sunDirWorld, new Vector3());
    sunDir.normalize();
    sunTheta = (float) Math.acos(MathUtils.clamp(sunDir.z, -1, 1));
    if (sunDir.z > 0) {
        sunSpectralRadiance = computeAttenuatedSunlight(sunTheta, turbidity);
        // produce color suitable for rendering
        sunColor = RGBSpace.SRGB.convertXYZtoRGB(sunSpectralRadiance.toXYZ().mul(1e-4f)).constrainRGB();
    } else {
        sunSpectralRadiance = new ConstantSpectralCurve(0);
    }
    // sunSolidAngle = (float) (0.25 * Math.PI * 1.39 * 1.39 / (150 * 150));
    float theta2 = sunTheta * sunTheta;
    float theta3 = sunTheta * theta2;
    float T = turbidity;
    float T2 = turbidity * turbidity;
    double chi = (4.0 / 9.0 - T / 120.0) * (Math.PI - 2.0 * sunTheta);
    zenithY = (4.0453 * T - 4.9710) * Math.tan(chi) - 0.2155 * T + 2.4192;
    zenithY *= 1000;
    /* conversion from kcd/m^2 to cd/m^2 */
    zenithx = (0.00165 * theta3 - 0.00374 * theta2 + 0.00208 * sunTheta + 0) * T2 + (-0.02902 * theta3 + 0.06377 * theta2 - 0.03202 * sunTheta + 0.00394) * T + (0.11693 * theta3 - 0.21196 * theta2 + 0.06052 * sunTheta + 0.25885);
    zenithy = (0.00275 * theta3 - 0.00610 * theta2 + 0.00316 * sunTheta + 0) * T2 + (-0.04212 * theta3 + 0.08970 * theta2 - 0.04153 * sunTheta + 0.00515) * T + (0.15346 * theta3 - 0.26756 * theta2 + 0.06669 * sunTheta + 0.26688);
    perezY[0] = 0.17872 * T - 1.46303;
    perezY[1] = -0.35540 * T + 0.42749;
    perezY[2] = -0.02266 * T + 5.32505;
    perezY[3] = 0.12064 * T - 2.57705;
    perezY[4] = -0.06696 * T + 0.37027;
    perezx[0] = -0.01925 * T - 0.25922;
    perezx[1] = -0.06651 * T + 0.00081;
    perezx[2] = -0.00041 * T + 0.21247;
    perezx[3] = -0.06409 * T - 0.89887;
    perezx[4] = -0.00325 * T + 0.04517;
    perezy[0] = -0.01669 * T - 0.26078;
    perezy[1] = -0.09495 * T + 0.00921;
    perezy[2] = -0.00792 * T + 0.21023;
    perezy[3] = -0.04405 * T - 1.65369;
    perezy[4] = -0.01092 * T + 0.05291;
    final int w = 32, h = 32;
    imageHistogram = new float[w][h];
    colHistogram = new float[w];
    float du = 1.0f / w;
    float dv = 1.0f / h;
    for (int x = 0; x < w; x++) {
        for (int y = 0; y < h; y++) {
            float u = (x + 0.5f) * du;
            float v = (y + 0.5f) * dv;
            Color c = getSkyRGB(getDirection(u, v));
            imageHistogram[x][y] = c.getLuminance() * (float) Math.sin(Math.PI * v);
            if (y > 0) {
                imageHistogram[x][y] += imageHistogram[x][y - 1];
            }
        }
        colHistogram[x] = imageHistogram[x][h - 1];
        if (x > 0) {
            colHistogram[x] += colHistogram[x - 1];
        }
        for (int y = 0; y < h; y++) {
            imageHistogram[x][y] /= imageHistogram[x][h - 1];
        }
    }
    for (int x = 0; x < w; x++) {
        colHistogram[x] /= colHistogram[w - 1];
    }
    jacobian = (float) (2 * Math.PI * Math.PI) / (w * h);
}
Also used : ConstantSpectralCurve(org.sunflow.image.ConstantSpectralCurve) Color(org.sunflow.image.Color) XYZColor(org.sunflow.image.XYZColor) Vector3(org.sunflow.math.Vector3)

Example 45 with Color

use of org.sunflow.image.Color in project joons-renderer by joonhyublee.

the class SCAsciiParser method parseColor.

protected Color parseColor() throws IOException {
    String space = p.getNextToken();
    Color c = null;
    if (space.equals("sRGB nonlinear")) {
        float r = p.getNextFloat();
        float g = p.getNextFloat();
        float b = p.getNextFloat();
        c = new Color(r, g, b);
        c.toLinear();
    } else if (space.equals("sRGB linear")) {
        float r = p.getNextFloat();
        float g = p.getNextFloat();
        float b = p.getNextFloat();
        c = new Color(r, g, b);
    } else {
        UI.printWarning(Module.API, "Unrecognized color space: %s", space);
    }
    return c;
}
Also used : Color(org.sunflow.image.Color)

Aggregations

Color (org.sunflow.image.Color)48 Vector3 (org.sunflow.math.Vector3)34 Ray (org.sunflow.core.Ray)22 OrthoNormalBasis (org.sunflow.math.OrthoNormalBasis)15 LightSample (org.sunflow.core.LightSample)8 Point3 (org.sunflow.math.Point3)7 ShadingState (org.sunflow.core.ShadingState)6 Bitmap (org.sunflow.image.Bitmap)2 XYZColor (org.sunflow.image.XYZColor)2 Timer (org.sunflow.system.Timer)2 FileWriter (java.io.FileWriter)1 IOException (java.io.IOException)1 ConstantSpectralCurve (org.sunflow.image.ConstantSpectralCurve)1 GenericBitmap (org.sunflow.image.formats.GenericBitmap)1 BoundingBox (org.sunflow.math.BoundingBox)1 IntArray (org.sunflow.util.IntArray)1