Example #1
0
void
ClosurePrimitive::sample_cos_hemisphere (const Vec3 &N, const Vec3 &omega_out,
                                         float randu, float randv,
                                         Vec3 &omega_in, float &pdf)
{
    // Default closure BSDF implementation: uniformly sample
    // cosine-weighted hemisphere above the point.
    to_unit_disk (randu, randv);
    float costheta = sqrtf (std::max(1 - randu * randu - randv * randv, 0.0f));
    Vec3 T, B;
    make_orthonormals (N, T, B);
    omega_in = randu * T + randv * B + costheta * N;
    pdf = costheta * (float) M_1_PI;
}
Example #2
0
void 
ClosurePrimitive::sample_uniform_hemisphere (const Vec3 &N, const Vec3 &omega_out,
                                             float randu, float randv, 
                                             Vec3 &omega_in, float &pdf)
{
    float z = randu;
    float r = sqrtf(std::max(0.f, 1.f - z*z));
    float phi = 2.f * M_PI * randv;
    float x = r * cosf(phi);
    float y = r * sinf(phi);
    
    Vec3 T, B;
    make_orthonormals (N, T, B);
    omega_in = x * T + y * B + z * N;
    pdf = 0.5f * (float) M_1_PI;
    
}
// set up the filter matrix
static void
gabor_setup_filter (const Dual2<Vec3> &P, GaborParams &gp)
{
    // Make texture-space normal, tangent, bitangent
    Vec3 n, t, b;
    n = P.dx().cross (P.dy());  // normal to P
    if (n.dot(n) < 1.0e-6f) {  /* length of deriv < 1/1000 */
        // No way to do filter if we have no derivs, and no reason to
        // do it if it's too small to have any effect.
        gp.do_filter = false;
        return;   // we won't need anything else if filtering is off
    }
    make_orthonormals (n, t, b);

    // Rotations from tangent<->texture space
    Matrix33 Mtex_to_tan = make_matrix33_cols (t, b, n);  // M3_local
    Matrix33 Mscreen_to_tex = make_matrix33_cols (P.dx(), P.dy(), Vec3(0.0f,0.0f,0.0f));
    Matrix33 Mscreen_to_tan = Mscreen_to_tex * Mtex_to_tan;  // M3_scr_tan
    Matrix22 M_scr_tan (Mscreen_to_tan[0][0], Mscreen_to_tan[0][1],
                        Mscreen_to_tan[1][0], Mscreen_to_tan[1][1]);
    float sigma_f_scr = 0.5f;
    Matrix22 Sigma_f_scr (sigma_f_scr * sigma_f_scr, 0.0f,
                          0.0f, sigma_f_scr * sigma_f_scr);
    Matrix22 M_scr_tan_t = M_scr_tan.transposed();
    Matrix22 Sigma_f_tan = M_scr_tan_t * Sigma_f_scr * M_scr_tan;

    gp.N = n;
    gp.filter = Sigma_f_tan;
    gp.det_filter = determinant(Sigma_f_tan);
    gp.local  = Mtex_to_tan;
    if (gp.det_filter < 1.0e-18f) {
        gp.do_filter = false;
        // Turn off filtering when tiny values will lead to numerical
        // errors later if we filter.  Yes, it's kind of arbitrary.
    }
}