use of org.sunflow.core.ShadingState in project joons-renderer by joonhyublee.
the class ProgressiveRenderer method progressiveRenderNext.
private int progressiveRenderNext(IntersectionState istate) {
final int TASK_SIZE = 16;
SmallBucket first = smallBucketQueue.poll();
if (first == null) {
return 0;
}
int ds = first.size / TASK_SIZE;
boolean useMask = !smallBucketQueue.isEmpty();
int mask = 2 * first.size / TASK_SIZE - 1;
int pixels = 0;
for (int i = 0, y = first.y; i < TASK_SIZE && y < imageHeight; i++, y += ds) {
for (int j = 0, x = first.x; j < TASK_SIZE && x < imageWidth; j++, x += ds) {
// check to see if this is a pixel from a higher level tile
if (useMask && (x & mask) == 0 && (y & mask) == 0) {
continue;
}
int instance = ((x & ((1 << QMC.MAX_SIGMA_ORDER) - 1)) << QMC.MAX_SIGMA_ORDER) + QMC.sigma(y & ((1 << QMC.MAX_SIGMA_ORDER) - 1), QMC.MAX_SIGMA_ORDER);
double time = QMC.halton(1, instance);
double lensU = QMC.halton(2, instance);
double lensV = QMC.halton(3, instance);
ShadingState state = scene.getRadiance(istate, x, imageHeight - 1 - y, lensU, lensV, time, instance, 4, null);
Color c = state != null ? state.getResult() : Color.BLACK;
pixels++;
// fill region
display.imageFill(x, y, Math.min(ds, imageWidth - x), Math.min(ds, imageHeight - y), c, state == null ? 0 : 1);
}
}
if (first.size >= 2 * TASK_SIZE) {
// generate child buckets
int size = first.size >>> 1;
for (int i = 0; i < 2; i++) {
if (first.y + i * size < imageHeight) {
for (int j = 0; j < 2; j++) {
if (first.x + j * size < imageWidth) {
SmallBucket b = new SmallBucket();
b.x = first.x + j * size;
b.y = first.y + i * size;
b.size = size;
b.constrast = 1.0f / size;
smallBucketQueue.put(b);
}
}
}
}
}
return pixels;
}
use of org.sunflow.core.ShadingState 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.core.ShadingState 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);
}
use of org.sunflow.core.ShadingState in project joons-renderer by joonhyublee.
the class InstantGI method getIrradiance.
@Override
public Color getIrradiance(ShadingState state, Color diffuseReflectance) {
float b = (float) Math.PI * c / diffuseReflectance.getMax();
Color irr = Color.black();
Point3 p = state.getPoint();
Vector3 n = state.getNormal();
int set = (int) (state.getRandom(0, 1, 1) * numSets);
for (PointLight vpl : virtualLights[set]) {
Ray r = new Ray(p, vpl.p);
float dotNlD = -(r.dx * vpl.n.x + r.dy * vpl.n.y + r.dz * vpl.n.z);
float dotND = r.dx * n.x + r.dy * n.y + r.dz * n.z;
if (dotNlD > 0 && dotND > 0) {
float r2 = r.getMax() * r.getMax();
Color opacity = state.traceShadow(r);
Color power = Color.blend(vpl.power, Color.BLACK, opacity);
float g = (dotND * dotNlD) / r2;
irr.madd(0.25f * Math.min(g, b), power);
}
}
// bias compensation
int nb = (state.getDiffuseDepth() == 0 || numBias <= 0) ? numBias : 1;
if (nb <= 0) {
return irr;
}
OrthoNormalBasis onb = state.getBasis();
Vector3 w = new Vector3();
float scale = (float) Math.PI / nb;
for (int i = 0; i < nb; i++) {
float xi = (float) state.getRandom(i, 0, nb);
float xj = (float) state.getRandom(i, 1, nb);
float phi = (float) (xi * 2 * Math.PI);
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(state.getPoint(), w);
r.setMax((float) Math.sqrt(cosTheta / b));
ShadingState temp = state.traceFinalGather(r, i);
if (temp != null) {
temp.getInstance().prepareShadingState(temp);
if (temp.getShader() != null) {
float dist = temp.getRay().getMax();
float r2 = dist * dist;
float cosThetaY = -Vector3.dot(w, temp.getNormal());
if (cosThetaY > 0) {
float g = (cosTheta * cosThetaY) / r2;
// was this path accounted for yet?
if (g > b) {
irr.madd(scale * (g - b) / g, temp.getShader().getRadiance(temp));
}
}
}
}
}
return irr;
}
use of org.sunflow.core.ShadingState in project joons-renderer by joonhyublee.
the class PathTracingGIEngine method getIrradiance.
@Override
public Color getIrradiance(ShadingState state, Color diffuseReflectance) {
if (samples <= 0) {
return Color.BLACK;
}
// compute new sample
Color irr = Color.black();
OrthoNormalBasis onb = state.getBasis();
Vector3 w = new Vector3();
int n = state.getDiffuseDepth() == 0 ? samples : 1;
for (int i = 0; i < n; i++) {
float xi = (float) state.getRandom(i, 0, n);
float xj = (float) state.getRandom(i, 1, n);
float phi = (float) (xi * 2 * Math.PI);
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);
ShadingState temp = state.traceFinalGather(new Ray(state.getPoint(), w), i);
if (temp != null) {
temp.getInstance().prepareShadingState(temp);
if (temp.getShader() != null) {
irr.add(temp.getShader().getRadiance(temp));
}
}
}
irr.mul((float) Math.PI / n);
return irr;
}
Aggregations