2010-03-28 6 views
6

저는 (0,0,0)을 중심으로 구형 프리미티브를 직접 바라 보는 카메라를 사용하여 Phong Illumination Scheme을 구현했습니다. 내 자신의 구현을 사용하여 장면을 렌더링 할뿐만 아니라 OpenGL을를 사용하는 장면을 볼하는 데 사용되는 장면 파일의 관련 내용은 다음과 같습니다 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 

Here

결과 이미지는.

Here

내 렌더링 응용 프로그램이 생산하는 이미지입니다.

  1. 내 이미지에 반사 하이라이트는 OpenGL에서 하나보다 작은 : 당신이 볼 수 있듯이

    , 둘 사이에 다양한 차이가있다.

  2. 확산 표면이 올바른 방식으로 확산되지 않는 것 같습니다. 노란색 영역이 내 이미지에서 불필요하게 커지는 반면 OpenGL에서는 구체의 아래쪽에 가까운 짙은 녹색 영역이 있습니다.
  3. 생성 된 색 OpenGL은 내 이미지보다 훨씬 더 어둡습니다.

내가보기에 가장 눈에 띄는 세 가지 차이점이 있습니다. 여기

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과 내가하려고하는 것 사이의 단순한 디스플레이 및 기능 차이인지 궁금합니다.

도움 주셔서 감사합니다.

답변

0

내 경우에는 감마 값의 차이에 대한 내 초기 추측은 맞았습니다. 내 렌더링 알고리즘을 호출 한 주 프로그램은 image->TosRGB() 호출을 수행하여 이미지의 각 픽셀의 RGB 값을 교정하여 감마 보정을 수행했습니다. 전화를 주석 처리 한 후 OpenGL에서 제작 한 이미지를 얻었습니다.

3

첫 번째 단계로, 교차 표면 정규화가 정규화되었는지 확인합니다. 특히 확산 및 반사 용어 점 제품을 계산할 때 중요합니다.

디버깅을 위해 조명 용어의 출력 (장면 주변 출력, 광 주변 확산 - 반사 출력, 광 감쇠 계수 등)을 하나씩 확인하고 방정식. 몇 가지 간단한 용어는 동일한 결과물을 생성 할 가능성이 있으며이 방법을 사용하면 코드 줄 수를 줄일 수 있습니다. 구현시 다른 객체/메소드와 관련이있을 수도 있습니다.

또한 OpenGL의 Phong 음영은 Phong 음영 모델을 엄격히 따르지 않습니다. 법선은 정점마다 계산 된 다음 삼각형 내부에 삽입되므로 표면의 점 당 계산되지 않습니다. 구형 모델은 충분히 모자이크 처리 된 것으로 보이므로 실용적인 문제는 아닙니다.

OpenGL은 내가 알고있는 한 sRGB 색 공간을 렌더링 대상으로 사용하지 않으면 감마 보정을 수행하지 않습니다. 올바른 소프트웨어 구현으로 인해 하드웨어 OpenGL 구현과 매우 유사한 결과를 얻을 것으로 기대됩니다. 해피 디버깅 :)