Я строю трассировщик лучей в качестве задания. Я пытаюсь заставить преломление работать в сферах, и я получил его полуфабрикат. Проблема в том, что я не могу избавиться от черной точки в центре сферыТрассировка лучей, полупрозрачная сфера имеет точку в центре
Это код для пересечения:
double a = rayDirection.DotProduct(rayDirection);
double b = rayOrigin.VectAdd(sphereCenter.Negative()).VectMult(2).DotProduct(rayDirection);
double c = rayOrigin.VectAdd(sphereCenter.Negative()).DotProduct(rayOrigin.VectAdd(sphereCenter.Negative())) - (radius * radius);
double discriminant = b * b - 4 * a * c;
if (discriminant >= 0)
{
// the ray intersects the sphere
// the first root
double root1 = ((-1 * b - sqrt(discriminant))/2.0 * a) - 0.000001;
double root2 = ((-1 * b + sqrt(discriminant))/2.0 * a) - 0.000001;
if (root1 > 0.00001)
{
// the first root is the smallest positive root
return root1;
}
else
{
// the second root is the smallest positive root
return root2;
}
}
else
{
// the ray missed the sphere
return -1;
}
Этот код отвечает за вычисления направление нового преломленного луча:
double n1 = refractionRay.GetRefractiveIndex();
double n2 = sceneObjects.at(indexOfWinningObject)->GetMaterial().GetRefractiveIndex();
if (n1 == n2)
{
// ray inside the same material, means that it is going to be refracted outside,
n2 = 1.000293;
}
double n = n1/n2;
Vect I = refractionRay.GetRayDirection();
Vect N = sceneObjects.at(indexOfWinningObject)->GetNormalAt(intersectionPosition);
double cosTheta1 = -N.DotProduct(I);
// we need the normal pointing towards the side the ray is coming from
if (cosTheta1 < 0)
{
N = N.Negative();
cosTheta1 = -N.DotProduct(I);
}
double cosTheta2 = sqrt(1 - (n * n) * (1 - (cosTheta1 * cosTheta1)));
Vect refractionDirection = I.VectMult(n).VectAdd(N.VectMult(n * cosTheta1 - cosTheta2));
Ray newRefractionRay(intersectionPosition.VectAdd(refractionDirection.VectMult(0.001)), refractionDirection, n2, refractionRay.GetRemainingIntersections());
При создании нового преломляющего луча, я попытался добавить времена направления малого значение в Инту чтобы создать происхождение этого нового луча внутри сферы. Размер черной точки изменяется, если я изменю это маленькое значение. Если я сделаю это слишком большим, поля сферы снова станут черными.
Если добавить цвет к объекту это выглядит следующим образом:
А если сделать что малая константа больше (0,1) это происходит:
Есть особое условие, которое я должен учитывать? Спасибо!
Обратите внимание, что у вас также есть отражатель в зеленой сфере. Если это актуально, я считаю, что передняя область бесцветная и прозрачная, а не рефлексивная? –
Я бы предложил сначала проверить ваши рефракционные уравнения - пересечение сферы выглядит якобы действительным (и это подтверждается правильным отображением непрозрачных сфер в сцене). – Alnitak
также не должно быть необходимости вычитать этот эпсилон-фактор из двух корней, если вы убедитесь, что значение найденных корней превышает epsilon. Эти факторы необходимы только для того, чтобы вновь образовавшиеся лучи, начиная с поверхности сферы, снова не пересекали сферу. – Alnitak