public Color bsdf(SurfacePoint x, Vector3 in, Vector3 out,
WavelengthPacket lambda) {
Vector3 p = out.unit().minus(in.unit()).unit();
Basis3 basis = x.getShadingBasis();
SphericalCoordinates omegaO = SphericalCoordinates.fromCartesian(out, basis).canonical();
SphericalCoordinates omegaP = SphericalCoordinates.fromCartesian(p, basis).canonical();
double NdotI = -basis.w().dot(in);
double NdotO = basis.w().dot(out);
double spf = 0.0;
if (NdotI * NdotO < 0.0) {
return lambda.getColorModel().getBlack(lambda);
}
double phiO = omegaO.azimuthal() < 0.0 ? omegaO.azimuthal() + 2.0 * Math.PI : omegaO.azimuthal();
double phiP = omegaP.azimuthal() < 0.0 ? omegaP.azimuthal() + 2.0 * Math.PI : omegaP.azimuthal();
phiP -= phiO;
if (phiP < 0.0) { phiP += 2.0 * Math.PI; }
int J = F.length;
for (int j = 0; j < J; j++) {
double Fj = MathUtil.bilinearInterpolate(
0, 0.5 * Math.PI, 0.0, 2.0 * Math.PI, F[j],
omegaO.polar(), phiO, false, true);
// double t = (double) (F[j].rows() - 1) * omegaO.polar() / (0.5 * Math.PI);
// if (Math.abs(t - Math.round(t)) < 0.05) {
// Fj = 0;
// }
// double Gj = 0.0;
//
// int K = u[j].length;
// for (int k = 0; k < K; k++) {
// double ujk = MathUtil.interpolate(0, 0.5 * Math.PI, u[j][k].elements(), omegaP.polar());
// double vjk = MathUtil.interpolate(0, 2.0 * Math.PI, v[j][k].elements(), phiP);
//
// Gj += ujk * vjk;
// }
double Gj = MathUtil.bilinearInterpolate(
0, 0.5 * Math.PI, 0.0, 2.0 * Math.PI, G[j],
omegaP.polar(), phiP, false, true);
spf += Fj * Gj;
}
double intensity = spf / NdotI;
double Fr = MathUtil.bilinearInterpolate(
0, 0.5 * Math.PI, 0.0, 2.0 * Math.PI, Fc[0],
omegaO.polar(), phiO);
double Fg = MathUtil.bilinearInterpolate(
0, 0.5 * Math.PI, 0.0, 2.0 * Math.PI, Fc[1],
omegaO.polar(), phiO);
double Fb = MathUtil.bilinearInterpolate(
0, 0.5 * Math.PI, 0.0, 2.0 * Math.PI, Fc[2],
omegaO.polar(), phiO);
double Gr = MathUtil.bilinearInterpolate(
0, 0.5 * Math.PI, 0.0, 2.0 * Math.PI, Gc[0],
omegaP.polar(), phiP);
double Gg = MathUtil.bilinearInterpolate(
0, 0.5 * Math.PI, 0.0, 2.0 * Math.PI, Gc[1],
omegaP.polar(), phiP);
double Gb = MathUtil.bilinearInterpolate(
0, 0.5 * Math.PI, 0.0, 2.0 * Math.PI, Gc[2],
omegaP.polar(), phiP);
double r = Fr * Gr * intensity;
double g = Fg * Gg * intensity;
double b = Fb * Gb * intensity;
// double r = intensity;