Ray Tracer Проблемы с тенью - PullRequest
       20

Ray Tracer Проблемы с тенью

0 голосов
/ 19 декабря 2018

Я работаю над трассировщиком лучей, но я застрял на несколько дней в теневой части.Моя тень ведет себя очень странно.Вот изображение трассировщика лучей:

enter image description here

Image of shadow with two spheres

Черная часть должна бытьтень.

Источник луча всегда (0.f, -10.f, -500.f), потому что это перспективная проекция, и это глаз камеры.Когда луч попадает на плоскость, точка попадания всегда является источником луча, но в сфере это не так.Это отличается, потому что это основано на положении сферы.Между плоскостью и сферой никогда не бывает пересечений, потому что источник - огромная разница.Я также пытался добавить тень на коробку, но это тоже не работает.Тень между двумя сферами работает!

Если кто-то хочет увидеть код пересечения, дайте мне знать.

Спасибо, что нашли время помочь мне!

Камера

Camera::Camera(float a_fFov, const Dimension& a_viewDimension, vec3 a_v3Eye, vec3 a_v3Center, vec3 a_v3Up) :
m_fFov(a_fFov),
m_viewDimension(a_viewDimension),
m_v3Eye(a_v3Eye),
m_v3Center(a_v3Center),
m_v3Up(a_v3Up)
{
  // Calculate the x, y and z axis
  vec3 v3ViewDirection = (m_v3Eye - m_v3Center).normalize();
  vec3 v3U = m_v3Up.cross(v3ViewDirection).normalize();
  vec3 v3V = v3ViewDirection.cross(v3U);

  // Calculate the aspect ratio of the screen
  float fAspectRatio = static_cast<float>(m_viewDimension.m_iHeight) / 
                       static_cast<float>(m_viewDimension.m_iWidth);
  float fViewPlaneHalfWidth = tanf(m_fFov / 2.f);
  float fViewPlaneHalfHeight = fAspectRatio * fViewPlaneHalfWidth;

  // The bottom left of the plane
  m_v3ViewPlaneBottomLeft = m_v3Center - v3V * fViewPlaneHalfHeight - v3U * fViewPlaneHalfWidth;

  // The amount we need to increment to get the direction. The width and height are based on the field of view.
  m_v3IncrementX = (v3U * 2.f * fViewPlaneHalfWidth);
  m_v3IncrementY = (v3V * 2.f * fViewPlaneHalfHeight);
}

Camera::~Camera()
{
}

const Ray Camera::GetCameraRay(float iPixelX, float iPixelY) const
{
  vec3 v3Target = m_v3ViewPlaneBottomLeft + m_v3IncrementX * iPixelX + m_v3IncrementY * iPixelY;
  vec3 v3Direction = (v3Target - m_v3Eye).normalize();

  return Ray(m_v3Eye, v3Direction);
}

Настройка камеры

Scene::Scene(const Dimension& a_Dimension) :
m_Camera(1.22173f, a_Dimension, vec3(0.f, -10.f, -500.f), vec3(0.f, 0.f, 0.f), vec3(0.f, 1.f, 0.f))
{
  // Setup sky light
  Color ambientLightColor(0.2f, 0.1f, 0.1f);
  m_AmbientLight = new AmbientLight(0.1f, ambientLightColor);

  // Setup shapes
  CreateShapes();

  // Setup lights
  CreateLights();

  // Setup buas
  m_fBias = 1.f;
}

Объекты сцены

Sphere* sphere2 = new Sphere();
sphere2->SetRadius(50.f);
sphere2->SetCenter(vec3(0.f, 0.f, 0.f));
sphere2->SetMaterial(matte3);

Plane* plane = new Plane(true);
plane->SetNormal(vec3(0.f, 1.f, 0.f));
plane->SetPoint(vec3(0.f, 0.f, 0.f));
plane->SetMaterial(matte1);

Подсветка сцены

PointLight* pointLight1 = new PointLight(1.f, Color(0.1f, 0.5f, 0.7f), vec3(0.f, -200.f, 0.f), 1.f, 0.09f, 0.032f);

Функция тени

for (const Light* light : a_Lights) {
    vec3 v3LightDirection = (light->m_v3Position - a_Contact.m_v3Hitpoint).normalized();

    light->CalcDiffuseLight(a_Contact.m_v3Point, a_Contact.m_v3Normal, m_fKd, lightColor);

    Ray lightRay(a_Contact.m_v3Point + a_Contact.m_v3Normal * a_fBias, v3LightDirection);

    bool test = a_RayTracer.ShadowTrace(lightRay, a_Shapes);

    vec3 normTest = a_Contact.m_v3Normal;
    float test2 = normTest.dot(v3LightDirection);

    // No shadow
    if (!test) {
        a_ResultColor += lightColor * !test * test2;
    }
    else {
        a_ResultColor = Color(); // Test code - change color to black.
    }
}

1 Ответ

0 голосов
/ 19 декабря 2018

У вас есть несколько ошибок:

  • в Sphere::Collides, m_fCollisionTime не установлено, когда t2>=t1
  • в Sphere::Collides, если m_fCollisionTime отрицательнотогда луч фактически не пересекается со сферой (это вызывает странную тень на вершине шара)
  • поместите плоскость ниже, и вы увидите тень шара
  • вам нужно проверить на ближайшее столкновение , когда стреляете лучом из глаза (просто попробуйте поменять местами порядок объектов, и сфера внезапно станет позади плоскости)

Исправив это, вы получите: enter image description here

...