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
Hình ảnh thu được sản xuất bởi OpenGL.
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:
- Đ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.
- 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
- 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.