private float brdf(Vector3 i, Vector3 o, OrthoNormalBasis basis) { float fr = 4 * (float)Math.PI * alphaX * alphaY; float p = basis.untransformZ(i) * basis.untransformZ(o); if (p > 0) { fr *= (float)Math.Sqrt(p); } else { fr = 0; } Vector3 h = Vector3.add(i, o, new Vector3()); basis.untransform(h); float hx = h.x / alphaX; hx *= hx; float hy = h.y / alphaY; hy *= hy; float hn = h.z * h.z; if (fr > 0) { fr = (float)Math.Exp(-(hx + hy) / hn) / fr; } return(fr); }
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; int w = 32, h = 32; imageHistogram = new float[w][]; for (int i = 0; i < imageHistogram.Length; i++) { imageHistogram[i] = new float[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); }
public Color GetRadiance(ShadingState state) { // lookup texture based on ray direction return(state.includeLights ? getColor(basis.untransform(state.getRay().getDirection(), new Vector3())) : Color.BLACK); }