use of org.sunflow.math.Vector3 in project joons-renderer by joonhyublee.
the class PointLight method getSamples.
public void getSamples(ShadingState state) {
Vector3 d = Point3.sub(lightPoint, state.getPoint(), new Vector3());
if (Vector3.dot(d, state.getNormal()) > 0 && Vector3.dot(d, state.getGeoNormal()) > 0) {
LightSample dest = new LightSample();
// prepare shadow ray
dest.setShadowRay(new Ray(state.getPoint(), lightPoint));
float scale = 1.0f / (float) (4 * Math.PI * lightPoint.distanceToSquared(state.getPoint()));
dest.setRadiance(power, power);
dest.getDiffuseRadiance().mul(scale);
dest.getSpecularRadiance().mul(scale);
dest.traceShadow(state);
state.addSample(dest);
}
}
use of org.sunflow.math.Vector3 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);
}
use of org.sunflow.math.Vector3 in project joons-renderer by joonhyublee.
the class SunSkyLight method update.
public boolean update(ParameterList pl, SunflowAPI api) {
Vector3 up = pl.getVector("up", null);
Vector3 east = pl.getVector("east", null);
if (up != null && east != null) {
basis = OrthoNormalBasis.makeFromWV(up, east);
} else if (up != null) {
basis = OrthoNormalBasis.makeFromW(up);
}
numSkySamples = pl.getInt("samples", numSkySamples);
sunDirWorld = pl.getVector("sundir", sunDirWorld);
turbidity = pl.getFloat("turbidity", turbidity);
groundExtendSky = pl.getBoolean("ground.extendsky", groundExtendSky);
groundColor = pl.getColor("ground.color", groundColor);
// recompute model
initSunSky();
return true;
}
use of org.sunflow.math.Vector3 in project joons-renderer by joonhyublee.
the class IrradianceCacheGIEngine method getIrradiance.
@Override
public Color getIrradiance(ShadingState state, Color diffuseReflectance) {
if (samples <= 0) {
return Color.BLACK;
}
if (state.getDiffuseDepth() > 0) {
// do simple path tracing for additional bounces (single ray)
float xi = (float) state.getRandom(0, 0, 1);
float xj = (float) state.getRandom(0, 1, 1);
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);
Vector3 w = new Vector3();
w.x = cosPhi * sinTheta;
w.y = sinPhi * sinTheta;
w.z = cosTheta;
OrthoNormalBasis onb = state.getBasis();
onb.transform(w);
Ray r = new Ray(state.getPoint(), w);
ShadingState temp = state.traceFinalGather(r, 0);
return temp != null ? getGlobalRadiance(temp).copy().mul((float) Math.PI) : Color.BLACK;
}
rwl.readLock().lock();
Color irr;
try {
irr = getIrradiance(state.getPoint(), state.getNormal());
} finally {
rwl.readLock().unlock();
}
if (irr == null) {
// compute new sample
irr = Color.black();
OrthoNormalBasis onb = state.getBasis();
float invR = 0;
float minR = Float.POSITIVE_INFINITY;
Vector3 w = new Vector3();
for (int i = 0; i < samples; i++) {
float xi = (float) state.getRandom(i, 0, samples);
float xj = (float) state.getRandom(i, 1, samples);
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);
ShadingState temp = state.traceFinalGather(r, i);
if (temp != null) {
minR = Math.min(r.getMax(), minR);
invR += 1.0f / r.getMax();
temp.getInstance().prepareShadingState(temp);
irr.add(getGlobalRadiance(temp));
}
}
irr.mul((float) Math.PI / samples);
invR = samples / invR;
rwl.writeLock().lock();
try {
insert(state.getPoint(), state.getNormal(), invR, irr);
} finally {
rwl.writeLock().unlock();
}
}
return irr;
}
use of org.sunflow.math.Vector3 in project joons-renderer by joonhyublee.
the class Scene method getRadiance.
/**
* Get the radiance seen through a particular pixel
*
* @param istate intersection state for ray tracing
* @param rx pixel x coordinate
* @param ry pixel y coordinate
* @param lensU DOF sampling variable
* @param lensV DOF sampling variable
* @param time motion blur sampling variable
* @param instance QMC instance seed
* @return a shading state for the intersected primitive, or
* <code>null</code> if nothing is seen through the specifieFd point
*/
public ShadingState getRadiance(IntersectionState istate, float rx, float ry, double lensU, double lensV, double time, int instance, int dim, ShadingCache cache) {
istate.numEyeRays++;
float sceneTime = camera.getTime((float) time);
if (bakingPrimitives == null) {
Ray r = camera.getRay(rx, ry, imageWidth, imageHeight, lensU, lensV, sceneTime);
return r != null ? lightServer.getRadiance(rx, ry, sceneTime, instance, dim, r, istate, cache) : null;
} else {
Ray r = new Ray(rx / imageWidth, ry / imageHeight, -1, 0, 0, 1);
traceBake(r, istate);
if (!istate.hit()) {
return null;
}
ShadingState state = ShadingState.createState(istate, rx, ry, sceneTime, r, instance, dim, lightServer);
bakingPrimitives.prepareShadingState(state);
if (bakingViewDependent) {
state.setRay(camera.getRay(state.getPoint(), sceneTime));
} else {
Point3 p = state.getPoint();
Vector3 n = state.getNormal();
// create a ray coming from directly above the point being
// shaded
Ray incoming = new Ray(p.x + n.x, p.y + n.y, p.z + n.z, -n.x, -n.y, -n.z);
incoming.setMax(1);
state.setRay(incoming);
}
lightServer.shadeBakeResult(state);
return state;
}
}
Aggregations