use of org.sunflow.image.Color in project joons-renderer by joonhyublee.
the class Hair method getRadiance.
@Override
public Color getRadiance(ShadingState state) {
// don't use these - gather lights for sphere of directions
// gather lights
state.initLightSamples();
state.initCausticSamples();
Vector3 v = state.getRay().getDirection();
v.negate();
Vector3 h = new Vector3();
Vector3 t = state.getBasis().transform(new Vector3(0, 1, 0));
Color diff = Color.black();
Color spec = Color.black();
for (LightSample ls : state) {
Vector3 l = ls.getShadowRay().getDirection();
float dotTL = Vector3.dot(t, l);
float sinTL = (float) Math.sqrt(1 - dotTL * dotTL);
// float dotVL = Vector3.dot(v, l);
diff.madd(sinTL, ls.getDiffuseRadiance());
Vector3.add(v, l, h);
h.normalize();
float dotTH = Vector3.dot(t, h);
float sinTH = (float) Math.sqrt(1 - dotTH * dotTH);
float s = (float) Math.pow(sinTH, 10.0f);
spec.madd(s, ls.getSpecularRadiance());
}
Color c = Color.add(diff, spec, new Color());
// transparency
return Color.blend(c, state.traceTransparency(), state.getV(), new Color());
}
use of org.sunflow.image.Color 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.image.Color 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);
}
}
}
}
}
use of org.sunflow.image.Color in project joons-renderer by joonhyublee.
the class ShadingState method diffuse.
/**
* Computes a plain diffuse response to the current light samples and global
* illumination.
*
* @param diff diffuse color
* @return shaded result
*/
public final Color diffuse(Color diff) {
// integrate a diffuse function
Color lr = Color.black();
if (diff.isBlack()) {
return lr;
}
for (LightSample sample : this) {
lr.madd(sample.dot(n), sample.getDiffuseRadiance());
}
lr.add(getIrradiance(diff));
return lr.mul(diff).mul(1.0f / (float) Math.PI);
}
use of org.sunflow.image.Color in project joons-renderer by joonhyublee.
the class LightServer method getRadiance.
ShadingState getRadiance(float rx, float ry, float time, int i, int d, Ray r, IntersectionState istate, ShadingCache cache) {
// set this value once - will stay constant for the entire ray-tree
istate.time = time;
scene.trace(r, istate);
if (istate.hit()) {
ShadingState state = ShadingState.createState(istate, rx, ry, time, r, i, d, this);
state.getInstance().prepareShadingState(state);
Shader shader = getShader(state);
if (shader == null) {
state.setResult(Color.BLACK);
return state;
}
if (cache != null) {
Color c = cache.lookup(state, shader);
if (c != null) {
state.setResult(c);
return state;
}
}
state.setResult(shader.getRadiance(state));
if (cache != null) {
cache.add(state, shader, state.getResult());
}
checkNanInf(state.getResult());
return state;
} else {
return null;
}
}
Aggregations