Si ya trabajas con VRML, esto no te servirá de gran cosa. Este apartado no intenta ser un curso completo de VRML, tan solo es una introducción al fascinante mundo de las ballenas !!## @@ ??!! ...., esto..., no las ballenas no, queria decir del VRML, es por los documentales sabes, me los trago todos y luego pasa lo que pasa. En fin, a lo que vamos, que si no lo conoces, pero tienes unas mínimas nociones de programación y HTML, después de ver este apartado podrás hacer tus primeros pinitos con VRML, y si ya eres un experto en el tema, puedes pasarte a verlo, no me ha quedado mal del todo.
La configuración más recomendable para seguir este curso, es un 486-66/ Pentium con 8Mb, y con una resolucción mínima de 800x600. En cuanto al color, si puedes disponer de 16 o 24 bits, la cosa mejorará muchísimo (no existe paleta de color en esos modos).
De todas formas, si la paleta se te modifica al entrar en un modelo 3D, cuando salgas de él, debes minimizar el navegador para que se restaure la paleta original.
Todo lo que se explique en este curso, va referido al estandard VRML 1.0, y para poder ver los resultados debes tener Netscape 3.0, o un plug-in como en tu navegador como Live3D o CosmoPlayer.
Una vez entramos en la pantalla de navegación, manteniendo pulsado el botón izquierdo del ratón sobre ella, teneis dos opciones: mover el ratón de arriba a abajo, con lo que lograreis acercaros o alejaros de la escena, o moverlo lateralmente, que intenta crear el efecto de girar la cabeza a uno y otro lado. Si en lugar del botón izquierdo pulsais el derecho, el efecto que lograis es de rotación; lo mejor es que lo experimenteis.
Existe un menú accesible al pinchar con el botón derecho sobre la pantalla, en el cual podeis configurar multitud de parámetros, como el tipo de representación: alámbrica, nube de puntos o sólida.
En ese menú, existen dos opciones interesantes en el apartado Navigation, que son Animate to clicked point, que nos permite avanzar automaticamente hacia el punto de un objeto sobre el que pinchemos, y Collision detection que como su nombre indica, detecta cuando chocamos con un objeto, impidiendonos atravesarlo.
Por último, daré un truco, para cuando esteis perdidos en la escena y no sepais volver al origen: la primera opción del menú View points, sirve para almacenar puntos de vista, pero si no habeis almacenado ninguno, tiene el Entry view, con lo que conseguireis volver al punto de vista inicial.

Cualquier punto en el espacio, viene definido por sus coordenas (x,y,z).

Pero un objeto representado solo por unos puntos, no seria muy real, por lo que en primera instancia, se recurre a la representación alámbrica, que no es otra cosa que unir parejas de puntos con una linea, de manera que nos de una idea más clara del objeto que representamos. Aunque mejora mucho, todavia no es muy buena representación puesto que se pueden producir ambiguedades, al no saber exactamente que lado del objeto miramos, por ser este transparente.

Por último, vamos ha hacer una mejora sustancial de nuestra representación, al añadir caras sólidas al objeto, que ya no deja ver a traves de ellas, con lo que el problema de ambiguedad en la interpretación del objeto se acaba. En total, para representar al objeto, necesitamos tener información sobre que puntos del espacio lo representan y en que orden deben unirse para formar las caras (opcionalmente puede almacenarse la información de las aristas, pero no es obligado).

#VRML V1.0 asciiEs obligatorio, anuque cualquier linea que comienza con "#" se interpreta como un comentario.
Muy muy , VRML es case sensitive, que en cristiano significa que, al contrario que HTML, él si diferencia entre mayúsculas y minúsculas.
Este es un lenguaje en el que no se usan muchos caracteres extraños, tan solo necesitareis para este curso los corchetes"[ ]" y las llaves "{ }", o sea que si pretendeis escribir algo, ya podeis localizarlas en vuestro teclado. Tampoco tendreis estructuras de control como en los lenguajes de programación tradicionales, de hecho VRML no es un lenguaje normal, tan solo es un lenguaje para definir la apariencia de un mundo virtual, creado por vosotros. Esto se ve claro si extendemos sus siglas Virtual Reality Modeling Lenguage, con lo que queda claro, que en su versión 1.0 que es la que nos interesa, es un lenguaje para Modelar, no para Programar en el sentido tradicional.
Nodos
Cada orden de VRML se
denomina nodo y viene seguida por una serie de parámetros entre llaves,
como por ejemplo Sphere{}, que crea una esfera como veremos en los
ejemplos de primitivas.
Superposición
Una característica
importante de VRML es la superposición de objetos. En esencia tiene el
mismo efecto que una suma booleana, pero solo aparentemente, puesto que esta no
se realiza en realidad. Lo único que pasa es que se superponen varios objetos y
se visualizan las partes de estos que sobresalen dando al exterior respecto de
los otros. No tiene ningún nodo asociado, simplemente debemos situar los
objetos en los lugares correspondientes y comprobar que el resultado es el
esperado.
Situación en el navegador
Cuando
por primera vez entramos al visualizador VRML, los ejes están dispuestos con la
componente Y apuntando hacia arriba, la X hacia la derecha y la Z hacia el
observador, siendo el origen de coordenadas el centro de la pantalla. Esto es
importante para que se puedan comprender las transformaciones realizadas en los
ejemplos. Además, todas las primitivas se insertan respecto de estos ejes
situándose centradas sobre ellos, por lo que si insertamos un cilindro de altura
dos en el origen y queremos situarnos en su parte superior, deberemos realizar
una traslación respecto del eje Y de una, y no dos unidades.
Todos los parámetros que definen estas primitivas, pueden ser definidos por nosotros, pero si no especificamos ninguno, el navegador da unas dimensiones por defecto.Cubo.
Cilindro.
Cono.
Esfera.
Cada uno de los nodos que nos premite crear una primitiva tiene unos parámetros diferentes:
Cube {
width (anchura)
height (altura)
depth (profundidad)
}
Sphere {
radius (radio)
}
Cone {
parts ALL|SIDES|BOTTOM
bottomRadius (radio)
height (altura)
}
Cylinder {
parts ALL|SIDES|BOTTOM|TOP
radius (radio)
height (altura)
}
#VRML V1.0 ascii
Cube {} |
Con este sencillo ejemplo, cramos un Cubo con las dimensiones por defecto que le de el navegador. |
#VRML V1.0 ascii
Cylinder {} |
En este, cramos un Cilindro.. |
#VRML V1.0 ascii
Cone {} |
Un Cono. |
#VRML V1.0 ascii
Sphere {} |
Y ahora una Esfera. |
|
|
Todas las partes del cono o cilindro serán visibles. |
|
|
Se verán los laterales del cono o cilindro. |
|
|
Se verá la base del cono o cilindro. |
|
|
Se verá la parte superior del cilindro. |
#VRML V1.0 ascii
Cylinder {
parts SIDES
radius 5
height 10
}Si os desplazais por el
cilindro, comprobareis que se han retirado las tapas, pero también comprobareis
probablemente que las caras posteriores del cilindro no se pueden ver hasta que
no le damos totalmente la vuelta. No hay ningún error, es un método de acelerar
el Render del objeto en pantalla denominado Backface Culling, por
el que las caras que no son visibles no se dibujan y vuestro navegador no se ha
percatado de que ahora sí que debe dibujar esas caras, puesto que hemos retirado
las tapas del cilindro. Algunos se dan cuenta de esto y las dibujan, pero otros
no.
AsciiText{}
Además de
estas primitivas, también podemos introducir texto en 3D, para lo tendremos que
usar el nodo AsciiText{} que aparece a continuación:
AsciiText {
string "cadena"
spacing 1
justification LEFT|CENTER|RIGHT
width 0
}Este nodo
permite introducir texto del juego de caracteres ASCII mediante su parámetro
string (siempre entre comillas) y permite ralizar ajustes al mismo, en
función de los valores que demos a sus parámetros. Con spacing
indicaremos al visualizador que las sucesivas cadenas que se escriban serán
separadas con uns distancia definida por el producto size*spacing.
Para ver el significado de size debereis mirar en los parámetros del
nodo FontStile{}.
La justificación del texto respecto de su punto de inserción la indica el
parámetro justification, ya os podeis imaginar cual es el significado de
sus valores. En cuanto al parámetro width, nos permite sugerir al
visualizador la anchura que deseamos para cada cadena. A continuación podeis ver
un sencillo ejemplo.
de lo que decia. #VRML V1.0 ascii
AsciiText {
string "Esto es un texto en 3D"
}Además de todo esto,
podeis situar el texto como si se tratara de un objeto más del entorno,
cambiarle el color e incluso aplicarle texturas.
FontStyle{}
Con este nodo se puede seleccionar el tipo de fuente que deseamos
para nuestros textos en 3D y su sistaxis es:
FontStyle {
size 1
family SERIF|SANS|TYPEWRITER
style NONE|BOLD|ITALIC
}Con el parámetro
size podemos determinar la altura y el espaciado vertical de las lineas
de texto adyacentes. Mediante family podemos elegir el tipo de fuente
entre las tres disponibles que son SERIF (similar a TimesRoman), SANS
(como Helvetica) y TYPEWRITER con espaciado constante como
Courier. Por último podemos indicar el estilo de la fuente con
style escribiendo BOLD para el texto en negrita e ITALIC para
texto en itálica. Si el navegador lo soporta, podremos combinar estos
últimos para especificar texto en negrita e itálica como en el
caso de las partes de una
primitiva.
#VRML V1.0 ascii
DEF BackgroundColor Info {string "0.15 0.6 0.7"}
Material {
#ambientColor 0 0 0
diffuseColor 1 0 0
#specularColor 0 0 0
#emissiveColor 0 0 0
#shininess 0
#transparency 0
}
Sphere {}Todos los valores numéricos son en coma flotante dentro del rango de 0 a 1. Para entenderlos, sería de gran utilidad conocer el modelo de iluminación de Phong, puesto que excepto transparency que indica el grado de transparencia del objeto y emissiveColor que especifica el color con que va a brillar en la oscuridad , los otros parámetros son similares a los de dicho modelo. En concreto, ambientColor, nos permite indicar el color del objeto frente a la luz ambiental de la escena por lo que va a actuar sobre las partes de dicho objeto no iluminadas directamente por luces, pero solo en el caso de que especifiquemos alguna luz distinta de la que sale por defecto y que está situada sobre la cabeza del observador aproximadamente. Con diffuseColor, especificamos lo que definiríamos como el color normal del objeto (reflexión difusa) y con specularColor podemos especificar el color de la luz reflejada por él (reflexión especular). El parámetro shininess sirve para indicar el nivel de brillo de la superficie. Cuando nos metamos con el tema del posicionamiento de luces, volveremos sobre esto. Por supuesto, no es necesario especificar todos los parámetros del nodo Material{}, lo normal será usar solo ambientColor y diffuseColor. Si usáis transparency, tened en cuenta que algunos visualizadores antiguos no lo implementan, por lo que no afectará al resultado final.
Formato RGB
Los
colores se especifican en formato RGB, es decir, mediante sus componentes de
color rojo (Red), verde (Green) y azul (Blue). En VRML, se
escriben con tres números reales con un rango entre 0 y 1 ambos inclusive (el
intervalo cerrado [0..1] para los más matemáticos). Es posible que en algún
sitio hayais visto este mismo método, pero usando numeros enteros con el rango
de 0 a 255 (un BYTE por componente de color en TrueColor), para
poder convertir esos colores al formato VRML, tan solo teneis que dividir cada
componente por 256.
Los campos del nodo Material{} que sirven para especificar un color, tienen tres apartados cada uno como podeis ver en el ejemplo superior. Cada apartado sirve para especificar un color básico o componente del color final en el orden RGB, o sea, primero especificaremos el rojo, luego el verde y por último el azul.
Color de fondo
Para
especificar el color de fondo, hemos usado la expresión DEF BackgroundColor
Info {string "0.15 0.6 0.7"}. El color viene indicado por la cadena que
aparece dentro del nodo Info{}, 0.15 para el rojo, 0.6 para el verde y
0.7 para el azul. Por ahora, con esto hay bastante. El significado del nodo
Info{} el operador DEF y el resto de cosas nuevas ya se verá más
adelante.
Separator { definición de objetos y propiedades }En
el ejemplo de las traslaciones, podreis ver más en detalle como actua este
nodo independizando cada una de las esferas del ejemplo de las otras.
Por supuesto, pueden anidarse (ponerse unos dentro de otros) varios nodos Separator{} sin ningún problema.
Ademas de este, existen otros nodos de agrupamiento como Group{}, pero no tienen tanta importancia como este y por ahora pasaré de incluirlos en el curso, cuando tenga un rato ya los añadiré.
En cualquier entorno de programación 3D, existen tres transformaciones básica, que son:
La translación, nos permite mover o trasladar un objeto por el espacio 3D. La rotación por su parte, nos permite rotar el objeto respecto de los ejes X, Y o Z un determinado número de radianes (radianes = grados *2*3.1416 /360). Por último, el escalado, nos permite introducir un factor de escala en cada uno de los ejes X, Y, Z, para estirar o encoger el objeto respecto de esos ejes independientemente uno de otro.Translación.
Rotación.
Escalado.
Traslaciones
En este ejemplo veremos una
esfera gris que está en el origen de coordenadas (0,0,0) y tres más que son esa
misma esfera pero translada en alguno de los ejes:
#VRML V1.0 ascii
Separator{
Material {emissiveColor 0.7 0.7 0.7}
Translation {translation 0 0 0}
Sphere {}
}
Separator{
Material {emissiveColor 1 0 0}
Translation {translation 5 0 0}
Sphere {}
}
Separator{
Material {emissiveColor 0 1 0}
Translation {translation -5 0 0}
Sphere {}
}
Separator{
Material {emissiveColor 0 0 1}
Translation {translation 0 5 0}
Sphere {}
}Para especificar la
translación, hemos usado Translation{translation X Y Z }, donde se
observa claramente que las traslaciones en cada uno de los ejes deben
especificarse respectivamente en la X, Y o Z, pudiendo, por supuesto,
especificar varios ejes a la vez.
Rotaciones
El caso
de las rotaciones es un poco más complicado de comprender y de explicar, pero no
mucho más. Las rotaciones, se especifican respecto de un eje formado por el
origen de coordenadas (0, 0, 0) y una posición (X, Y, Z) en el espacio 3D, entre
las que se establece un vector que será el eje de rotación anteriormente
comentado. El metodo básico es muy simple: se usa la instrucción
Rotation{rotation X Y Z rad } donde los valores X, Y o Z pueden ser
cualquier número real y el valor de rad corresponde al ángulo en radianes
que deseemos rotar. Si deseamos realizar la rotación respecto de uno de los ejes
de coordenadas X, Y o Z, nos bastará con poner en su posición un valor numérico
cualquiera y dejar los correspondientes a los otros dos ejes a 0. Lo veremos más
claro con un ejemplo:
#VRML V1.0 ascii
Separator{
Material {emissiveColor 0.7 0.7 0.7}
Translation {translation -4.5 0 0}
Rotation {rotation 0 0 0 0}
Cube {}
}
Separator{
Material {emissiveColor 1 0 0}
Translation {translation -1.5 0 0}
Rotation {rotation 1 0 0 1.57}
Cube {}
}
Separator{
Material {emissiveColor 0 1 0}
Translation {translation 1.5 0 0}
Rotation {rotation 0 1 0 1.57}
Cube {}
}
Separator{
Material {emissiveColor 0 0 1}
Translation {translation 4.5 0 0}
Rotation {rotation 0 0 1 1.57}
Cube {}
}Este ejemplo, se ha
complicado un poco, pero es muy interesante porque en el se combinan dos
transformaciones, la traslación y la rotación. Antes de rotar cada uno de los
cubos, lo movemos para que no se amontonen unos encima de otros como podeis
comprobar si eliminais las translaciones. Pero lo más curioso es que no
da lo mismo transladar primero y luego rotar que al reves. La explicación es
sencilla: las translaciones y rotaciones, se realizan sobre unos ejes, y existen
unos ejes para cada objeto, es decir, cuando trasladamos una esfera, la
trasladamos respecto de ella misma, de su posicion anterior. Cuando transladamos
un objeto lo trasladamos a él y a sus ejes particulares. Lo mismo pero más
grave, ocurre con las rotaciones, cuando rotamos un objeto, lo rotamos respecto
de sus ejes actuales, pero también rotamos sus ejes. Esto último podeis
comprobarlo si rotais primero y transladais después en el ejemplo.
Escalados
El
escalado no tiene muchas complicaciones. Se trata de estirar o encoger un objeto
por cada uno de sus ejes. Se consigue con la orden Scale{ scaleFactor X Y Z
}, donde X, Y y Z son valores mayores que 0. Estos valores, multiplican las
coordenadas correspondientes de los puntos del objeto, por lo que un valor de
0.5 reducirá a la mitad el objeto en el eje al que se aplique y un valor de 1.5
lo aumentara en un 50%. Pueden aplicarse a la vez todos los escalados sin ningún
tipo de problema. En el ejemplo siguiente,
veremos esto con más claridad:
#VRML V1.0 ascii
Separator{
Material {emissiveColor 0.7 0.7 0.7}
Translation {translation -4.5 0 0}
Scale {scalefactor 1 1 1}
Cylinder {}
}
Separator{
Material {emissiveColor 1 0 0}
Translation {translation -1.5 0 0}
Scale {scalefactor 1 1 1.5}
Cylinder {}
}
Separator{
Material {emissiveColor 0 1 0}
Translation {translation 1.5 0 0}
Scale {scalefactor 1 0.5 1}
Cylinder {}
}
Separator{
Material {emissiveColor 0 0 1}
Translation {translation 4.5 0 0}
Scale {scalefactor 1.5 1 0.5}
Cylinder {}
}
Translation {translation 1.5 0 0}
Transform {translation 1.5 0 0}
Scale {scaleFactor 1.5 1 1}
Trasnform {scaleFactor 1.5 1 1} |
En este caso, los dos pares de expresiones son equivalentes, ambas especifican una traslación o un escalado en el eje X de 1.5 . |
Transform
{
translation 4.5 0 0
rotation 1 1 0 3.14
translation 0 0 1
} |
Ahora, lo que hemos hecho es agrupar dentro de un solo nodo Transform{} varias transformaciones. |
Para poder usar estos tres tipos de luces, VRML incorpora tres nuevos nodos:Infinitas o direccionales, cuyo foco emisor se supone que se encuentra a una distancia lo suficientemente alejada de la escena que ilumina como para suponer que esta en el infinito. Con esto se consigue una simplificación, que es la de poder considerar todos los rayos de luz incidentes como paralelos entre si. Un claro ejemplo de este tipo de luces es la del sol que incide sobre la tierra, cuyos rayos son prácticamente paralelos entre si. Solo necesitan un vector para caracterizarlas, expresado normalmente con un punto respecto del origen de coordenadas.
Puntuales, las cuales vienen caracterizadas por un punto del espacio en el cual se sitúan y desde el que emiten luz en todas direcciones. Un ejemplo de este tipo de luces sería una bombilla, la cual está en un lugar determinado de la escena y emite su luz desde ese lugar hacia toda la escena. En el límite, si situásemos una luz de este tipo a una distancia lo suficientemente alejada de la escena, podríamos considerarla como una luz infinita.
Focales, con las que podremos crear efectos como los de enfocar una fuente de luz sobre un objeto determinado. Este tipo de luces viene caracterizado por dos puntos en el espacio en lugar de uno solo como en las dos anteriores. El primero de ellos indica la posición en la que se encuentra situada la fuente de luz y el segundo determina la dirección y el sentido de la luz o dicho de otra forma, hacia donde esta enfocada. Puede considerarse este tipo de luz como algo similar a una linterna que permite dirigir la luz hacia un lugar determinado de la escena.
Además de los parámetros comentados, podréis ver tres más que no he mencionado que son comunes a los tres nodos y son on, que es booleano y por tanto puede tomar los valores de TRUE o FALSE para poder desactivar una luz sin necesidad de eliminar su código de la escena. Tambiién tenemos intensity, que mediante un numero real con un rango entre 0.0 y 1.0 nos va ha permitir especificar la intensidad de la luz a la que pertenezca y por último y no por ello miserablemente despreciado, encontramos color, el cual nos va a permitir especificar en formato RGB el color de la luz emitida por nuestra fuente de la misma manera que en el número pasado especificábamos el color de un objeto.DirectionalLight{}, mediante el que podemos especificar luces infinitas usando el parámetro direction, que contiene las coordenadas de un punto, el cual junto con el origen actual de coordenadas define un vector mediante el que especificaremos el sentido de todos los rayos de luz emitidos por esta luz.
DirectionalLight { on TRUE intensity 1 color 1 1 1 direction 0 0 -1 }PointLight{}, que nos va a permitir modelar las luces de tipo puntual, situándolas en el lugar del espacio especificado por medio del parámetro location y que emitirá sus rayos en todas direcciones a partir de él, por lo que no necesita mas parámetros.
PointLight { on TRUE intensity 1 color 1 1 1 location 0 0 1 }SpotLight{}, el cual nos proporciona el nodo más complejo de todos para poder modelar una luz de tipo focal. En este tipo de luces, tenemos dos puntos a definir, los cuales definirán un vector que apuntara hacia el objeto o parte de la escena a iluminar. Mediante el parámetro location, especificamos la posición de la luz en la escena y mediante el parámetro direction lo que especificamos es hacia donde enfocamos la luz que hemos situado mediante el anterior parámetro. Podéis comprobar que este nodo es un poco más complejo que los otros, al aparecer dos parámetros nuevos que son cutOffAngle mediante el que podemos especificar la amplitud del cono de iluminación de este tipo de luces (imaginad una linterna) y dropOffRate que nos va ha permitir definir mediante un número real la velocidad de caída de la luz hacia los bordes de su cono de iluminación.
SpotLight { on TRUE intensity 1 color 1 1 1 location 0 0 1 direction 0 0 -1 dropOffRate 0 cutOffAngle 0.785398 }
#VRML V1.0 ascii
Separator
{
DirectionalLight {
on TRUE
intensity 0.8
direction 0 -1 0
}
Material{diffuseColor 1 0 0}
Transform{translation 0 1.5 0}
Sphere{}
}
Separator
{
DirectionalLight {
on FALSE
intensity 0.8
direction -1 1 0
}
Material{diffuseColor 0 1 0}
Transform{translation 1.5 -1.5 0}
Sphere{}
}
Separator
{
DirectionalLight {
on TRUE
intensity 0.8
direction 1 1 0
}
Material{diffuseColor 0 0 1}
Transform{translation -1.5 -1.5 0}
Sphere{}
} |
En la imagen del ejemplo, podemos comprobar que una de las tres luces está desactivada y según el visualizador usado vereis individualizada o no la luz de cada nodo Separator{} con su esfera. Probad a encender y apagar las luces con el parámetro on, pero no intentéis probar muchas más cosas porque en el momento de escribir esta parte del curso no funcionan sobre Cosmo Player ni sobre Live3D que son los PlugIn's más comunes. |
#VRML V1.0 ascii
Separator {
Texture2 {
filename "textura1.jpg"
#image 0 0 0
#wrapS REPEAT
#wrapT REPEAT
}
Sphere{}
} |
![]() |
El parámetro filename es el que contiene el nombre de la textura, el cual puede ser desde luego una URL. El siguiente parámetro que encontramos es image, que nos permitirá crearnos una trama de bits para usarla como textura, pero como no es muy útil, simplemete la ignoraré. Después de estos, encontramos wrapS y wrapT los cuales hacen referencia a la manera de extender la textura en sus dos ejes por la superficie del objeto. Para comprenderlos mejor se debería conocer realmente como se produce el mapeo de una textura sobre una superficie, cosa que se escapa al interés y espacio de este curso (los Kbytes son los Kbytes...). Los valores que pueden tomar estos parámetros son:
Ahora, vamos a ver como se extiende una textura sobre cada una de las primitivas que conocemos:REPEAT, que permite repetir la textura fuera del rango de coordenadas de textura normal entre 0 y 1. Dejad normalmente esta opción o no las especifiquéis.
CLAMP, que fuerza a que las coordenadas de la textura entren en el rango de 0 a 1. Estas coordenadas representan las dos dimensiones del gráfico a mapear sobre las tres del objeto VRML.
En el caso de la proyección esférica, es conveniente dejar unos ribetes en los bordes superior e inferior sin dibujo en el gráfico de textura para evitar distorsiones al aplicarla.Cube{}- Sobre esta, la textura se extiende de manera plana en cada una de las caras del paralelepípedo, la proyección usada es una planar normal y corriente.
Cone{}- En este caso cambian las proyecciones, en la base se extiende de una manera similar a como lo realizaba sobre el cubo, pero sobre las caras laterales lo hace "enrollándose", o más técnicamente, mediante una proyección cilíndrica.
Cylinder{}- Es muy similar a la anterior, en las dos tapas del cilindro se realiza una proyección plana de la textura y en las caras laterales se vuelve a proyectar de manera cilíndrica, pero en este caso el resultado no distorsiona tanto el gráfico como en el caso del cono.
Sphere{}- Para la esfera, se usa la proyección esférica (que original...), que consiste en recubrir esta como si juntásemos el borde superior de la textura en el polo superior de la esfera, el inferior en el polo inferior y después tratásemos de cubrir la esfera estirando la textura. Veremos más claro todo esto en los ejemplos.
Para mayor claridad, la textura que se va a utilizar es una foto y no una autorrepetitiva, con lo que se apreciarán mejor los tipos de proyección y los efectos o deformaciones que provocan las proyecciones sobre la imagen.
#VRML V1.0 ascii
Separator {
Texture2 {
filename "Xw-Tie.jpg"
}
Cube{}
Cylinder{}
Cone{}
Sphere{}
} |
![]() |
Texture2Transform{}- Mediante este nodo podemos asociar una serie de transformaciones a una textura de la misma manera que hacíamos sobre un objeto 3D, pero teniendo en cuenta que en este caso, la imagen es una superficie con solo dos dimensiones, por lo que solo usaremos dos valores en cada transformación, uno para cada eje de coordenadas de textura.
Texture2Transform { translation 0 0 rotation 0 scaleFactor 1 1 center 0 0 }Como podéis ver, tenemos básicamente las mismas transformaciones que en el caso del nodo Transform{} pero sobre dos ejes. Las traslaciones se asocian al parámetro translation, las rotaciones al parámetro rotation (en radianes, claro...) y el escalado no uniforme al parámetro scaleFactor. Los casos del escalado y la rotación, deben realizarse respecto de un punto de la textura, el cual viene determinado por el último de los parámetros, center , que especifica el punto del mapa de textura sobre el que se realizarán dichas transformaciones. Los valores van en el rango de 0 a 1 como todos los referidos a las texturas, puesto que se asume que tanto el eje horizontal denominado S como el vertical denominado T, tienen una dimensión de una unidad, independientemente del tamaño en pixels de la textura. Como en otros nodos, pueden omitirse los parámetros que no deseemos usar.De la misma forma que en el nodo Transform{}, las diversas transformaciones se acumulan sucesivamente en una única matriz de transformación, en nuestro caso también se obtiene una única matriz, la cual se aplicará sucesivamente a todos lo objetos que queden dentro de su radio de acción (refrescad el uso del nodo Separator{}). El orden en que se evalúan las transformaciones a acumular en la matriz es: escalado-> rotación-> traslación en el caso de que se especifiquen todas.
#VRML V1.0 ascii Separator { Texture2Trasform { sin transformar translation 0.5 0 rotation 0.785 scaleFactor 1.5 1 } Texture2 { filename"caballo.jpg" } Cube{} }Selecciona una de las tres transformaciones a aplicar a esta textura sobre un cubo
TextureCoordinate2{}- Existe un segundo nodo asociado a estos menesteres que es el que da nombre a este apartado. Define una serie de coordenadas que se usarán para mapear texturas en los objetos definidos mediante los nodos PointSet{}, IndexedLineSet{} o IndexedFaceSet{}, mediante el que se reemplazan los vértices actuales del objeto definido a efectos de texturado y que tiene el siguiente formato:
TextureCoordinate2 { point 0 0 }Las coordenadas de textura que podemos introducir en él, nos permitirán crear algunos efectos interesantes, pero para ver esto, necesitaremos primero saber como funcionan los tres nodos anteriores, que son los que nos van a permitir explotar las verdaderas capacidades del VRML, puesto que hasta ahora nos habíamos limitado a crear objetos predefinidos mediante las primitivas que proporciona el lenguaje, lo cual es a todas luces muy limitado. Con estos nuevos nodos podremos crear cualquier escena que se nos ocurra (tampoco os paseis...), y si tenemos el programa adecuado, importar diseños de 3D Studio o similares a formato VRML
Para aplicar texturas a objetos creados mediante la enumeración de sus caras y/o vértices en nodos como IndexedFaceSet{}, se presentan problemas más complejos que los vistos hasta ahora, pero primero tendremos que ver la manera de usar estos nuevos nodos para definir nuestros objetos en la siguiente entrega de este manual, que estoy realizando en mis ratos libres.
Si teneis alguna aportación constructiva al curso, quereis preguntarme algo, o pedirme que me extienda más en alguna cosa, no os corteis y decidlo.
Ya que habeis leido el curso de VRML, no olvideis pasar por mi Museo virtual.
Si quereis una versión en ZIP para verlo tranquilamente desconectados y que además esté preparada para ser imprimida, pinchad aquí, solo son 56KB.
Para que esteis al día de las actualizaciones del curso, mandadme un correo indicando que quereis que os avise de los cambios y mejoras.