使用 Phong 模型的点光源照明

Posted

技术标签:

【中文标题】使用 Phong 模型的点光源照明【英文标题】:point light illumination using Phong model 【发布时间】:2010-04-02 00:55:53 【问题描述】:

我希望使用 Phong 照明方案渲染一个包含一个盒子和一个点光源的场景。以下是我计算的相关代码sn-ps:

R3Rgb Phong(R3Scene *scene, R3Ray *ray, R3Intersection *intersection)

  R3Rgb radiance;
  if(intersection->hit == 0)
  
    radiance = scene->background;
    return radiance;
  

  ...
  // obtain ambient term
  ... // this is zero for my test

  // obtain emissive term
  ... // this is also zero for my test

  // 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);

    // check if the light is "behind" the surface normal
    if(normal.Dot(light_vector)<=0)
      continue;

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

    if(Ks.IsBlack())
      continue;

    // calculate specular reflection
    ... // this I believe to be irrelevant for the particular test I'm doing

  

  radiance = intensity_diffuse;
  return radiance;


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_POINT_LIGHT:
      light_intensity = light->color/denominator;
      break;

    ...
  
  return light_intensity;


R3Vector LightDirection(R3Light *light, R3Point position)

  R3Vector light_direction;
  switch(light->type)
  
    ...
    case R3_POINT_LIGHT:
      light_direction = position - light->position;
      break;
    ...
  
  light_direction.Normalize();
  return light_direction;

我相信错误一定是在 LightDirection(...)LightIntensity(...) 函数中的某个地方,因为当我使用定向光源运行我的代码时,我获得了所需的渲染图像(因此这让我相信 Phong 照明等式是正确的)。此外,在 Phong(...) 中,当我计算 intensity_diffuse 并在调试时,我将 light_color 除以 10,我得到的结果图像看起来更像我需要的。我是否正确计算了light_color

谢谢。

【问题讨论】:

生成的渲染图像比预期的要亮。所以“错误”是指我在计算给定点位置的光强度时可能出错 我刚刚通过在light_intensity = light-&gt;color/denominator;LightIntensity(...) 中添加light_intensity = light_intensity/(1.+distance+distance*distance); 来测试实现,它似乎给了我想要的东西。这是正常的吗?编辑:这并没有给我我想要的东西,但似乎需要进行某种划分.... 菲涅耳是我尝试过的最基本的灯光模型,或者是 Gouraud 的替代品。它们都可以在 OpenGL 中使用 【参考方案1】:

原来我没有错误。我用来比较结果的“最终图像”计算不正确。

【讨论】:

以上是关于使用 Phong 模型的点光源照明的主要内容,如果未能解决你的问题,请参考以下文章

如何为 Phong 着色实现选择光源?

基于Qt的OpenGL可编程管线学习- 方向光点光源phongblin-phong

简单的图形学——光源

使用 HLSL 和 D3D11 进行 Blinn-Phong 着色:点光源

WebGL使用点光源照明(WebGL进阶06)

用定向光源计算反射矢量