4D星宇

c++

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  57 随笔 :: 0 文章 :: 39 评论 :: 0 Trackbacks

                           学习光线追踪(格式都乱了,郁闷)
射线类的定义:
class Ray
{
   public:
 Ray() : m_Origin( vector3( 0, 0, 0 ) ), m_Direction( vector3( 0, 0, 0 ) ) {};
 Ray( vector3& a_Origin, vector3& a_Dir );
   private:
 vector3 m_Origin;
 vector3 m_Direction;
};
光线追踪算法:
For each pixel
{
 Construct ray from camera through pixel
 Find first primitive hit by ray
 Determine color at intersection point
 Draw color

求最近交点
 // find the nearest intersection
for ( int s = 0; s < m_Scene->GetNrPrimitives(); s++ )
{
 Primitive* pr = m_Scene->GetPrimitive( s );
 int res;
 if (res = pr->Intersect( a_Ray, a_Dist ))
 {
  prim = pr;
  result = res; // 0 = miss, 1 = hit, -1 = hit from inside primitive
 }
}
交点的颜色:
// determine color at point of intersection
pi = a_Ray.GetOrigin() + a_Ray.GetDirection() * a_Dist;
// trace lights
for ( int l = 0; l < m_Scene->GetNrPrimitives(); l++ )
{
 Primitive* p = m_Scene->GetPrimitive( l );
 if (p->IsLight())
 {
  Primitive* light = p;
  // calculate diffuse shading
  vector3 L = ((Sphere*)light)->GetCentre() - pi;
  NORMALIZE( L );
  vector3 N = prim->GetNormal( pi );
  if (prim->GetMaterial()->GetDiffuse() > 0)
  {
   float dot = DOT( N, L );
   if (dot > 0)
   {
    float diff = dot * prim->GetMaterial()->GetDiffuse();
    // add diffuse component to ray color
    a_Acc += diff * prim->GetMaterial()->GetColor() * light->GetMaterial()->GetColor();
   }
  }
 }
}
计算反射:
// calculate reflection
float refl = prim->GetMaterial()->GetReflection();
if (refl > 0.0f)
{
 vector3 N = prim->GetNormal( pi );
 vector3 R = a_Ray.GetDirection() - 2.0f * DOT( a_Ray.GetDirection(), N ) * N;
 if (a_Depth < TRACEDEPTH)
 {
  Color rcol( 0, 0, 0 );
  float dist;
  Raytrace( Ray( pi + R * EPSILON, R ), rcol, a_Depth + 1, a_RIndex, dist );
  a_Acc += refl * rcol * prim->GetMaterial()->GetColor();
 }
}
Phong光照公式:intensity = diffuse * (L.N) + specular * (V.R)n

vector3 V = a_Ray.GetDirection();
vector3 R = L - 2.0f * DOT( L, N ) * N;
float dot = DOT( V, R );
if (dot > 0)
{
 float spec = powf( dot, 20 ) * prim->GetMaterial()->GetSpecular() * shade;
// add specular component to ray color
a_Acc += spec * light->GetMaterial()->GetColor();
}
计算阴影
// handle point light source
float shade = 1.0f;
if (light->GetType() == Primitive::SPHERE)
{
 vector3 L = ((Sphere*)light)->GetCentre() - pi;
 float tdist = LENGTH( L );
 L *= (1.0f / tdist);
 Ray r = Ray( pi + L * EPSILON, L );
 for ( int s = 0; s < m_Scene->GetNrPrimitives(); s++ )
 {
  Primitive* pr = m_Scene->GetPrimitive( s );
  if ((pr != light) && (pr->Intersect( r, tdist )))
  {
   shade = 0;
   break;
  }
 }
}

posted on 2008-07-06 10:53 bloodbao 阅读(494) 评论(0)  编辑 收藏 引用 所属分类: c++

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理