sábado, febrero 28, 2009

Ajedrez

Hyperbolic surfaces, ambient occlusion, diffuse reflections, area lights, focal blur

Etiquetas:

miércoles, abril 09, 2008

XSight RT v1.5

Nueva versión pública de XSight RT v1.5, también para .NET Framework 3.5. La descarga contiene el instalador del ejecutable, la ayuda y un puñado de escenas para pruebas. No he incluido el código fuente.
La aplicación permite editar escenas con un lenguaje sencillo y bien documentado, y generar imágenes a partir de estas descripciones. De momento, funciona como una aplicación SDI, permitiendo trabajar con un único documento por instancia de la misma.
Refracción y ley de Beer
En esta versión, se incorpora la generación concurrente de escenas, con un modo dual, que reduce casi a la mitad el tiempo de generación en ordenadores con doble núcleo (algo menos en procesadores de un solo núcleo con hyperthreading). Además, ya funciona el material glass, y puede utilizarse un color para el cristal (según la ley de Beer). Hay también soporte para normales perturbadas, los pigmentos crackle y bubbles, cilindros y esferas de cuarto grado, una operación merge para materiales transparentes (equivalente a union, pero eliminando las superficies internas). Y se ha mejorado la velocidad, en general, del núcleo.
Reflexión difusa y niebla

Etiquetas: ,

martes, marzo 04, 2008

Superesferas

Superesferas (XSight RT)
El dado de la imagen está modelado mediante una "superesfera" que se puede describir mediante la ecuación x^4 + y^4 + z^4 = 1. Al tratarse de una ecuación de cuarto grado, se puede resolver algebraicamente, algo que XSight RT hace muy eficientemente. El resultado es la figura del dado: un objeto a mitad de camino entre una esfera (de las de toda la vida) y un cubo. Si en vez de elevar a la cuarta potencia, usásemos exponentes mayores, la figura iría aproximándose más al cubo... pero la ecuación dejaría de tener una solución algebraica, y tendría que resolverse mediante el método de Newton.
Las texturas del tapete y del propio dado están modeladas, naturalmente, mediante el clásico y eficiente ruido de Perlin.

Etiquetas: , ,

sábado, marzo 01, 2008

Grietas

Crackle
Observe el cambio en el "suelo", respecto a la imagen del post anterior: he añadido un patrón que en inglés se conoce como crackle. Lo interesante es que está basado en los diagramas de Voronoi, que se definen como el conjunto de líneas equidistantes respecto a un conjunto de puntos aleatorios en el plano. Si a un robot lo situas en una habitación con objetos calientes, para evitar acercarse demasiado a ellos, tendría que calcular el diagrama de Voronoi asociado, para moverse a lo largo de las líneas del mismo.
En mi imagen, se ha utilizado el crackle para el "pigmento" del plano, pero podría utilizarse también para trucar los vectores normales, y simular que el plano está ligeramente arrugado. Esta técnica, aplicada a una superficie reflectante, puede usarse para simular la superficie del mar.
Para una versión del I King
J.L. Borges

El porvenir es tan irrevocable
Como el rígido ayer. No hay una cosa
Que no sea una letra silenciosa
De la eterna escritura indescifrable
Cuyo libro es el tiempo. Quien se aleja
De su casa ya ha vuelto. Nuestra vida
Es la senda futura y recorrida.
El rigor ha tejido la madeja.
No te arredres. La ergástula es oscura,
La firme trama es de incesante hierro,
Pero en algún recodo de tu encierro
Puede haber una luz, una hendidura.
El camino es fatal como la flecha.
Pero en las grietas está Dios, que acecha.
El patrón crackle, imitando la difracción de la luz entre las hojas de un árbol

Etiquetas: ,

domingo, febrero 24, 2008

Físicamente imposible

No es difícil verlo: ¿qué es lo que "falla" en la siguiente imagen?
Dos esferas de cristal (XSight RT)
No se trata de la distorsión de los mosaicos: la imagen ha sido generada con una lente cilíndrica. Este tipo de lentes permite representar ángulos mayores en una de las dos dimensiones (alto/ancho), al precio de que las líneas rectas no siempre se representan como líneas rectas en la imagen generada.

El problema está, en efecto, en la sombra bajo las esferas. Pero no se trata de que sobren las sombras... sino de que falta algo dentro de las sombras: el área donde se concentran los rayos por el efecto lenticular de las esferas. Es una paradoja: se puede lograr sombra con una esfera transparente.
La imagen ha sido generada, por supuesto, con XSight RT, y se trata de una prueba del nuevo soporte para refracción. La buena noticia: la simulación de materiales es buena. Me gusta más la apariencia del "vidrio" (la mezcla de reflexión y refracción dependiente del ángulo de incidencia) de XSight RT que la de POV Ray, al menos en el vidrio que éste ofrece por omisión. Además, no se pierde velocidad relativa.
Imagen generada con POV Ray¿Cómo habría que resolver lo de la sombra? POV Ray ofrece varias salidas: la primera, que fue probablemente la primera en soportar históricamente, consiste en tener en cuenta la presencia de materiales transparentes al efectuar las pruebas de oclusión. Es decir, se podría permitir que la luz directa atravesase la esfera. XSight RT no seguirá esa vía... porque también es físicamente incorrecta. El problema es que el algoritmo puro de raytracing no permite generar las superficies cáusticas. El raytracing consiste en generar los rayos a la inversa, partiendo de la cámara, y aquí hace falta trazar rayos directamente desde una fuente de luz.
La segunda solución de POV Ray, y que será la implementada por XSight RT, es utilizar una técnica llamada photon mapping. El reto está en hacerlo eficientemente, y que la técnica sea lo más "transparente" posible para el diseñador gráfico. Quiero decir, que no sea necesario indicar tropecientos parámetros para poder generar este tipo de imágenes.

Etiquetas: ,

sábado, febrero 09, 2008

XSight RT v1.1, para .NET v3.5

Si se aburre, puede entretenerse un poco experimentando con XSight RT v1.1, para .NET Framework 3.5. La descarga contiene el instalador del ejecutable, la ayuda y un puñado de escenas para pruebas. No he incluido el código fuente.
La aplicación permite editar escenas con un lenguaje sencillo y bien documentado, y generar imágenes a partir de estas descripciones. De momento, funciona como una aplicación SDI, permitiendo trabajar con un único documento por instancia de la misma. No está conectado todavía el soporte de refracción y transparencias, ni la perturbación de normales (es una técnica con un nombre perturbador).

Etiquetas: ,

jueves, enero 17, 2008

SILLY

No, no estoy llamando "tonto" a nadie: es el nombre que se me ocurrió para el lenguaje de descripción de escenas de XSight RT, y significa, simplemente, Small Instantiation Language... claro, añadiéndole el sufijo de los adverbios ingleses.
El caso es que se trata de un lenguaje orientado a la creación de objetos; de ahí lo de Instantiation. Resulta también que hay un gran números de circunstancias en los que esa "categoría" de minilenguajes resulta útil. ¿Quiere otro ejemplo? Ahí tiene la generación de compiladores. Freya utiliza GOLD: un sistema que recibe una gramática y produce una tabla de análisis sintáctico. Pero es más común el uso de sistemas como Yacc y Bison, que permiten asociar instrucciones en C/C++/C# a la gramática. Hace poco encontré este otro generador, de Wayne Kelly, de la Queensland University of Technology. Incluye el código fuente completo del generador, en C#, y es un código limpio y legible.
Tengo, desde hace un tiempo, la idea de ensayar el uso de un lenguaje tipo SILLY con un generador de compiladores para .NET. Como el análisis sintáctico suele utilizarse para crear, en paralelo, un Arbol de Sintaxis Abstracta (AST), el lenguaje se especializaría en la creación de objetos. Algunas ideas sencillas:
  • Nada de operador new. Cuando un nombre de tipo se usa como función, significa la construcción de una instancia.
  • El lenguaje soportaría inicializadores de objetos... al estilo Freya, claro. Es decir, se podrían inicializar campos y propiedades del objeto creado usando una sintaxis similar a la de los parámetros con nombre.
  • Cada "no terminal" de la gramática tendría un tipo de datos asociado.
  • Cada "regla", o "producción", tendría una expresión asociada, de un tipo derivado del tipo asociado al no terminal.
Veamos un ejemplo sencillo:
<Exp> ::=          : AstExp
<Exp> '+' <Term> : AstBinary($Exp, '+', $Term)
<Term> : $Term
La primera línea advierte que las expresiones van asociadas a nodos de la clase AstExp. En la segunda, cada vez que se detecta una suma, se crea un nodo AstBinary a partir de los nodos de las partes constituyentes. La tercera línea indica que se copie, simplemente, el nodo asociado al término. Este es, naturalmente, el caso más sencillo y frecuente. También es frecuente el uso de listas, por lo que esta variante de SILLY debería soportarlas:
<VarGroup> ::=         : List[AstVar]
<VarGroup> ',' <Var> : $VarGroup + { $Var }
<Var> : { $Var }
Es decir, las llaves se utilizarían para delimitar literales de listas, y el signo + significaría "unión", o concatenación de listas.
Ahora mire un "invento" curioso, asociado a la regla sintáctica correspondiente al operador existencial de Freya:

<Exp> ::= : AstExp
'*' IN <Exp> : if $Exp is AstRange
then AstBin($Exp.Lo, "<=", $Exp.Hi)
else AstExists($Exp)
Para empezar, observe que he mostrado una expresión condicional, no una instrucción condicional. Lo interesante es lo que ocurre en la rama then de la expresión: como esa rama se evalúa cuando $Exp es un AstRange, cambiamos el tipo declarado para $Exp de esa rama para abajo (en el árbol de expresiones); por eso permitimos las referencias a las propiedades Lo y Hi (low y high), definidas para AstRange. Creo que un convenio de este tipo ahorraría mucho trabajo y sería muy útil en lenguajes de propósito general... aunque tengo que pensarlo un poco más, antes de dar el recurso por bueno.
Naturalmente, se permitiría expresiones let/where, y quizás sería necesario algún "aplicador" para actuar sobre elementos de una lista. El "compilador" tendría que encargarse también de algo que podemos clasificar como inyección de código: se supone que, a la vez que se construye el árbol sintáctico, los nodos de éste deben irse asociando a intervalos o rangos de texto dentro del código fuente. A los nodos devueltos en cada reducción, por ejemplo, se les podría asociar automáticamente al rango determinado por el texto reducido. Pero habría casos más complicados:
<Exp> ::=            : AstExp
<Exp> IS NOT <Ref> : AstNeg(AstCast($1, $3))
El nodo AstNeg es el inmediatamente devuelto por la reducción, por lo que es fácil asignarle un rango. En cambio, el nodo AstCast se esconde dentro del nodo principal. Una solución laboriosa sería indicar explícitamente la asignación del rango:
AstNeg(AstCast($1, $3, Range := @1 + @3))
Este es un ejemplo de los inicializadores de objetos ya mencionados. Observe que @1 se refiere al rango asociado al primer nodo de la regla. Otra solución más elegante sería permitir que el compilador dedujese dicha asignación, a partir de los parámetros detectados en la llamada al constructor AstCast.
¿Qué le parece?

Etiquetas: , ,

lunes, agosto 14, 2006

Blobs

BlobsXSight RT despega en complejidad. La imagen adyacente muestra un tipo de sólido llamado blob (en inglés, claro). La figura mostrada, en particular, es no convexa: una línea puede tener más de dos puntos de intersección con uno de estos sólidos.
¿Qué es un blob y cómo se define? La variante implementada por XSight RT se define ubicando esferas en el espacio. El centro de cada esfera define entonces un campo de fuerza, cuya intensidad decrece a medida que nos alejamos del centro de la esfera. Si los campos de dos esferas se solapan en una zona, sus respectivas intensidades se suman. Entonces se define un valor deseado para la intensidad, y la superficie del blob se define como los puntos en los que la intensidad de campo es igual al valor elegido. El resultado es que dos esferas, inicialmente disjuntas, pueden "soldarse" entre sí mediante una superficie continua y suave, como la del ejemplo.
El modelo usado por XSight RT es un subconjunto de los blobs implementados por POV Ray. POV Ray permite usar también cilindros como elementos dentro de un blob, pero espero poder ampliar mi implementación. Lo interesante de estos objetos es que para calcular las intersecciones sólo necesitamos resolver una ecuación polinomial de cuarto grado... de forma similar a lo que ocurre con los toros (las rosquillas, no los bichos con cuernos). Y lo mejor de todo es que XSight RT tiene un algoritmo de resolución para ecuaciones cuárticas muy eficientes. Una ecuación de cuarto grado se resuelve mediante una ecuación auxiliar de tercer grado. Pero de esta ecuación auxiliar sólo se necesita la primera raíz (de las tres posibles), y los coeficientes de la ecuación auxiliar tienen una forma especial. Mientras otros sistemas resuelven una ecuación auxiliar "completa", calculando las tres raíces, XSight RT utiliza un algoritmo optimizado.

Etiquetas: , ,