static Vector3 TrowbridgeReitzSample(Vector3 wi, float alpha_x, float alpha_y, float U1, float U2) { // 1. stretch wi Vector3 wiStretched = Vector3.Normalize(new Vector3(alpha_x * wi.X, alpha_y * wi.Y, wi.Z)); // 2. simulate P22_{wi}(x_slope, y_slope, 1, 1) float slope_x, slope_y; TrowbridgeReitzSample11(ShadingSpace.CosTheta(wiStretched), U1, U2, out slope_x, out slope_y); // 3. rotate float tmp = ShadingSpace.CosPhi(wiStretched) * slope_x - ShadingSpace.SinPhi(wiStretched) * slope_y; slope_y = ShadingSpace.SinPhi(wiStretched) * slope_x + ShadingSpace.CosPhi(wiStretched) * slope_y; slope_x = tmp; // 4. unstretch slope_x = alpha_x * slope_x; slope_y = alpha_y * slope_y; // 5. compute normal return(Vector3.Normalize(new Vector3(-slope_x, -slope_y, 1))); }