double ksY = ColorUtil.getMeanChannelValue(ks);
double rhos = Math.min(1.0, ksY * Math.abs(vdotn) * (n + 2.0) / (n + 1.0));
if (rj < rhod) {
Vector3 out = RandomUtil.diffuse(ru, rv).toCartesian(x.getBasis());
Ray3 ray = new Ray3(x.getPosition(), out);
return ScatteredRay.diffuse(ray, kd.divide(rhod), getScatteringPDF(x, v, out, adjoint, lambda));
} else if (rj < rhod + rhos) {
Vector3 r = Optics.reflect(v, x.getNormal());
Vector3 out = new SphericalCoordinates(Math.acos(Math.pow(ru, 1.0 / (n + 1.0))), 2.0 * Math.PI * rv).toCartesian(Basis3.fromW(r));
double ndoto = x.getNormal().dot(out);
Color weight = ks.times(((n + 2.0) / (n + 1.0)) * Math.abs(ndoto) / rhos);
//double rdoto = r.dot(out);
double pdf = getScatteringPDF(x, v, out, adjoint, lambda);//rhod / Math.PI + rhos * (Math.pow(rdoto, n) / ndoto) * (n + 1.0) / (2.0 * Math.PI);
Ray3 ray = new Ray3(x.getPosition(), out);
return ScatteredRay.glossy(ray, weight, pdf);
}
return null;
}