我已經實現了一個Phong照明方案,它使用一個以(0,0,0)爲中心並直接觀察球體基元的相機。以下是用於查看使用OpenGL以及使用我自己的實現來渲染場景的場景的場景文件的相關內容:OpenGL渲染與自己的Phong照明實現
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
通過OpenGL圖像產生的最終圖像。
我渲染應用程序生成的圖像。
正如你所看到的,有這兩個之間的各種差異:
- 我的形象上的鏡面高光比一個在OpenGL小。
- 漫反射表面似乎不以正確的方式漫射,導致我的圖像中的黃色區域不需要很大,而在OpenGL中,有一個很好的深綠色區域更靠近球體底部
- 產生的顏色通過OpenGL比我的圖像中的要暗得多。
這些是我看到的最突出的三個差異。下面是我實現的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;
}
下面是相關LightIntensity(...)和LightDirection(...)功能:
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;
}
我將不勝感激任何建議,到任何明顯的執行錯誤。我想知道是否可能僅僅因爲用於OpenGL顯示的伽馬值和我的顯示器的默認伽瑪值而發生差異。我也知道,OpenGL(或至少是我提供的部分)不能在對象上投射陰影。並不是說這與問題的關係有關,但它只是讓我想知道它是否僅僅是OpenGL和我正在嘗試做的顯示和性能差異。
謝謝你的幫助。