Пересечение лучей и сфер: дискриминант НЕПРАВИЛЬНЫЙ

Хорошо, я работаю над трассировщиком лучей с использованием затенения по фонгу. Пока все хорошо. Я пролил лучи, которые попали на сферы в моей сцене, применил к ним затенение фонга, и это выглядит нормально.

Теперь я вычисляю теневые лучи, которые испускают луч из точки пересечения первичного луча с источником света и смотрю, попадает ли он в какие-либо объекты на своем пути. Если да, то в тени.

Однако при вычислении того, попадает ли теневой луч в какие-либо сферы, кажется, есть ошибка с моим вычисленным дискриминантом, что является странным, поскольку до сих пор он был правильным для первичных лучей.

Вот установка:

// Origin of ray (x,y,z)
origin: -1.9865333, 1.0925934, -9.8653316
// Direction of ray (x,y,z), already normalized
ray: -0.99069530, -0.13507602, -0.016648887

// Center of sphere (x,y,z)
cCenter: 1.0, 1.0, -10.0
// Radius of the sphere (x,y,z)
cRadius: 1.0

, а вот код для поиска дискриминанта:

// A = d DOT d
float a = dotProd(ray, ray);

// B = 2 * (o - c) DOT d
Point temp (2.0*(origin.getX() - cCenter.getX()), 2.0*(origin.getY() - cCenter.getY()), 2.0*(origin.getZ() - cCenter.getZ()));
float b = dotProd(temp, ray);

// C = (o - c) DOT (o - c) - r^2
temp.setAll(origin.getX() - cCenter.getX(), origin.getY() - cCenter.getY(), origin.getZ() - cCenter.getZ());
float c = dotProd(temp, temp);
c -= (cRadius * cRadius);

// Find the discriminant (B^2 - 4AC)
float discrim = (b*b) - 4*a*c; 

Ясно, что луч направлен от сферы, но дискриминант здесь положительный (2,88), что указывает на то, что луч попадает в сферу. И этот код отлично работает для первичных лучей, поскольку их дискриминанты должны быть правильными, но не для этих вторичных теневых лучей.

Я что-то упустил?


person user1115016    schedule 25.12.2011    source источник
comment
Я предполагаю, что вам не хватает понимания математики и того, что она вам говорит. Сообщит ли этот алгоритм вам, пересекает ли ЛИНИЯ сферу, а не луч? То есть линия имеет бесконечную протяженность в двух направлениях.   -  person    schedule 25.12.2011
comment
@woodchips Луч - это вектор (точка с направлением), поэтому он бесконечен в одном направлении (направлении, в котором он указывает). Формула основана на функции шара. Точка P лежит на сфере, если она удовлетворяет: || P - Pc || = r ^ 2, где Pc - центр сферы, а r - радиус. Для луча точка P находится на луче, если P = Q + td, где Q - начальная точка луча, d - направление, а t - время. Вот ссылка на случай, если мое объяснение не соответствует действительности: wiki.cgsociety.org/index.php/Ray_Sphere_Intersection   -  person user1115016    schedule 25.12.2011
comment
да. И хотя вы тщательно скопировали определения линии и луча, вы просто не позаботились понять уравнения, которые используются, и реализовать то, на что вы ссылаетесь. Положительный или отрицательный дискриминант НЕ означает, что существует решение для пересечения луча. Он сообщает вам, что существует решение для бесконечной ЛИНИИ, пересекающей сферу, если дискриминант положительный !!!!!!! (На самом деле неотрицательный критерий интереса.) Прочтите тот документ, на который вы ссылаетесь, и прочтите его внимательно.   -  person    schedule 25.12.2011
comment
Если линия ДЕЙСТВИТЕЛЬНО пересекает сферу, можно определить, находится ли точка пересечения в направлении луча, на который на самом деле указывает луч.   -  person    schedule 25.12.2011
comment
@woodchips Я польщен, что вы думаете, что я скопировал определение. Я прочитал этот документ, и нигде на странице нет упоминания о строке. Однако ваше объяснение имеет смысл, поскольку оно обнаруживает попадания по обе стороны луча (т. Е. Линии). Думаю, это дает мне над чем поработать сейчас. Спасибо.   -  person user1115016    schedule 30.12.2011
comment
@woodchips Решил! Простой отрицательный тест на t-значение дает результат. Еще раз спасибо за лечение моего безумия.   -  person user1115016    schedule 30.12.2011


Ответы (3)


Такой короткий ответ на мою проблему, если кто-то обнаружит это и имеет ту же проблему:

Дискриминант сообщает вам, существует ли попадание для линиинет для луча, как я думал). Если он положительный, значит, он обнаружил попадание где-то на линии.

Итак, при вычислении t-значений для луча проверьте, являются ли они отрицательными. Если они есть, то это попадание ЗА точку происхождения луча (т. Е. Противоположное направление луча), поэтому отбросьте его. Сохраняйте только положительные значения, поскольку они попадают в направлении луча.

Еще более короткий ответ: отбросьте отрицательные t-значения.

Благодарим древесную щепу за то, что заставили меня это понять.

person user1115016    schedule 30.12.2011

Проблема в том, что уловка для нахождения пересечения линии и сферы требует решения квадратного уравнения. У такого уравнения есть одна из трех возможностей решения - есть 0, 1 или 2 реальных решения этого уравнения. Знак дискриминанта говорит нам, сколько существует реальных решений (а также помогает нам найти эти решения).

Если существует единственное решение, линия просто целует поверхность сферы. Это происходит, когда дискриминант точно равен нулю.

Если существует два решения, то линия проходит через сферу, ударяясь о поверхность в ДВУХ различных точках.

Если реального решения не существует (случай, когда дискриминант отрицательный), линия лежит слишком далеко от сферы, чтобы вообще ее касаться.

Обнаружив, подходит ли линия когда-либо к сфере или нет, мы только тогда беспокоимся, попадет ли в нее луч. Для этого мы можем посмотреть, как мы определяем луч. Луч - это полупрямая линия, уходящая в бесконечность только в одном направлении. Итак, мы смотрим, где на линии встречаются точки пересечения. Только если пересечение происходит на половине интересующей нас линии, существует пересечение ЛУЧ-сферы.

Дело в том, что вычисление дискриминанта (и просто проверка его знака) говорит вам ТОЛЬКО о том, что делает линия, а не о том, где на этой линии происходит пересечение.

Конечно, внимательное прочтение ссылки, которую вы сами предоставили, рассказало бы вам все это.

person Community    schedule 25.12.2011
comment
Ответ в вашем комментарии был более полезным. - person user1115016; 30.12.2011

Уверен, что "o-c" должно быть "c-o"

Вы стреляете лучом в неправильном направлении и находите пересечение на другой стороне сферы.

person Jeremiah    schedule 25.12.2011