use of org.sunflow.image.Color in project joons-renderer by joonhyublee.
the class UberShader method getRadiance.
public Color getRadiance(ShadingState state) {
// make sure we are on the right side of the material
state.faceforward();
// direct lighting
state.initLightSamples();
state.initCausticSamples();
Color d = getDiffuse(state);
Color lr = state.diffuse(d);
if (!state.includeSpecular()) {
return lr;
}
if (glossyness == 0) {
float cos = state.getCosND();
float dn = 2 * cos;
Vector3 refDir = new Vector3();
refDir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x;
refDir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y;
refDir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z;
Ray refRay = new Ray(state.getPoint(), refDir);
// compute Fresnel term
cos = 1 - cos;
float cos2 = cos * cos;
float cos5 = cos2 * cos2 * cos;
Color spec = getSpecular(state);
Color ret = Color.white();
ret.sub(spec);
ret.mul(cos5);
ret.add(spec);
return lr.add(ret.mul(state.traceReflection(refRay, 0)));
} else {
return lr.add(state.specularPhong(getSpecular(state), 2 / glossyness, numSamples));
}
}
use of org.sunflow.image.Color in project joons-renderer by joonhyublee.
the class SCParser method parseLightBlock.
private void parseLightBlock(SunflowAPIInterface api) throws ParserException, IOException, ColorSpecificationException {
p.checkNextToken("{");
p.checkNextToken(TYPE);
if (p.peekNextToken("mesh")) {
UI.printWarning(Module.API, "Deprecated light type: mesh");
p.checkNextToken(NAME);
String name = p.getNextToken();
UI.printInfo(Module.API, "Reading light mesh: %s ...", name);
p.checkNextToken(EMIT);
api.parameter(RADIANCE, null, parseColor().getRGB());
int samples = numLightSamples;
if (p.peekNextToken(SAMPLES)) {
samples = p.getNextInt();
} else {
UI.printWarning(Module.API, "Samples keyword not found - defaulting to %d", samples);
}
api.parameter(SAMPLES, samples);
int numVertices = p.getNextInt();
int numTriangles = p.getNextInt();
float[] points = new float[3 * numVertices];
int[] triangles = new int[3 * numTriangles];
for (int i = 0; i < numVertices; i++) {
p.checkNextToken("v");
points[3 * i + 0] = p.getNextFloat();
points[3 * i + 1] = p.getNextFloat();
points[3 * i + 2] = p.getNextFloat();
// ignored
p.getNextFloat();
p.getNextFloat();
p.getNextFloat();
p.getNextFloat();
p.getNextFloat();
}
for (int i = 0; i < numTriangles; i++) {
p.checkNextToken("t");
triangles[3 * i + 0] = p.getNextInt();
triangles[3 * i + 1] = p.getNextInt();
triangles[3 * i + 2] = p.getNextInt();
}
api.parameter(POINTS, POINT, VERTEX, points);
api.parameter(TRIANGLES, triangles);
api.light(name, TRIANGLE_MESH);
} else if (p.peekNextToken(POINT)) {
UI.printInfo(Module.API, "Reading point light ...");
Color pow;
if (p.peekNextToken(COLOR)) {
pow = parseColor();
p.checkNextToken(POWER);
float po = p.getNextFloat();
pow.mul(po);
} else {
UI.printWarning(Module.API, "Deprecated color specification - please use color and power instead");
p.checkNextToken(POWER);
pow = parseColor();
}
p.checkNextToken("p");
api.parameter(CENTER, parsePoint());
api.parameter(POWER, null, pow.getRGB());
api.light(generateUniqueName("pointlight"), POINT);
} else if (p.peekNextToken("spherical")) {
UI.printInfo(Module.API, "Reading spherical light ...");
p.checkNextToken(COLOR);
Color pow = parseColor();
p.checkNextToken(RADIANCE);
pow.mul(p.getNextFloat());
api.parameter(RADIANCE, null, pow.getRGB());
p.checkNextToken(CENTER);
api.parameter(CENTER, parsePoint());
p.checkNextToken(RADIUS);
api.parameter(RADIUS, p.getNextFloat());
p.checkNextToken(SAMPLES);
api.parameter(SAMPLES, p.getNextInt());
api.light(generateUniqueName("spherelight"), "sphere");
} else if (p.peekNextToken("directional")) {
UI.printInfo(Module.API, "Reading directional light ...");
p.checkNextToken("source");
Point3 s = parsePoint();
api.parameter("source", s);
p.checkNextToken("target");
Point3 t = parsePoint();
api.parameter("dir", Point3.sub(t, s, new Vector3()));
p.checkNextToken(RADIUS);
api.parameter(RADIUS, p.getNextFloat());
p.checkNextToken(EMIT);
Color e = parseColor();
if (p.peekNextToken("intensity")) {
float i = p.getNextFloat();
e.mul(i);
} else {
UI.printWarning(Module.API, "Deprecated color specification - please use emit and intensity instead");
}
api.parameter(RADIANCE, null, e.getRGB());
api.light(generateUniqueName("dirlight"), "directional");
} else if (p.peekNextToken("ibl")) {
UI.printInfo(Module.API, "Reading image based light ...");
p.checkNextToken("image");
api.parameter(TEXTURE, p.getNextToken());
p.checkNextToken(CENTER);
api.parameter(CENTER, parseVector());
p.checkNextToken("up");
api.parameter("up", parseVector());
p.checkNextToken("lock");
api.parameter("fixed", p.getNextBoolean());
int samples = numLightSamples;
if (p.peekNextToken(SAMPLES)) {
samples = p.getNextInt();
} else {
UI.printWarning(Module.API, "Samples keyword not found - defaulting to %d", samples);
}
api.parameter(SAMPLES, samples);
if (p.peekNextToken("lowsamples")) {
api.parameter("lowsamples", p.getNextInt());
} else {
api.parameter("lowsamples", samples);
}
api.light(generateUniqueName("ibl"), "ibl");
} else if (p.peekNextToken("meshlight")) {
p.checkNextToken(NAME);
String name = p.getNextToken();
UI.printInfo(Module.API, "Reading meshlight: %s ...", name);
p.checkNextToken(EMIT);
Color e = parseColor();
if (p.peekNextToken(RADIANCE)) {
float r = p.getNextFloat();
e.mul(r);
} else {
UI.printWarning(Module.API, "Deprecated color specification - please use emit and radiance instead");
}
api.parameter(RADIANCE, null, e.getRGB());
int samples = numLightSamples;
if (p.peekNextToken(SAMPLES)) {
samples = p.getNextInt();
} else {
UI.printWarning(Module.API, "Samples keyword not found - defaulting to %d", samples);
}
api.parameter(SAMPLES, samples);
// parse vertices
p.checkNextToken(POINTS);
int np = p.getNextInt();
api.parameter(POINTS, POINT, VERTEX, parseFloatArray(np * 3));
// parse triangle indices
p.checkNextToken(TRIANGLES);
int nt = p.getNextInt();
api.parameter(TRIANGLES, parseIntArray(nt * 3));
api.light(name, TRIANGLE_MESH);
} else if (p.peekNextToken("sunsky")) {
p.checkNextToken("up");
api.parameter("up", parseVector());
p.checkNextToken("east");
api.parameter("east", parseVector());
p.checkNextToken("sundir");
api.parameter("sundir", parseVector());
p.checkNextToken("turbidity");
api.parameter("turbidity", p.getNextFloat());
if (p.peekNextToken(SAMPLES)) {
api.parameter(SAMPLES, p.getNextInt());
}
if (p.peekNextToken("ground.extendsky")) {
api.parameter("ground.extendsky", p.getNextBoolean());
} else if (p.peekNextToken("ground.color")) {
api.parameter("ground.color", null, parseColor().getRGB());
}
api.light(generateUniqueName("sunsky"), "sunsky");
} else if (p.peekNextToken("cornellbox")) {
UI.printInfo(Module.API, "Reading cornell box ...");
p.checkNextToken("corner0");
api.parameter("corner0", parsePoint());
p.checkNextToken("corner1");
api.parameter("corner1", parsePoint());
p.checkNextToken("left");
api.parameter("leftColor", null, parseColor().getRGB());
p.checkNextToken("right");
api.parameter("rightColor", null, parseColor().getRGB());
p.checkNextToken("top");
api.parameter("topColor", null, parseColor().getRGB());
p.checkNextToken("bottom");
api.parameter("bottomColor", null, parseColor().getRGB());
p.checkNextToken("back");
api.parameter("backColor", null, parseColor().getRGB());
p.checkNextToken(EMIT);
api.parameter(RADIANCE, null, parseColor().getRGB());
if (p.peekNextToken(SAMPLES)) {
api.parameter(SAMPLES, p.getNextInt());
}
api.light(generateUniqueName("cornellbox"), "cornell_box");
} else {
UI.printWarning(Module.API, "Unrecognized object type: %s", p.getNextToken());
}
p.checkNextToken("}");
}
use of org.sunflow.image.Color in project joons-renderer by joonhyublee.
the class MultipassRenderer method renderBucket.
private void renderBucket(Display display, int bx, int by, int threadID, IntersectionState istate, ShadingCache cache) {
// pixel sized extents
int x0 = bx * bucketSize;
int y0 = by * bucketSize;
int bw = Math.min(bucketSize, imageWidth - x0);
int bh = Math.min(bucketSize, imageHeight - y0);
// prepare bucket
display.imagePrepare(x0, y0, bw, bh, threadID);
Color[] bucketRGB = new Color[bw * bh];
float[] bucketAlpha = new float[bw * bh];
for (int y = 0, i = 0, cy = imageHeight - 1 - y0; y < bh; y++, cy--) {
for (int x = 0, cx = x0; x < bw; x++, i++, cx++) {
// sample pixel
Color c = Color.black();
float a = 0;
int instance = ((cx & ((1 << QMC.MAX_SIGMA_ORDER) - 1)) << QMC.MAX_SIGMA_ORDER) + QMC.sigma(cy & ((1 << QMC.MAX_SIGMA_ORDER) - 1), QMC.MAX_SIGMA_ORDER);
double jitterX = QMC.halton(0, instance);
double jitterY = QMC.halton(1, instance);
double jitterT = QMC.halton(2, instance);
double jitterU = QMC.halton(3, instance);
double jitterV = QMC.halton(4, instance);
for (int s = 0; s < numSamples; s++) {
float rx = cx + 0.5f + (float) warpCubic(QMC.mod1(jitterX + s * invNumSamples));
float ry = cy + 0.5f + (float) warpCubic(QMC.mod1(jitterY + QMC.halton(0, s)));
double time = QMC.mod1(jitterT + QMC.halton(1, s));
double lensU = QMC.mod1(jitterU + QMC.halton(2, s));
double lensV = QMC.mod1(jitterV + QMC.halton(3, s));
ShadingState state = scene.getRadiance(istate, rx, ry, lensU, lensV, time, instance + s, 5, cache);
if (state != null) {
c.add(state.getResult());
a++;
}
}
bucketRGB[i] = c.mul(invNumSamples);
bucketAlpha[i] = a * invNumSamples;
if (cache != null) {
cache.reset();
}
}
}
// update pixels
display.imageUpdate(x0, y0, bw, bh, bucketRGB, bucketAlpha);
}
use of org.sunflow.image.Color in project joons-renderer by joonhyublee.
the class CausticPhotonMap method getSamples.
@Override
public void getSamples(ShadingState state) {
if (storedPhotons == 0) {
return;
}
NearestPhotons np = new NearestPhotons(state.getPoint(), gatherNum, gatherRadius * gatherRadius);
locatePhotons(np);
if (np.found < 8) {
return;
}
Point3 ppos = new Point3();
Vector3 pdir = new Vector3();
Vector3 pvec = new Vector3();
float invArea = 1.0f / ((float) Math.PI * np.dist2[0]);
float maxNDist = np.dist2[0] * 0.05f;
float f2r2 = 1.0f / (filterValue * filterValue * np.dist2[0]);
float fInv = 1.0f / (1.0f - 2.0f / (3.0f * filterValue));
for (int i = 1; i <= np.found; i++) {
Photon phot = np.index[i];
Vector3.decode(phot.dir, pdir);
float cos = -Vector3.dot(pdir, state.getNormal());
if (cos > 0.001) {
ppos.set(phot.x, phot.y, phot.z);
Point3.sub(ppos, state.getPoint(), pvec);
float pcos = Vector3.dot(pvec, state.getNormal());
if ((pcos < maxNDist) && (pcos > -maxNDist)) {
LightSample sample = new LightSample();
sample.setShadowRay(new Ray(state.getPoint(), pdir.negate()));
sample.setRadiance(new Color().setRGBE(np.index[i].power).mul(invArea / cos), Color.BLACK);
sample.getDiffuseRadiance().mul((1.0f - (float) Math.sqrt(np.dist2[i] * f2r2)) * fInv);
state.addSample(sample);
}
}
}
}
use of org.sunflow.image.Color in project joons-renderer by joonhyublee.
the class SimpleRenderer method renderBucket.
public void renderBucket(int bx, int by, IntersectionState istate) {
// pixel sized extents
int x0 = bx * 32;
int y0 = by * 32;
int bw = Math.min(32, imageWidth - x0);
int bh = Math.min(32, imageHeight - y0);
Color[] bucketRGB = new Color[bw * bh];
float[] bucketAlpha = new float[bw * bh];
for (int y = 0, i = 0; y < bh; y++) {
for (int x = 0; x < bw; x++, i++) {
ShadingState state = scene.getRadiance(istate, x0 + x, imageHeight - 1 - (y0 + y), 0.0, 0.0, 0.0, 0, 0, null);
bucketRGB[i] = (state != null) ? state.getResult() : Color.BLACK;
bucketAlpha[i] = (state != null) ? 1 : 0;
}
}
// update pixels
display.imageUpdate(x0, y0, bw, bh, bucketRGB, bucketAlpha);
}
Aggregations