use of org.sunflow.math.Vector3 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.math.Vector3 in project joons-renderer by joonhyublee.
the class Box method prepareShadingState.
@Override
public void prepareShadingState(ShadingState state) {
state.init();
state.getRay().getPoint(state.getPoint());
int n = state.getPrimitiveID();
switch(n) {
case 0:
state.getNormal().set(new Vector3(1, 0, 0));
break;
case 1:
state.getNormal().set(new Vector3(-1, 0, 0));
break;
case 2:
state.getNormal().set(new Vector3(0, 1, 0));
break;
case 3:
state.getNormal().set(new Vector3(0, -1, 0));
break;
case 4:
state.getNormal().set(new Vector3(0, 0, 1));
break;
case 5:
state.getNormal().set(new Vector3(0, 0, -1));
break;
default:
state.getNormal().set(new Vector3(0, 0, 0));
break;
}
state.getGeoNormal().set(state.getNormal());
state.setBasis(OrthoNormalBasis.makeFromW(state.getNormal()));
state.setShader(state.getInstance().getShader(0));
state.setModifier(state.getInstance().getModifier(0));
}
use of org.sunflow.math.Vector3 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.math.Vector3 in project joons-renderer by joonhyublee.
the class GridPhotonMap method prepare.
@Override
public void prepare(Options options, BoundingBox sceneBounds) {
// get settings
numEmit = options.getInt("gi.irr-cache.gmap.emit", 100000);
numGather = options.getInt("gi.irr-cache.gmap.gather", 50);
gatherRadius = options.getFloat("gi.irr-cache.gmap.radius", 0.5f);
bounds = new BoundingBox(sceneBounds);
bounds.enlargeUlps();
Vector3 w = bounds.getExtents();
nx = (int) Math.max(((w.x / gatherRadius) + 0.5f), 1);
ny = (int) Math.max(((w.y / gatherRadius) + 0.5f), 1);
nz = (int) Math.max(((w.z / gatherRadius) + 0.5f), 1);
int numCells = nx * ny * nz;
UI.printInfo(Module.LIGHT, "Initializing grid photon map:");
UI.printInfo(Module.LIGHT, " * Resolution: %dx%dx%d", nx, ny, nz);
UI.printInfo(Module.LIGHT, " * Total cells: %d", numCells);
for (hashPrime = 0; hashPrime < PRIMES.length; hashPrime++) {
if (PRIMES[hashPrime] > (numCells / 5)) {
break;
}
}
cellHash = new PhotonGroup[PRIMES[hashPrime]];
UI.printInfo(Module.LIGHT, " * Initial hash size: %d", cellHash.length);
}
use of org.sunflow.math.Vector3 in project joons-renderer by joonhyublee.
the class GridPhotonMap method store.
@Override
public void store(ShadingState state, Vector3 dir, Color power, Color diffuse) {
// don't store on the wrong side of a surface
if (Vector3.dot(state.getNormal(), dir) > 0) {
return;
}
Point3 pt = state.getPoint();
// outside grid bounds ?
if (!bounds.contains(pt)) {
return;
}
Vector3 ext = bounds.getExtents();
int ix = (int) (((pt.x - bounds.getMinimum().x) * nx) / ext.x);
int iy = (int) (((pt.y - bounds.getMinimum().y) * ny) / ext.y);
int iz = (int) (((pt.z - bounds.getMinimum().z) * nz) / ext.z);
ix = MathUtils.clamp(ix, 0, nx - 1);
iy = MathUtils.clamp(iy, 0, ny - 1);
iz = MathUtils.clamp(iz, 0, nz - 1);
int id = ix + iy * nx + iz * nx * ny;
synchronized (this) {
int hid = id % cellHash.length;
PhotonGroup g = cellHash[hid];
PhotonGroup last = null;
boolean hasID = false;
while (g != null) {
if (g.id == id) {
hasID = true;
if (Vector3.dot(state.getNormal(), g.normal) > NORMAL_THRESHOLD) {
break;
}
}
last = g;
g = g.next;
}
if (g == null) {
g = new PhotonGroup(id, state.getNormal());
if (last == null) {
cellHash[hid] = g;
} else {
last.next = g;
}
if (!hasID) {
// we have not seen this ID before
hashSize++;
// resize hash if we have grown too large
if (hashSize > cellHash.length) {
growPhotonHash();
}
}
}
g.count++;
g.flux.add(power);
g.diffuse.add(diffuse);
numStoredPhotons++;
}
}
Aggregations