Пример #1
0
vec3f Renderer::sample(Scene& scene, Ray ray, int num_bounces)
{
    vec3f accum_radiance(0.0, 0.0, 0.0);
    vec3f rem_radiance(1.0, 1.0, 1.0);

    for (int b=0; b < num_bounces; b++) {
        TriangleHit hit_data = scene.m_tree->hit(ray);
        Triangle* tri = hit_data.tri;
        float dist = hit_data.dist;

        if (tri == nullptr) {
            return vec3f(0.0, 0.0, 0.0);
        }

        tinyobj::mesh_t mesh = tri->shape_data->mesh;
        Material mat = scene.m_mats[mesh.material_ids[tri->index / 3]];

        // Material properties
        vec3f emittance = to_vec3f(mat.emission);
        vec3f diffuse = to_vec3f(mat.diffuse);
        // vec3f specular = to_vec3f(mat.specular);
        vec3f &norm = tri->norm;

        // Calculate BRDF
        vec3f brdf = 2 * diffuse;

        // Reflect in a random direction on the normal's unit hemisphere.
        ray.pos = ray.pos + dist * ray.dir;
        // ray.dir = rand_hemisphere_vec(norm);
        ray.dir = cos_dist_hemisphere_vec(norm);

        // Add accumulation of outgoing radiance.
        accum_radiance += rem_radiance.cwiseProduct(emittance);
        rem_radiance = rem_radiance.cwiseProduct(brdf);

        // For specular, reflect perfectly.
        // Ray spec_reflect_ray;
        // vec3f spec_reflected_amt;
        // spec_reflect_ray.pos = reflect_ray.pos;
        // spec_reflect_ray.dir = ray.dir + (2 * cos_theta * norm);
        // spec_reflected_amt = sample(scene, spec_reflect_ray, bounce + 1,
        //         max_bounces);
    }

    return accum_radiance;
}
Пример #2
0
int main()
{
 int exit = 0, i, vnum, pnum;
 VEC3F pos = vec3f(0.0, 0.0, 0.3), ang = ZERO_VEC3F;
 MAT16F tmat;
 VERTEX *vertex;
 POLY3D *poly;

 init();

 load_map("quake_map2.txt", &vertex, &poly, &vnum, &pnum, 0.2);

 LOCK_VARIABLE(fps);
 LOCK_VARIABLE(frame_count);
 LOCK_FUNCTION(update_fps);
 install_int(update_fps, 1000);

 VEC3F cam_pos = vec3f(0.0, 3.0, 0.0), cam_dir, cam_dir_normal, cam_ang = vec3f(0.0, 0.0, 0.0);

 while(!exit)
  {
   int mx, my;
   get_mouse_mickeys(&mx, &my);
   position_mouse(SCREEN_W / 2, SCREEN_H / 2);

   cam_ang.x += my * 0.001;
   cam_ang.y -= mx * 0.001;
   cam_dir.x = CAM_SPEED * cos(0.5 * M_PI + cam_ang.y);
   cam_dir.y = CAM_SPEED * cos(0.5 * M_PI + cam_ang.x);
   cam_dir.z = CAM_SPEED * sin(0.5 * M_PI + cam_ang.y);
   cam_dir_normal = vec3f(-cam_dir.z, 0.0, cam_dir.x);

   if(key[KEY_ESC]) { exit = 1; }
   if(key[KEY_W]) { cam_pos = VEC3F_SUM(cam_pos, cam_dir); }
   if(key[KEY_S]) { cam_pos = VEC3F_DIFF(cam_pos, cam_dir); }
   if(key[KEY_A]) { cam_pos = VEC3F_SUM(cam_pos, cam_dir_normal); }
   if(key[KEY_D]) { cam_pos = VEC3F_DIFF(cam_pos, cam_dir_normal); }

   set_fov(90.0);
   if(mouse_b > 1)
    set_fov(30.0);

   reset_mat16f(tmat);
   translate_mat16f(tmat, -cam_pos.x, -cam_pos.y, -cam_pos.z);
   rotate_z_mat16f(tmat, 0.0);
   rotate_y_mat16f(tmat, -cam_ang.y);
   rotate_x_mat16f(tmat, -cam_ang.x);

   for(i = 0; i < vnum; i++)
    {
     transform_vec3f(&vertex[i].trans, vertex[i].object, tmat);
     project_vertex(&vertex[i]);
    }

   clear_to_color(buffer, 0);
   clear_to_color(BASE_INT_z_buffer, BASE_INT_z_buffer_precision);

   for(i = 0; i < pnum; i++)
    {
     update_poly3d_normal(&poly[i], vertex);
     V0 = vertex[poly[i].vind[0]].trans;
     global_n = USCALE_VEC3F(NORMALIZED_VEC3F(poly[i].normal), -1.0);
     VEC3F N = global_n;
     DIST = -VEC3F_DOT_PRODUCT(V0, N);

     get_axes(vertex[poly[i].vind[0]].trans,
              vertex[poly[i].vind[1]].trans,
              vertex[poly[i].vind[2]].trans,
              to_vec3f(poly[i].texcoord[0]),
              to_vec3f(poly[i].texcoord[1]),
              to_vec3f(poly[i].texcoord[2]), &A, &B, &C);
     T0 = to_vec3f(poly[i].texcoord[0]);

     if(cull_backface(&poly[i], vertex))
     render_poly3d(&poly[i], vertex);
    }

   textprintf_ex(buffer, font, 10, 10, makecol(255, 255, 255), 0, "FPS: %d", fps);
   blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
   frame_count++;
  }

 for(i = 0; i < pnum; i++)
  destroy_poly3d(&poly[i]);
 free(vertex);

 deinit_engine();
 return 0;
}