2010-03-28 28 views
6

Tôi đã triển khai Sơ đồ chiếu sáng bằng cách sử dụng máy ảnh ở giữa (0,0,0) và nhìn thẳng vào hình cầu nguyên thủy. Sau đây là các nội dung có liên quan của các tập tin cảnh được sử dụng để xem các cảnh sử dụng OpenGL cũng như để làm cho cảnh sử dụng thực hiện của riêng tôi:OpenGL render so với thực hiện Chiếu sáng Phong riêng

ambient 0 1 0 

dir_light 1 1 1  -3 -4 -5 

# A red sphere with 0.5 green ambiance, centered at (0,0,0) with radius 1 
material 0 0.5 0 1 0 0 1 0 0 0 0 0 0 0 0 10 1 0 
sphere 0 0 0 0 1 

Here

Hình ảnh thu được sản xuất bởi OpenGL.

Here

Hình ảnh mà ứng dụng hiển thị của tôi tạo ra.

Như bạn có thể thấy, có sự khác biệt nhiều giữa hai:

  1. Điểm nổi bật gương về hình ảnh của tôi là nhỏ hơn so với một trong OpenGL.
  2. Bề mặt khuếch tán dường như không khuếch tán trong cách chính xác, kết quả là khu vực màu vàng là unneccessarily lớn trong hình ảnh của tôi, trong khi ở OpenGL có một khu vực màu xanh đậm đẹp gần gũi hơn với đáy của hình cầu
  3. Màu sản xuất bởi OpenGL tối hơn nhiều so với hình ảnh của tôi.

Đó là ba sự khác biệt nổi bật nhất mà tôi thấy. Sau đây là thực hiện của tôi về sự chiếu sáng Phong:

R3Rgb Phong(R3Scene *scene, R3Ray *ray, R3Intersection *intersection) 
{ 
    R3Rgb radiance; 
    if(intersection->hit == 0) 
    { 
    radiance = scene->background; 
    return radiance; 
    } 

    R3Vector normal = intersection->normal; 
    R3Rgb Kd = intersection->node->material->kd; 
    R3Rgb Ks = intersection->node->material->ks; 

    // obtain ambient term 
    R3Rgb intensity_ambient = intersection->node->material->ka*scene->ambient; 

    // obtain emissive term 
    R3Rgb intensity_emission = intersection->node->material->emission; 

    // for each light in the scene, obtain calculate the diffuse and specular terms 
    R3Rgb intensity_diffuse(0,0,0,1); 
    R3Rgb intensity_specular(0,0,0,1); 
    for(unsigned int i = 0; i < scene->lights.size(); i++) 
    { 
    R3Light *light = scene->Light(i); 
    R3Rgb light_color = LightIntensity(scene->Light(i), intersection->position); 
    R3Vector light_vector = -LightDirection(scene->Light(i), intersection->position); 

    // calculate diffuse reflection 
    intensity_diffuse += Kd*normal.Dot(light_vector)*light_color; 

    // calculate specular reflection 
    R3Vector reflection_vector = 2.*normal.Dot(light_vector)*normal-light_vector; 
    reflection_vector.Normalize(); 
    R3Vector viewing_vector = ray->Start() - intersection->position; 
    viewing_vector.Normalize(); 
    double n = intersection->node->material->shininess; 
    intensity_specular += Ks*pow(max(0.,viewing_vector.Dot(reflection_vector)),n)*light_color; 

    } 

    radiance = intensity_emission+intensity_ambient+intensity_diffuse+intensity_specular; 
    return radiance; 
} 

Sau đây là các LightIntensity liên quan (...) và LightDirection (...) chức năng:

R3Vector LightDirection(R3Light *light, R3Point position) 
{ 
    R3Vector light_direction; 
    switch(light->type) 
    { 
    case R3_DIRECTIONAL_LIGHT: 
     light_direction = light->direction; 
     break; 

    case R3_POINT_LIGHT: 
     light_direction = position-light->position; 
     break; 

    case R3_SPOT_LIGHT: 
     light_direction = position-light->position; 
     break; 
    } 
    light_direction.Normalize(); 
    return light_direction; 
} 

R3Rgb LightIntensity(R3Light *light, R3Point position) 
{ 
    R3Rgb light_intensity; 
    double distance; 
    double denominator; 
    if(light->type != R3_DIRECTIONAL_LIGHT) 
    { 
    distance = (position-light->position).Length(); 
    denominator = light->constant_attenuation + 
         light->linear_attenuation*distance + 
         light->quadratic_attenuation*distance*distance; 
    } 

    switch(light->type) 
    { 
    case R3_DIRECTIONAL_LIGHT: 
     light_intensity = light->color; 
     break; 

    case R3_POINT_LIGHT: 
     light_intensity = light->color/denominator; 
     break; 

    case R3_SPOT_LIGHT: 
     R3Vector from_light_to_point = position - light->position; 
     light_intensity = light->color*(
         pow(light->direction.Dot(from_light_to_point), 
          light->angle_attenuation)); 
     break; 
    } 
    return light_intensity; 
} 

tôi rất nhiều sẽ đánh giá cao bất cứ đề nghị như cho bất kỳ lỗi triển khai nào rõ ràng. Tôi tự hỏi nếu sự khác biệt có thể xảy ra đơn giản chỉ vì các giá trị gamma được sử dụng để hiển thị bởi OpenGL và giá trị gamma mặc định cho màn hình của tôi. Tôi cũng biết rằng OpenGL (hoặc ít nhất là tha phần mà tôi đã được cung cấp) không thể cast bóng trên các đối tượng. Không phải là điều này có liên quan đến vấn đề được đề cập, nhưng nó chỉ khiến tôi tự hỏi liệu nó có đơn giản là sự khác biệt về hiển thị và khả năng giữa OpenGL và những gì tôi đang cố gắng làm.

Cảm ơn sự giúp đỡ của bạn.

Trả lời

0

Trong trường hợp của tôi, dự đoán ban đầu của tôi về sự khác biệt về giá trị gamma là chính xác. Chương trình chính được gọi là thuật toán kết xuất của tôi thực hiện hiệu chỉnh gamma bằng cách sửa giá trị RGB của mỗi pixel của hình ảnh của tôi bằng cách thực hiện cuộc gọi image->TosRGB(). Sau khi nhận xét cuộc gọi, tôi đã có được hình ảnh được sản xuất bởi OpenGL.

3

Bước đầu tiên, tôi sẽ kiểm tra xem bề mặt giao lộ bình thường của bạn có được chuẩn hóa hay không, đặc biệt quan trọng khi tính toán các sản phẩm dot khuếch tán và cụm từ đặc trưng.

Vì mục đích gỡ lỗi, bạn có thể kiểm tra đầu ra của điều kiện ánh sáng (chẳng hạn như đầu ra xung quanh cảnh, đầu ra xung quanh ánh sáng khuếch tán, đầu ra ánh sáng, yếu tố suy giảm ánh sáng, v.v.) phương trình. Một số thuật ngữ đơn giản có khả năng tạo ra kết quả giống hệt nhau và bạn có thể thu hẹp tìm kiếm của mình xuống ít dòng mã hơn bằng cách tiếp cận này. Nó thậm chí có thể bật ra được liên quan đến các đối tượng/phương pháp khác trong việc thực hiện của bạn. Ngoài ra, xin lưu ý rằng bóng phong của OpenGL không tuân theo mô hình bóng Phong phong nghiêm ngặt, vì các chỉ tiêu được tính trên mỗi đỉnh và sau đó được nội suy bên trong tam giác, chúng không được tính trên mỗi điểm trên bề mặt. Mô hình hình cầu của bạn dường như được phân chia đủ, vì vậy đây không phải là một vấn đề thực tế.

OpenGL không thực hiện hiệu chỉnh gamma trừ khi bạn sử dụng không gian màu sRGB làm mục tiêu hiển thị, theo như tôi biết. Tôi hy vọng việc triển khai phần mềm chính xác để tạo ra các kết quả rất giống với việc triển khai OpenGL phần cứng. Happy debugging :)

Các vấn đề liên quan