public void scatterPhoton(ShadingState state, Color power) { Color diffuse, specular; // make sure we are on the right side of the material state.faceforward(); diffuse = getDiffuse(state); specular = getSpecular(state); state.storePhoton(state.getRay().getDirection(), power, diffuse); float d = diffuse.getAverage(); float r = specular.getAverage(); double rnd = state.getRandom(0, 0, 1); if (rnd < d) { // photon is scattered power.mul(diffuse).mul(1.0f / d); OrthoNormalBasis onb = state.getBasis(); double u = 2 * Math.PI * rnd / d; double v = state.getRandom(0, 1, 1); float s = (float)Math.Sqrt(v); float s1 = (float)Math.Sqrt(1.0 - v); Vector3 w = new Vector3((float)Math.Cos(u) * s, (float)Math.Sin(u) * s, s1); w = onb.transform(w, new Vector3()); state.traceDiffusePhoton(new Ray(state.getPoint(), w), power); } else if (rnd < d + r) { if (glossyness == 0) { float cos = -Vector3.dot(state.getNormal(), state.getRay().getDirection()); power.mul(diffuse).mul(1.0f / d); // photon is reflected float dn = 2 * cos; Vector3 dir = new Vector3(); dir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x; dir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y; dir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z; state.traceReflectionPhoton(new Ray(state.getPoint(), dir), power); } else { float dn = 2.0f * state.getCosND(); // reflected direction Vector3 refDir = new Vector3(); refDir.x = (dn * state.getNormal().x) + state.getRay().dx; refDir.y = (dn * state.getNormal().y) + state.getRay().dy; refDir.z = (dn * state.getNormal().z) + state.getRay().dz; power.mul(spec).mul(1.0f / r); OrthoNormalBasis onb = state.getBasis(); double u = 2 * Math.PI * (rnd - r) / r; double v = state.getRandom(0, 1, 1); float s = (float)Math.Pow(v, 1 / ((1.0f / glossyness) + 1)); float s1 = (float)Math.Sqrt(1 - s * s); Vector3 w = new Vector3((float)Math.Cos(u) * s1, (float)Math.Sin(u) * s1, s); w = onb.transform(w, new Vector3()); state.traceReflectionPhoton(new Ray(state.getPoint(), w), power); } } }
public Color getRadiance(ShadingState state) { if (!state.includeSpecular) { return(Color.BLACK); } state.faceforward(); float cos = state.getCosND(); float dn = 2 * cos; Vector3 refDir = new Vector3(); refDir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x; refDir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y; refDir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z; Ray refRay = new Ray(state.getPoint(), refDir); // compute Fresnel term cos = 1 - cos; float cos2 = cos * cos; float cos5 = cos2 * cos2 * cos; Color ret = Color.white(); ret.sub(color); ret.mul(cos5); ret.add(color); return(ret.mul(state.traceReflection(refRay, 0))); }
public Color GetRadiance(ShadingState state) { // make sure we are on the right side of the material state.faceforward(); // direct lighting state.initLightSamples(); state.initCausticSamples(); Color d = getDiffuse(state); Color lr = state.diffuse(d); if (!state.includeSpecular) return lr; if (glossyness == 0) { float cos = state.getCosND(); float dn = 2 * cos; Vector3 refDir = new Vector3(); refDir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x; refDir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y; refDir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z; Ray refRay = new Ray(state.getPoint(), refDir); // compute Fresnel term cos = 1 - cos; float cos2 = cos * cos; float cos5 = cos2 * cos2 * cos; Color spec = getSpecular(state); Color ret = Color.white(); ret.sub(spec); ret.mul(cos5); ret.add(spec); return lr.add(ret.mul(state.traceReflection(refRay, 0))); } else return lr.add(state.specularPhong(getSpecular(state), 2 / glossyness, numSamples)); }
public Color getRadiance(ShadingState state) { if (!state.includeLights) return Color.BLACK; state.faceforward(); // emit constant radiance return state.isBehind() ? Color.BLACK : radiance; }
public Color getRadiance(ShadingState state) { // make sure we are on the right side of the material state.faceforward(); // setup lighting state.initLightSamples(); state.initCausticSamples(); return(state.diffuse(getDiffuse(state))); }
public Color getRadiance(ShadingState state) { // make sure we are on the right side of the material state.faceforward(); // setup lighting state.initLightSamples(); state.initCausticSamples(); return state.diffuse(getDiffuse(state)); }
public Color GetRadiance(ShadingState state) { if (!state.includeSpecular) return Color.BLACK; Vector3 reflDir = new Vector3(); Vector3 refrDir = new Vector3(); state.faceforward(); float cos = state.getCosND(); bool inside = state.isBehind(); float neta = inside ? eta : 1.0f / eta; float dn = 2 * cos; reflDir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x; reflDir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y; reflDir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z; // refracted ray float arg = 1 - (neta * neta * (1 - (cos * cos))); bool tir = arg < 0; if (tir) refrDir.x = refrDir.y = refrDir.z = 0; else { float nK = (neta * cos) - (float)Math.Sqrt(arg); refrDir.x = (neta * state.getRay().dx) + (nK * state.getNormal().x); refrDir.y = (neta * state.getRay().dy) + (nK * state.getNormal().y); refrDir.z = (neta * state.getRay().dz) + (nK * state.getNormal().z); } // compute Fresnel terms float cosTheta1 = Vector3.dot(state.getNormal(), reflDir); float cosTheta2 = -Vector3.dot(state.getNormal(), refrDir); float pPara = (cosTheta1 - eta * cosTheta2) / (cosTheta1 + eta * cosTheta2); float pPerp = (eta * cosTheta1 - cosTheta2) / (eta * cosTheta1 + cosTheta2); float kr = 0.5f * (pPara * pPara + pPerp * pPerp); float kt = 1 - kr; Color absorption = null; if (inside && absorptionDistance > 0) { // this ray is inside the object and leaving it // compute attenuation that occured along the ray absorption = Color.mul(-state.getRay().getMax() / absorptionDistance, absorptionColor.copy().opposite()).exp(); if (absorption.isBlack()) return Color.BLACK; // nothing goes through } // refracted ray Color ret = Color.black(); if (!tir) { ret.madd(kt, state.traceRefraction(new Ray(state.getPoint(), refrDir), 0)).mul(color); } if (!inside || tir) ret.add(Color.mul(kr, state.traceReflection(new Ray(state.getPoint(), reflDir), 0)).mul(color)); return absorption != null ? ret.mul(absorption) : ret; }
public Color getRadiance(ShadingState state) { if (!state.includeLights) { return(Color.BLACK); } state.faceforward(); // emit constant radiance return(state.isBehind() ? Color.BLACK : radiance); }
public Color getRadiance(ShadingState state) { // make sure we are on the right side of the material state.faceforward(); // setup lighting state.initLightSamples(); state.initCausticSamples(); // execute shader return(state.diffuse(getDiffuse(state)).add(state.specularPhong(spec, power, numRays))); }
public Color getRadiance(ShadingState state) { state.faceforward(); state.initCausticSamples(); // integrate a diffuse function Color lr = Color.black(); foreach (LightSample sample in state) lr.madd(sample.dot(state.getNormal()), sample.getDiffuseRadiance()); return lr.mul(1.0f / (float)Math.PI); }
public Color getRadiance(ShadingState state) { // make sure we are on the right side of the material state.faceforward(); // setup lighting state.initLightSamples(); state.initCausticSamples(); // execute shader return state.diffuse(getDiffuse(state)).add(state.specularPhong(spec, power, numRays)); }
public void store(ShadingState state, Vector3 dir, Color power, Color diffuse) { state.faceforward(); PointLight vpl = new PointLight(); vpl.p = state.getPoint(); vpl.n = state.getNormal(); vpl.power = power; lock (lockObj) { virtualLights.Add(vpl); } }
public Color getRadiance(ShadingState state) { state.faceforward(); state.initCausticSamples(); // integrate a diffuse function Color lr = Color.black(); foreach (LightSample sample in state) { lr.madd(sample.dot(state.getNormal()), sample.getDiffuseRadiance()); } return(lr.mul(1.0f / (float)Math.PI)); }
public Color GetRadiance(ShadingState state) { if (state.getNormal() == null) { // if this shader has been applied to an infinite instance because of shader overrides // run the default shader, otherwise, just shade black return(state.getShader() != this ? state.getShader().GetRadiance(state) : Color.BLACK); } // make sure we are on the right side of the material state.faceforward(); // setup lighting state.initLightSamples(); state.initCausticSamples(); return(state.diffuse(Color.GRAY)); }
public Color GetRadiance(ShadingState state) { if (state.getNormal() == null) { // if this shader has been applied to an infinite instance because of shader overrides // run the default shader, otherwise, just shade black return state.getShader() != this ? state.getShader().GetRadiance(state) : Color.BLACK; } // make sure we are on the right side of the material state.faceforward(); // setup lighting state.initLightSamples(); state.initCausticSamples(); return state.diffuse(Color.GRAY); }
public void ScatterPhoton(ShadingState state, Color power) { float avg = color.getAverage(); double rnd = state.getRandom(0, 0, 1); if (rnd >= avg) return; state.faceforward(); float cos = state.getCosND(); power.mul(color).mul(1.0f / avg); // photon is reflected float dn = 2 * cos; Vector3 dir = new Vector3(); dir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x; dir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y; dir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z; state.traceReflectionPhoton(new Ray(state.getPoint(), dir), power); }
public Color GetRadiance(ShadingState state) { int side = state.getPrimitiveID(); Color kd = null; switch (side) { case 0: kd = left; break; case 1: kd = right; break; case 3: kd = back; break; case 4: kd = bottom; break; case 5: float lx = state.getPoint().x; float ly = state.getPoint().y; if (lx >= lxmin && lx < lxmax && ly >= lymin && ly < lymax && state.getRay().dz > 0) { return(state.includeLights ? radiance : Color.BLACK); } kd = top; break; default: Debug.Assert(false); break; } // make sure we are on the right side of the material state.faceforward(); // setup lighting state.initLightSamples(); state.initCausticSamples(); return(state.diffuse(kd)); }
public void scatterPhoton(ShadingState state, Color power) { // make sure we are on the right side of the material state.faceforward(); Color d = getDiffuse(state); state.storePhoton(state.getRay().getDirection(), power, d); float avgD = d.getAverage(); float avgS = spec.getAverage(); double rnd = state.getRandom(0, 0, 1); if (rnd < avgD) { // photon is scattered diffusely power.mul(d).mul(1.0f / avgD); OrthoNormalBasis onb = state.getBasis(); double u = 2 * Math.PI * rnd / avgD; double v = state.getRandom(0, 1, 1); float s = (float)Math.Sqrt(v); float s1 = (float)Math.Sqrt(1.0f - v); Vector3 w = new Vector3((float)Math.Cos(u) * s, (float)Math.Sin(u) * s, s1); w = onb.transform(w, new Vector3()); state.traceDiffusePhoton(new Ray(state.getPoint(), w), power); } else if (rnd < avgD + avgS) { // photon is scattered specularly float dn = 2.0f * state.getCosND(); // reflected direction Vector3 refDir = new Vector3(); refDir.x = (dn * state.getNormal().x) + state.getRay().dx; refDir.y = (dn * state.getNormal().y) + state.getRay().dy; refDir.z = (dn * state.getNormal().z) + state.getRay().dz; power.mul(spec).mul(1.0f / avgS); OrthoNormalBasis onb = state.getBasis(); double u = 2 * Math.PI * (rnd - avgD) / avgS; double v = state.getRandom(0, 1, 1); float s = (float)Math.Pow(v, 1 / (this.power + 1)); float s1 = (float)Math.Sqrt(1 - s * s); Vector3 w = new Vector3((float)Math.Cos(u) * s1, (float)Math.Sin(u) * s1, s); w = onb.transform(w, new Vector3()); state.traceReflectionPhoton(new Ray(state.getPoint(), w), power); } }
public Color GetRadiance(ShadingState state) { // make sure we are on the right side of the material state.faceforward(); // direct lighting state.initLightSamples(); state.initCausticSamples(); Color d = getDiffuse(state); Color lr = state.diffuse(d); if (!state.includeSpecular) { return(lr); } if (glossyness == 0) { float cos = state.getCosND(); float dn = 2 * cos; Vector3 refDir = new Vector3(); refDir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x; refDir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y; refDir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z; Ray refRay = new Ray(state.getPoint(), refDir); // compute Fresnel term cos = 1 - cos; float cos2 = cos * cos; float cos5 = cos2 * cos2 * cos; Color spec = getSpecular(state); Color ret = Color.white(); ret.sub(spec); ret.mul(cos5); ret.add(spec); return(lr.add(ret.mul(state.traceReflection(refRay, 0)))); } else { return(lr.add(state.specularPhong(getSpecular(state), 2 / glossyness, numSamples))); } }
public void scatterPhoton(ShadingState state, Color power) { float avg = color.getAverage(); double rnd = state.getRandom(0, 0, 1); if (rnd >= avg) { return; } state.faceforward(); float cos = state.getCosND(); power.mul(color).mul(1.0f / avg); // photon is reflected float dn = 2 * cos; Vector3 dir = new Vector3(); dir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x; dir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y; dir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z; state.traceReflectionPhoton(new Ray(state.getPoint(), dir), power); }
public void scatterPhoton(ShadingState state, Color power) { Color diffuse; // make sure we are on the right side of the material state.faceforward(); diffuse = getDiffuse(state); state.storePhoton(state.getRay().getDirection(), power, diffuse); float d = diffuse.getAverage(); float r = d * refl; double rnd = state.getRandom(0, 0, 1); if (rnd < d) { // photon is scattered power.mul(diffuse).mul(1.0f / d); OrthoNormalBasis onb = state.getBasis(); double u = 2 * Math.PI * rnd / d; double v = state.getRandom(0, 1, 1); float s = (float)Math.Sqrt(v); float s1 = (float)Math.Sqrt(1.0 - v); Vector3 w = new Vector3((float)Math.Cos(u) * s, (float)Math.Sin(u) * s, s1); w = onb.transform(w, new Vector3()); state.traceDiffusePhoton(new Ray(state.getPoint(), w), power); } else if (rnd < d + r) { float cos = -Vector3.dot(state.getNormal(), state.getRay().getDirection()); power.mul(diffuse).mul(1.0f / d); // photon is reflected float dn = 2 * cos; Vector3 dir = new Vector3(); dir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x; dir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y; dir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z; state.traceReflectionPhoton(new Ray(state.getPoint(), dir), power); } }
public Color GetRadiance(ShadingState state) { if (!state.includeSpecular) return Color.BLACK; state.faceforward(); float cos = state.getCosND(); float dn = 2 * cos; Vector3 refDir = new Vector3(); refDir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x; refDir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y; refDir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z; Ray refRay = new Ray(state.getPoint(), refDir); // compute Fresnel term cos = 1 - cos; float cos2 = cos * cos; float cos5 = cos2 * cos2 * cos; Color ret = Color.white(); ret.sub(color); ret.mul(cos5); ret.add(color); return ret.mul(state.traceReflection(refRay, 0)); }
public void ScatterPhoton(ShadingState state, Color power) { Color diffuse; // make sure we are on the right side of the material state.faceforward(); diffuse = getDiffuse(state); state.storePhoton(state.getRay().getDirection(), power, diffuse); float d = diffuse.getAverage(); float r = d * refl; double rnd = state.getRandom(0, 0, 1); if (rnd < d) { // photon is scattered power.mul(diffuse).mul(1.0f / d); OrthoNormalBasis onb = state.getBasis(); double u = 2 * Math.PI * rnd / d; double v = state.getRandom(0, 1, 1); float s = (float)Math.Sqrt(v); float s1 = (float)Math.Sqrt(1.0 - v); Vector3 w = new Vector3((float)Math.Cos(u) * s, (float)Math.Sin(u) * s, s1); w = onb.transform(w, new Vector3()); state.traceDiffusePhoton(new Ray(state.getPoint(), w), power); } else if (rnd < d + r) { float cos = -Vector3.dot(state.getNormal(), state.getRay().getDirection()); power.mul(diffuse).mul(1.0f / d); // photon is reflected float dn = 2 * cos; Vector3 dir = new Vector3(); dir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x; dir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y; dir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z; state.traceReflectionPhoton(new Ray(state.getPoint(), dir), power); } }
public Color getRadiance(ShadingState state) { state.faceforward(); return state.getGlobalRadiance(); }
public Color GetRadiance(ShadingState state) { state.faceforward(); return new Color().set(state.getIrradiance(Color.WHITE)).mul(1.0f / (float)Math.PI); }
public Color GetRadiance(ShadingState state) { state.faceforward(); return(new Color().set(state.getIrradiance(Color.WHITE)).mul(1.0f / (float)Math.PI)); }
public void ScatterPhoton(ShadingState state, Color power) { // make sure we are on the right side of the material state.faceforward(); Color d = getDiffuse(state); state.storePhoton(state.getRay().getDirection(), power, d); float avgD = d.getAverage(); float avgS = rhoS.getAverage(); double rnd = state.getRandom(0, 0, 1); if (rnd < avgD) { // photon is scattered diffusely power.mul(d).mul(1.0f / avgD); OrthoNormalBasis onb = state.getBasis(); double u = 2 * Math.PI * rnd / avgD; double v = state.getRandom(0, 1, 1); float s = (float)Math.Sqrt(v); float s1 = (float)Math.Sqrt(1.0f - v); Vector3 w = new Vector3((float)Math.Cos(u) * s, (float)Math.Sin(u) * s, s1); w = onb.transform(w, new Vector3()); state.traceDiffusePhoton(new Ray(state.getPoint(), w), power); } else if (rnd < avgD + avgS) { // photon is scattered specularly power.mul(rhoS).mul(1 / avgS); OrthoNormalBasis basis = state.getBasis(); Vector3 inv = state.getRay().getDirection().negate(new Vector3()); double r1 = rnd / avgS; double r2 = state.getRandom(0, 1, 1); float alphaRatio = alphaY / alphaX; float phi = 0; if (r1 < 0.25) { double val = 4 * r1; phi = (float)Math.Atan(alphaRatio * Math.Tan(Math.PI / 2 * val)); } else if (r1 < 0.5) { double val = 1 - 4 * (0.5 - r1); phi = (float)Math.Atan(alphaRatio * Math.Tan(Math.PI / 2 * val)); phi = (float)Math.PI - phi; } else if (r1 < 0.75) { double val = 4 * (r1 - 0.5); phi = (float)Math.Atan(alphaRatio * Math.Tan(Math.PI / 2 * val)); phi += (float)Math.PI; } else { double val = 1 - 4 * (1 - r1); phi = (float)Math.Atan(alphaRatio * Math.Tan(Math.PI / 2 * val)); phi = 2 * (float)Math.PI - phi; } float cosPhi = (float)Math.Cos(phi); float sinPhi = (float)Math.Sin(phi); float denom = (cosPhi * cosPhi) / (alphaX * alphaX) + (sinPhi * sinPhi) / (alphaY * alphaY); float theta = (float)Math.Atan(Math.Sqrt(-Math.Log(1 - r2) / denom)); float sinTheta = (float)Math.Sin(theta); float cosTheta = (float)Math.Cos(theta); Vector3 h = new Vector3(); h.x = sinTheta * cosPhi; h.y = sinTheta * sinPhi; h.z = cosTheta; basis.transform(h); Vector3 o = new Vector3(); float ih = Vector3.dot(h, inv); o.x = 2 * ih * h.x - inv.x; o.y = 2 * ih * h.y - inv.y; o.z = 2 * ih * h.z - inv.z; Ray r = new Ray(state.getPoint(), o); state.traceReflectionPhoton(r, power); } }
public void ScatterPhoton(ShadingState state, Color power) { Color diffuse, specular; // make sure we are on the right side of the material state.faceforward(); diffuse = getDiffuse(state); specular = getSpecular(state); state.storePhoton(state.getRay().getDirection(), power, diffuse); float d = diffuse.getAverage(); float r = specular.getAverage(); double rnd = state.getRandom(0, 0, 1); if (rnd < d) { // photon is scattered power.mul(diffuse).mul(1.0f / d); OrthoNormalBasis onb = state.getBasis(); double u = 2 * Math.PI * rnd / d; double v = state.getRandom(0, 1, 1); float s = (float)Math.Sqrt(v); float s1 = (float)Math.Sqrt(1.0 - v); Vector3 w = new Vector3((float)Math.Cos(u) * s, (float)Math.Sin(u) * s, s1); w = onb.transform(w, new Vector3()); state.traceDiffusePhoton(new Ray(state.getPoint(), w), power); } else if (rnd < d + r) { if (glossyness == 0) { float cos = -Vector3.dot(state.getNormal(), state.getRay().getDirection()); power.mul(diffuse).mul(1.0f / d); // photon is reflected float dn = 2 * cos; Vector3 dir = new Vector3(); dir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x; dir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y; dir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z; state.traceReflectionPhoton(new Ray(state.getPoint(), dir), power); } else { float dn = 2.0f * state.getCosND(); // reflected direction Vector3 refDir = new Vector3(); refDir.x = (dn * state.getNormal().x) + state.getRay().dx; refDir.y = (dn * state.getNormal().y) + state.getRay().dy; refDir.z = (dn * state.getNormal().z) + state.getRay().dz; power.mul(spec).mul(1.0f / r); OrthoNormalBasis onb = state.getBasis(); double u = 2 * Math.PI * (rnd - r) / r; double v = state.getRandom(0, 1, 1); float s = (float)Math.Pow(v, 1 / ((1.0f / glossyness) + 1)); float s1 = (float)Math.Sqrt(1 - s * s); Vector3 w = new Vector3((float)Math.Cos(u) * s1, (float)Math.Sin(u) * s1, s); w = onb.transform(w, new Vector3()); state.traceReflectionPhoton(new Ray(state.getPoint(), w), power); } } }
public Color GetRadiance(ShadingState state) { int side = state.getPrimitiveID(); Color kd = null; switch (side) { case 0: kd = left; break; case 1: kd = right; break; case 3: kd = back; break; case 4: kd = bottom; break; case 5: float lx = state.getPoint().x; float ly = state.getPoint().y; if (lx >= lxmin && lx < lxmax && ly >= lymin && ly < lymax && state.getRay().dz > 0) return state.includeLights ? radiance : Color.BLACK; kd = top; break; default: Debug.Assert(false); break; } // make sure we are on the right side of the material state.faceforward(); // setup lighting state.initLightSamples(); state.initCausticSamples(); return state.diffuse(kd); }
public void ScatterPhoton(ShadingState state, Color power) { Color refr = Color.mul(1 - f0, color); Color refl = Color.mul(f0, color); float avgR = refl.getAverage(); float avgT = refr.getAverage(); double rnd = state.getRandom(0, 0, 1); if (rnd < avgR) { state.faceforward(); // don't reflect internally if (state.isBehind()) return; // photon is reflected float cos = state.getCosND(); power.mul(refl).mul(1.0f / avgR); float dn = 2 * cos; Vector3 dir = new Vector3(); dir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x; dir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y; dir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z; state.traceReflectionPhoton(new Ray(state.getPoint(), dir), power); } else if (rnd < avgR + avgT) { state.faceforward(); // photon is refracted float cos = state.getCosND(); float neta = state.isBehind() ? eta : 1.0f / eta; power.mul(refr).mul(1.0f / avgT); float wK = -neta; float arg = 1 - (neta * neta * (1 - (cos * cos))); Vector3 dir = new Vector3(); if (state.isBehind() && absorptionDistance > 0) { // this ray is inside the object and leaving it // compute attenuation that occured along the ray power.mul(Color.mul(-state.getRay().getMax() / absorptionDistance, absorptionColor.copy().opposite()).exp()); } if (arg < 0) { // TIR float dn = 2 * cos; dir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x; dir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y; dir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z; state.traceReflectionPhoton(new Ray(state.getPoint(), dir), power); } else { float nK = (neta * cos) - (float)Math.Sqrt(arg); dir.x = (-wK * state.getRay().dx) + (nK * state.getNormal().x); dir.y = (-wK * state.getRay().dy) + (nK * state.getNormal().y); dir.z = (-wK * state.getRay().dz) + (nK * state.getNormal().z); state.traceRefractionPhoton(new Ray(state.getPoint(), dir), power); } } }
public Color getRadiance(ShadingState state) { // make sure we are on the right side of the material state.faceforward(); OrthoNormalBasis onb = state.getBasis(); // direct lighting and caustics state.initLightSamples(); state.initCausticSamples(); Color lr = Color.black(); // compute specular contribution if (state.includeSpecular) { Vector3 inv = state.getRay().getDirection().negate(new Vector3()); foreach (LightSample sample in state) { float cosNL = sample.dot(state.getNormal()); float fr = brdf(inv, sample.getShadowRay().getDirection(), onb); lr.madd(cosNL * fr, sample.getSpecularRadiance()); } // indirect lighting - specular if (numRays > 0) { int n = state.getDepth() == 0 ? numRays : 1; for (int i = 0; i < n; i++) { // specular indirect lighting double r1 = state.getRandom(i, 0, n); double r2 = state.getRandom(i, 1, n); float alphaRatio = alphaY / alphaX; float phi = 0; if (r1 < 0.25) { double val = 4 * r1; phi = (float)Math.Atan(alphaRatio * Math.Tan(Math.PI / 2 * val)); } else if (r1 < 0.5) { double val = 1 - 4 * (0.5 - r1); phi = (float)Math.Atan(alphaRatio * Math.Tan(Math.PI / 2 * val)); phi = (float)Math.PI - phi; } else if (r1 < 0.75) { double val = 4 * (r1 - 0.5); phi = (float)Math.Atan(alphaRatio * Math.Tan(Math.PI / 2 * val)); phi += (float)Math.PI; } else { double val = 1 - 4 * (1 - r1); phi = (float)Math.Atan(alphaRatio * Math.Tan(Math.PI / 2 * val)); phi = 2 * (float)Math.PI - phi; } float cosPhi = (float)Math.Cos(phi); float sinPhi = (float)Math.Sin(phi); float denom = (cosPhi * cosPhi) / (alphaX * alphaX) + (sinPhi * sinPhi) / (alphaY * alphaY); float theta = (float)Math.Atan(Math.Sqrt(-Math.Log(1 - r2) / denom)); float sinTheta = (float)Math.Sin(theta); float cosTheta = (float)Math.Cos(theta); Vector3 h = new Vector3(); h.x = sinTheta * cosPhi; h.y = sinTheta * sinPhi; h.z = cosTheta; onb.transform(h); Vector3 o = new Vector3(); float ih = Vector3.dot(h, inv); o.x = 2 * ih * h.x - inv.x; o.y = 2 * ih * h.y - inv.y; o.z = 2 * ih * h.z - inv.z; float no = onb.untransformZ(o); float ni = onb.untransformZ(inv); float w = ih * cosTheta * cosTheta * cosTheta * (float)Math.Sqrt(Math.Abs(no / ni)); Ray r = new Ray(state.getPoint(), o); lr.madd(w / n, state.traceGlossy(r, i)); } } lr.mul(rhoS); } // add diffuse contribution lr.add(state.diffuse(getDiffuse(state))); return lr; }
public void scatterPhoton(ShadingState state, Color power) { // make sure we are on the right side of the material state.faceforward(); Color d = getDiffuse(state); state.storePhoton(state.getRay().getDirection(), power, d); float avgD = d.getAverage(); float avgS = rhoS.getAverage(); double rnd = state.getRandom(0, 0, 1); if (rnd < avgD) { // photon is scattered diffusely power.mul(d).mul(1.0f / avgD); OrthoNormalBasis onb = state.getBasis(); double u = 2 * Math.PI * rnd / avgD; double v = state.getRandom(0, 1, 1); float s = (float)Math.Sqrt(v); float s1 = (float)Math.Sqrt(1.0f - v); Vector3 w = new Vector3((float)Math.Cos(u) * s, (float)Math.Sin(u) * s, s1); w = onb.transform(w, new Vector3()); state.traceDiffusePhoton(new Ray(state.getPoint(), w), power); } else if (rnd < avgD + avgS) { // photon is scattered specularly power.mul(rhoS).mul(1 / avgS); OrthoNormalBasis basis = state.getBasis(); Vector3 inv = state.getRay().getDirection().negate(new Vector3()); double r1 = rnd / avgS; double r2 = state.getRandom(0, 1, 1); float alphaRatio = alphaY / alphaX; float phi = 0; if (r1 < 0.25) { double val = 4 * r1; phi = (float)Math.Atan(alphaRatio * Math.Tan(Math.PI / 2 * val)); } else if (r1 < 0.5) { double val = 1 - 4 * (0.5 - r1); phi = (float)Math.Atan(alphaRatio * Math.Tan(Math.PI / 2 * val)); phi = (float)Math.PI - phi; } else if (r1 < 0.75) { double val = 4 * (r1 - 0.5); phi = (float)Math.Atan(alphaRatio * Math.Tan(Math.PI / 2 * val)); phi += (float)Math.PI; } else { double val = 1 - 4 * (1 - r1); phi = (float)Math.Atan(alphaRatio * Math.Tan(Math.PI / 2 * val)); phi = 2 * (float)Math.PI - phi; } float cosPhi = (float)Math.Cos(phi); float sinPhi = (float)Math.Sin(phi); float denom = (cosPhi * cosPhi) / (alphaX * alphaX) + (sinPhi * sinPhi) / (alphaY * alphaY); float theta = (float)Math.Atan(Math.Sqrt(-Math.Log(1 - r2) / denom)); float sinTheta = (float)Math.Sin(theta); float cosTheta = (float)Math.Cos(theta); Vector3 h = new Vector3(); h.x = sinTheta * cosPhi; h.y = sinTheta * sinPhi; h.z = cosTheta; basis.transform(h); Vector3 o = new Vector3(); float ih = Vector3.dot(h, inv); o.x = 2 * ih * h.x - inv.x; o.y = 2 * ih * h.y - inv.y; o.z = 2 * ih * h.z - inv.z; Ray r = new Ray(state.getPoint(), o); state.traceReflectionPhoton(r, power); } }
public void ScatterPhoton(ShadingState state, Color power) { Color refr = Color.mul(1 - f0, color); Color refl = Color.mul(f0, color); float avgR = refl.getAverage(); float avgT = refr.getAverage(); double rnd = state.getRandom(0, 0, 1); if (rnd < avgR) { state.faceforward(); // don't reflect internally if (state.isBehind()) { return; } // photon is reflected float cos = state.getCosND(); power.mul(refl).mul(1.0f / avgR); float dn = 2 * cos; Vector3 dir = new Vector3(); dir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x; dir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y; dir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z; state.traceReflectionPhoton(new Ray(state.getPoint(), dir), power); } else if (rnd < avgR + avgT) { state.faceforward(); // photon is refracted float cos = state.getCosND(); float neta = state.isBehind() ? eta : 1.0f / eta; power.mul(refr).mul(1.0f / avgT); float wK = -neta; float arg = 1 - (neta * neta * (1 - (cos * cos))); Vector3 dir = new Vector3(); if (state.isBehind() && absorptionDistance > 0) { // this ray is inside the object and leaving it // compute attenuation that occured along the ray power.mul(Color.mul(-state.getRay().getMax() / absorptionDistance, absorptionColor.copy().opposite()).exp()); } if (arg < 0) { // TIR float dn = 2 * cos; dir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x; dir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y; dir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z; state.traceReflectionPhoton(new Ray(state.getPoint(), dir), power); } else { float nK = (neta * cos) - (float)Math.Sqrt(arg); dir.x = (-wK * state.getRay().dx) + (nK * state.getNormal().x); dir.y = (-wK * state.getRay().dy) + (nK * state.getNormal().y); dir.z = (-wK * state.getRay().dz) + (nK * state.getNormal().z); state.traceRefractionPhoton(new Ray(state.getPoint(), dir), power); } } }
public Color GetRadiance(ShadingState state) { if (!state.includeSpecular) { return(Color.BLACK); } Vector3 reflDir = new Vector3(); Vector3 refrDir = new Vector3(); state.faceforward(); float cos = state.getCosND(); bool inside = state.isBehind(); float neta = inside ? eta : 1.0f / eta; float dn = 2 * cos; reflDir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x; reflDir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y; reflDir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z; // refracted ray float arg = 1 - (neta * neta * (1 - (cos * cos))); bool tir = arg < 0; if (tir) { refrDir.x = refrDir.y = refrDir.z = 0; } else { float nK = (neta * cos) - (float)Math.Sqrt(arg); refrDir.x = (neta * state.getRay().dx) + (nK * state.getNormal().x); refrDir.y = (neta * state.getRay().dy) + (nK * state.getNormal().y); refrDir.z = (neta * state.getRay().dz) + (nK * state.getNormal().z); } // compute Fresnel terms float cosTheta1 = Vector3.dot(state.getNormal(), reflDir); float cosTheta2 = -Vector3.dot(state.getNormal(), refrDir); float pPara = (cosTheta1 - eta * cosTheta2) / (cosTheta1 + eta * cosTheta2); float pPerp = (eta * cosTheta1 - cosTheta2) / (eta * cosTheta1 + cosTheta2); float kr = 0.5f * (pPara * pPara + pPerp * pPerp); float kt = 1 - kr; Color absorption = null; if (inside && absorptionDistance > 0) { // this ray is inside the object and leaving it // compute attenuation that occured along the ray absorption = Color.mul(-state.getRay().getMax() / absorptionDistance, absorptionColor.copy().opposite()).exp(); if (absorption.isBlack()) { return(Color.BLACK); // nothing goes through } } // refracted ray Color ret = Color.black(); if (!tir) { ret.madd(kt, state.traceRefraction(new Ray(state.getPoint(), refrDir), 0)).mul(color); } if (!inside || tir) { ret.add(Color.mul(kr, state.traceReflection(new Ray(state.getPoint(), reflDir), 0)).mul(color)); } return(absorption != null?ret.mul(absorption) : ret); }
public Color GetRadiance(ShadingState state) { // make sure we are on the right side of the material state.faceforward(); OrthoNormalBasis onb = state.getBasis(); // direct lighting and caustics state.initLightSamples(); state.initCausticSamples(); Color lr = Color.black(); // compute specular contribution if (state.includeSpecular) { Vector3 inv = state.getRay().getDirection().negate(new Vector3()); foreach (LightSample sample in state) { float cosNL = sample.dot(state.getNormal()); float fr = brdf(inv, sample.getShadowRay().getDirection(), onb); lr.madd(cosNL * fr, sample.getSpecularRadiance()); } // indirect lighting - specular if (numRays > 0) { int n = state.getDepth() == 0 ? numRays : 1; for (int i = 0; i < n; i++) { // specular indirect lighting double r1 = state.getRandom(i, 0, n); double r2 = state.getRandom(i, 1, n); float alphaRatio = alphaY / alphaX; float phi = 0; if (r1 < 0.25) { double val = 4 * r1; phi = (float)Math.Atan(alphaRatio * Math.Tan(Math.PI / 2 * val)); } else if (r1 < 0.5) { double val = 1 - 4 * (0.5 - r1); phi = (float)Math.Atan(alphaRatio * Math.Tan(Math.PI / 2 * val)); phi = (float)Math.PI - phi; } else if (r1 < 0.75) { double val = 4 * (r1 - 0.5); phi = (float)Math.Atan(alphaRatio * Math.Tan(Math.PI / 2 * val)); phi += (float)Math.PI; } else { double val = 1 - 4 * (1 - r1); phi = (float)Math.Atan(alphaRatio * Math.Tan(Math.PI / 2 * val)); phi = 2 * (float)Math.PI - phi; } float cosPhi = (float)Math.Cos(phi); float sinPhi = (float)Math.Sin(phi); float denom = (cosPhi * cosPhi) / (alphaX * alphaX) + (sinPhi * sinPhi) / (alphaY * alphaY); float theta = (float)Math.Atan(Math.Sqrt(-Math.Log(1 - r2) / denom)); float sinTheta = (float)Math.Sin(theta); float cosTheta = (float)Math.Cos(theta); Vector3 h = new Vector3(); h.x = sinTheta * cosPhi; h.y = sinTheta * sinPhi; h.z = cosTheta; onb.transform(h); Vector3 o = new Vector3(); float ih = Vector3.dot(h, inv); o.x = 2 * ih * h.x - inv.x; o.y = 2 * ih * h.y - inv.y; o.z = 2 * ih * h.z - inv.z; float no = onb.untransformZ(o); float ni = onb.untransformZ(inv); float w = ih * cosTheta * cosTheta * cosTheta * (float)Math.Sqrt(Math.Abs(no / ni)); Ray r = new Ray(state.getPoint(), o); lr.madd(w / n, state.traceGlossy(r, i)); } } lr.mul(rhoS); } // add diffuse contribution lr.add(state.diffuse(getDiffuse(state))); return(lr); }
public Color getRadiance(ShadingState state) { state.faceforward(); return(state.getGlobalRadiance()); }