use of org.sunflow.core.Ray in project joons-renderer by joonhyublee.
the class DirectionalSpotlight method getSamples.
public void getSamples(ShadingState state) {
if (Vector3.dot(dir, state.getGeoNormal()) < 0 && Vector3.dot(dir, state.getNormal()) < 0) {
// project point onto source plane
float x = state.getPoint().x - src.x;
float y = state.getPoint().y - src.y;
float z = state.getPoint().z - src.z;
float t = ((x * dir.x) + (y * dir.y) + (z * dir.z));
if (t >= 0.0) {
x -= (t * dir.x);
y -= (t * dir.y);
z -= (t * dir.z);
if (((x * x) + (y * y) + (z * z)) <= r2) {
Point3 p = new Point3();
p.x = src.x + x;
p.y = src.y + y;
p.z = src.z + z;
LightSample dest = new LightSample();
dest.setShadowRay(new Ray(state.getPoint(), p));
dest.setRadiance(radiance, radiance);
dest.traceShadow(state);
state.addSample(dest);
}
}
}
}
use of org.sunflow.core.Ray in project joons-renderer by joonhyublee.
the class SunSkyLight method getSamples.
public void getSamples(ShadingState state) {
if (Vector3.dot(sunDirWorld, state.getGeoNormal()) > 0 && Vector3.dot(sunDirWorld, state.getNormal()) > 0) {
LightSample dest = new LightSample();
dest.setShadowRay(new Ray(state.getPoint(), sunDirWorld));
dest.getShadowRay().setMax(Float.MAX_VALUE);
dest.setRadiance(sunColor, sunColor);
dest.traceShadow(state);
state.addSample(dest);
}
int n = state.getDiffuseDepth() > 0 ? 1 : numSkySamples;
for (int i = 0; i < n; i++) {
// random offset on unit square, we use the infinite version of
// getRandom because the light sampling is adaptive
double randX = state.getRandom(i, 0, n);
double randY = state.getRandom(i, 1, n);
int x = 0;
while (randX >= colHistogram[x] && x < colHistogram.length - 1) {
x++;
}
float[] rowHistogram = imageHistogram[x];
int y = 0;
while (randY >= rowHistogram[y] && y < rowHistogram.length - 1) {
y++;
}
// sample from (x, y)
float u = (float) ((x == 0) ? (randX / colHistogram[0]) : ((randX - colHistogram[x - 1]) / (colHistogram[x] - colHistogram[x - 1])));
float v = (float) ((y == 0) ? (randY / rowHistogram[0]) : ((randY - rowHistogram[y - 1]) / (rowHistogram[y] - rowHistogram[y - 1])));
float px = ((x == 0) ? colHistogram[0] : (colHistogram[x] - colHistogram[x - 1]));
float py = ((y == 0) ? rowHistogram[0] : (rowHistogram[y] - rowHistogram[y - 1]));
float su = (x + u) / colHistogram.length;
float sv = (y + v) / rowHistogram.length;
float invP = (float) Math.sin(sv * Math.PI) * jacobian / (n * px * py);
Vector3 localDir = getDirection(su, sv);
Vector3 dir = basis.transform(localDir, new Vector3());
if (Vector3.dot(dir, state.getGeoNormal()) > 0 && Vector3.dot(dir, state.getNormal()) > 0) {
LightSample dest = new LightSample();
dest.setShadowRay(new Ray(state.getPoint(), dir));
dest.getShadowRay().setMax(Float.MAX_VALUE);
Color radiance = getSkyRGB(localDir);
dest.setRadiance(radiance, radiance);
dest.getDiffuseRadiance().mul(invP);
dest.getSpecularRadiance().mul(invP);
dest.traceShadow(state);
state.addSample(dest);
}
}
}
use of org.sunflow.core.Ray in project joons-renderer by joonhyublee.
the class Hair method prepareShadingState.
@Override
public void prepareShadingState(ShadingState state) {
state.init();
Instance i = state.getInstance();
state.getRay().getPoint(state.getPoint());
Ray r = state.getRay();
Shader s = i.getShader(0);
state.setShader(s != null ? s : this);
int primID = state.getPrimitiveID();
int hair = primID / numSegments;
int line = primID % numSegments;
int vRoot = hair * 3 * (numSegments + 1);
int v0 = vRoot + line * 3;
// tangent vector
Vector3 v = getTangent(line, v0, state.getV());
v = state.transformVectorObjectToWorld(v);
state.setBasis(OrthoNormalBasis.makeFromWV(v, new Vector3(-r.dx, -r.dy, -r.dz)));
state.getBasis().swapVW();
// normal
state.getNormal().set(0, 0, 1);
state.getBasis().transform(state.getNormal());
state.getGeoNormal().set(state.getNormal());
state.getUV().set(0, (line + state.getV()) / numSegments);
}
use of org.sunflow.core.Ray in project joons-renderer by joonhyublee.
the class AmbientOcclusionGIEngine method getIrradiance.
@Override
public Color getIrradiance(ShadingState state, Color diffuseReflectance) {
OrthoNormalBasis onb = state.getBasis();
Vector3 w = new Vector3();
Color result = Color.black();
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) (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(state.getPoint(), w);
r.setMax(maxDist);
result.add(Color.blend(bright, dark, state.traceShadow(r)));
}
return result.mul((float) Math.PI / samples);
}
use of org.sunflow.core.Ray in project joons-renderer by joonhyublee.
the class ImageBasedLight method getSamples.
public void getSamples(ShadingState state) {
if (samples == null) {
int n = state.getDiffuseDepth() > 0 ? 1 : numSamples;
for (int i = 0; i < n; i++) {
// random offset on unit square, we use the infinite version of
// getRandom because the light sampling is adaptive
double randX = state.getRandom(i, 0, n);
double randY = state.getRandom(i, 1, n);
int x = 0;
while (randX >= colHistogram[x] && x < colHistogram.length - 1) {
x++;
}
float[] rowHistogram = imageHistogram[x];
int y = 0;
while (randY >= rowHistogram[y] && y < rowHistogram.length - 1) {
y++;
}
// sample from (x, y)
float u = (float) ((x == 0) ? (randX / colHistogram[0]) : ((randX - colHistogram[x - 1]) / (colHistogram[x] - colHistogram[x - 1])));
float v = (float) ((y == 0) ? (randY / rowHistogram[0]) : ((randY - rowHistogram[y - 1]) / (rowHistogram[y] - rowHistogram[y - 1])));
float px = ((x == 0) ? colHistogram[0] : (colHistogram[x] - colHistogram[x - 1]));
float py = ((y == 0) ? rowHistogram[0] : (rowHistogram[y] - rowHistogram[y - 1]));
float su = (x + u) / colHistogram.length;
float sv = (y + v) / rowHistogram.length;
float invP = (float) Math.sin(sv * Math.PI) * jacobian / (n * px * py);
Vector3 dir = getDirection(su, sv);
basis.transform(dir);
if (Vector3.dot(dir, state.getGeoNormal()) > 0) {
LightSample dest = new LightSample();
dest.setShadowRay(new Ray(state.getPoint(), dir));
dest.getShadowRay().setMax(Float.MAX_VALUE);
Color radiance = texture.getPixel(su, sv);
dest.setRadiance(radiance, radiance);
dest.getDiffuseRadiance().mul(invP);
dest.getSpecularRadiance().mul(invP);
dest.traceShadow(state);
state.addSample(dest);
}
}
} else {
if (state.getDiffuseDepth() > 0) {
for (int i = 0; i < numLowSamples; i++) {
if (Vector3.dot(lowSamples[i], state.getGeoNormal()) > 0 && Vector3.dot(lowSamples[i], state.getNormal()) > 0) {
LightSample dest = new LightSample();
dest.setShadowRay(new Ray(state.getPoint(), lowSamples[i]));
dest.getShadowRay().setMax(Float.MAX_VALUE);
dest.setRadiance(lowColors[i], lowColors[i]);
dest.traceShadow(state);
state.addSample(dest);
}
}
} else {
for (int i = 0; i < numSamples; i++) {
if (Vector3.dot(samples[i], state.getGeoNormal()) > 0 && Vector3.dot(samples[i], state.getNormal()) > 0) {
LightSample dest = new LightSample();
dest.setShadowRay(new Ray(state.getPoint(), samples[i]));
dest.getShadowRay().setMax(Float.MAX_VALUE);
dest.setRadiance(colors[i], colors[i]);
dest.traceShadow(state);
state.addSample(dest);
}
}
}
}
}
Aggregations