Intenté esta pregunta en matemáticas. SE y, sorprendentemente, la respuesta fue "las ecuaciones son demasiado desagradables, solo alimente la función a un buscador de raíces numérico". Pero si te consideras un "tipo gráfico" como yo y has jugado mucho con las curvas de Bezier para el trabajo de diseño, tengo que creer que se puede hacer mejor. Hay un algoritmo publicado por Kajiya que no tengo los antecedentes para entender (Matrices de Sylvester), pero el consejo relacionado con las matemáticas fue que el resultado es un polinomio de grado 18 en t, y aún necesita resolver eso numéricamente. Tuve otra idea con un resultado similar .
Entonces, ¿es un sueño total esperar resolver algebraicamente la intersección de la superficie Ray / Bezier, permitiendo codificar explícitamente y tener una super-suavidad súper rápida?
Salvo eso, ¿cuál es el método más rápido para realizar este cálculo? ¿Puedes "encontrar los movimientos" para obtener un límite estrecho (y un objetivo) para la subdivisión recursiva? Si tiene que usar un buscador de raíz numérico (suspiro), ¿qué propiedades necesita y hay una mejor opción para la velocidad?
Mi pensamiento original era prepararme para una superficie específica, similar a la expansión de Laplace como se describe en la respuesta a mi otra pregunta matemática sobre triángulos . Pero también me interesarían los métodos generales. Solo estoy pensando en un conjunto fijo de formas, como la tetera de Utah . Pero me interesarían mucho las formas de optimizar la coherencia temporal en los cuadros animados.
fuente
Respuestas:
En primer lugar, aquí está el método Kajiya en el que creo que está pensando: Kajiya, Parches paramétricos de trazado de rayos , SIGGRAPH 82. La versión del informe técnico podría ser más informativa.
Lo que espero que obtengas de eso es que no es imposible y no es conceptualmente difícil si no te importa ensuciarte las manos con algo de geometría algebraica y números complejos. Sin embargo, hacerlo directamente es absurdamente caro.
Los trazadores de rayos "reales" tienden a hacer una combinación de dos cosas:
Parece que ese último punto mata el requisito de "súper suavidad", pero no es tan malo como eso si usa diferenciales de rayos . Hacer coincidir el nivel de teselación con el "tamaño" del rayo limita muy bien el error. Además, probablemente necesite diferenciales para las coordenadas de textura de todos modos, por lo que también podría usarlo para controlar la precisión de la prueba de intersección.
Explotar la coherencia temporal no es una mala idea, pero exactamente cómo lo harías depende mucho de la representación gráfica de tu escena. Es posible que desee ver la coherencia de los rayos. Pregúntele a su motor de búsqueda favorito sobre el rastreo de paquetes de rayos y el reordenamiento de rayos .
fuente
Sí, es un sueño imposible. Un parche bicúbico de Bezier es una superficie algebraica de grado 18. Para intersecar un rayo con esta superficie, debe encontrar las raíces de un polinomio de grado 18. No hay una fórmula para estas raíces: debe encontrarlas por métodos numéricos . De hecho, hay resultados matemáticos ( el teorema de Abel-Ruffini ) que nos dicen que nunca puede haber fórmulas para raíces de ecuaciones más allá del grado 4. Las matemáticas no solo dicen que las fórmulas aún no se han encontrado; dice que nunca serán encontrados, porque no pueden existir.
Si realmente desea hacer un trazado de rayos analítico (algebraico) de formas curvilíneas, puede intentar usar parches Steiner . Estos tienen grado 4, por lo que la intersección parche de rayos se puede calcular encontrando las raíces de un cuarto (es decir, un polinomio de grado 4). Hay fórmulas para encontrar raíces de cuartiles, pero son bastante desagradables y es sorprendentemente difícil escribir código que implemente las fórmulas de manera confiable.
fuente
Otra opción, que utilicé hace un par de décadas (¡ay!), Es utilizar el esquema de Toth de 1985 que empleaba la aritmética de intervalos para reducir el espacio de búsqueda. IIRC, eventualmente recurrirá a Newton-Rhapson pero, nuevamente IIRC, creo que raramente requirió más de uno o dos pasos para llegar a una buena solución.
Aunque no lo he mirado (bueno, aparte de un vistazo rápido) Mitchell ha publicado algunos trabajos más recientes sobre el trazado de rayos con matemáticas de intervalos.
(Debo agregar que, si solo está haciendo superficies Bezier, entonces el método de intervalo podría ser un poco "excesivo" ya que puede usar trucos como el florecimiento para obtener límites y derivados. Sin embargo, si combina las curvas Bezier con otras funciones, ej. rotación alrededor de un eje, entonces su generalidad es más útil).
fuente
https://www.shadertoy.com/results?query=bezier ordenar por edad, en caso de problemas de compatibilidad:
, ... muestra muchas soluciones de muchos subconjuntos de spline, ya sea devolviendo la distancia a una spline 2d o trazando un parche 3d. Las estrías y parches vienen en muchas formas. bevensine beind más simple, bezier es simple, los nubs son demasiado complejos. Cuantas más restricciones agregue a su spline, más simple se vuelve. NURBS es una exageración exagerada; - su no uniformidad de pesos (la "NU") disminuye la eficiencia en comparación con splines más simétricas - su racionalidad (la R) también agrega cierta complejidad, para segmentar (racionar) y mezclar con segmentos cercanos (resuelto recursivamente).
bezier-patch-tracing es la resolución de la raíz y con eso viene la priorización contextual en la precisión; en qué orden resolver la ecuación cuadrática. esto se vuelve poco práctico en exponentes más altos que cúbicos, debido a la complejidad exponencial y la pérdida de precisión.
ray-marching == esfera-tracking es el enfoque heurístico más simple para la resolución de raíces, que parece ser la solución simple y más eficiente para renderizar la mayoría de los parches de splines.
La representación de Lagrange simplifica el trazado / marcha (ya que los puntos L están EN la spline mientras que los puntos ControlVector (de la misma spline) rara vez están en la spline)
El caso especial de una spline de cielo celeste, donde las primeras derivadas de stat y end son == 0. simplifica la continuidad e implica menos diferenciales (menos resta). Un parche de cielo celeste se puede rastrear de manera eficiente en una sola pasada: https://www.shadertoy.com/view/4djfW3, mientras que otras splines cúbicas (o más altas) hacen que el enfoque heurístico de seguimiento de esfera / marcha de rayos sea más eficiente (y " suficientemente preciso ") que atreverse a calcular analíticamente todas las raíces para mantener la raíz positiva más pequeña (con errores de precisión que se acumulan exponencialmente para cada raíz).
En gráficos de computadora, las splines y los parches han sido reemplazados casi por completo por z-brushing en 2006. z-brushing utiliza mapas de desplazamiento con coordenadas homogéneas, o incluso usando un "tipo" que usa una unión de esfera y linesegments (los linesegments tienen un radio de 0, las esferas tienen una longitud de 0, una unión es simple y útil). Para una pérdida menor de precisión para una gran ganancia en el rendimiento a un costo de memoria relativamente bajo para una tabla de consulta, eso se hace fácilmente dinámico en una gpu.
fuente