6.8.3  Densidad

Las partículas de media se distribuyen normalmente con densidad constante por todo el medio. Sin embargo, la sentencia density permite modificar la densidad en el espacio, utilizando cualquiera de las funciones de patrón que tiene POV-Ray (las mismas que se usan en las texturas). Si no se especifica una sentencia density, la densidad permanece a un valor constante de 1.0 en todo el medio. Se puede declarar más de una sentencia density dentro de una sentencia media. Ver "Densidad múltiple frente a múltiples medios". La sintaxis para density es:

DENSIDAD:
    density
    {
        [IDENTIFICADOR_DENSIDAD]
        [TIPO_DENSIDAD]
        [MODIFICADOR_DENSIDAD...]
    }
TIPO_DENSIDAD:
    TIPO_PATRÓN | COLOR 
MODIFICADOR_DENSIDAD:
    MODIFICADOR_PATRÓN | LISTA_DENSIDAD | color_map { CUERPO_MAPA_COLOR } |
    colour_map { CUERPO_MAPA_COLOR } | density_map { CUERPO_MAPA_DENSIDAD }

La sentencia density puede comenzar con un identificador opcional de densidad. Los valores posteriores modifican los valores por defecto o los valores anteriores en el identificador. El siguiente elemento es de tipo patrón. Ésta es una de las funciones de patrón de POV-Ray como bozo, wood, gradient, waves, etc. Particularmente útiles son los patrones spherical, planar, cylindrical y boxed, los cuales sólo estaban antes disponibles para su uso con la ya desaparecida característica halo. Todos los patrones devuelven un valor entre 0.0 y 1.0. Este valor se interpreta como la densidad en el medio en un punto en particular. Ver "Patrones" para más detalles sobre algún tipo de patrón en particular. Aunque un patrón de COLOR sólido está permitido, en general se usa sólo cuando la sentencia density se encuentra dentro de un density_map.

6.8.3.1  Modificadores Generales de Densidad

Una sentencia density puede modificarse con alguno de los modificadores de patrón generales como las transformaciones, turbulence y warp. Ver "Modificadores de patrones" para más detalles. Además hay varios modificadores específicos de densidad que pueden ser usados.

6.8.3.2  Densidad con Mapas de Colores

Típicamente media utiliza un solo color constante en toda su extensión. Incluso si se cambia la densidad, normalmente sólo hay que especificar un color con los identificadores absorption, emission, o scattering. Sin embargo cuando se utiliza emission para simular fuego o explosiones, el centro de la llama (área de alta densidad) es típicamente más brillante, y blanco o amarillo. El borde exterior de la llama (menos densidad) se transforma gradualmente en naranja, rojo o, en algunos casos, azul oscuro. Para modelar este cambio dependiente de la densidad en el color visible, se debe especificar un color_map. La función del patrón devuelve un valor entre 0.0 y 1.0 y este valor se pasa al mapa de color para calcular qué color o mezcla de colores se usará. Ver "Mapas de Color" para conocer cómo se comportan los valores del patrón con un color_map.

Este color resultante se multiplica por el color de absorption, emission y scattering. Actualmente no hay forma de especificar diferentes mapas de color para cada tipo de medio dentro de la misma sentencia media.

Consideremos este ejemplo:

  media{
    emission 0.75
    scattering {1, 0.5}
    density { spherical
      color_map {
        [0.0 rgb <0,0,0.5>]
        [0.5 rgb <0.8, 0.8, 0.4>]
        [1.0 rgb <1,1,1>]
      }
    }
  }

Los rangos del mapa de color van desde el blanco en la densidad 1.0, al amarillo brillante en la densidad 0.5 y al azul oscuro en la densidad 0. Supongamos el muestreo de un punto a densidad 0.5. La emisión es 0.75*<0.8,0.8,0.4> o <0.6,0.6,0.3>. De igual forma el color de dispersión es 0.5*<0.8,0.8,0.4> o <0.4,0.4,0.2>.

Para patrones de tipo bloque como checker, hexagon, y brick se puede especificar una lista de color como ésta:

  density{
    checker 
    density {rgb<1,0,0>}
    density {rgb<0,0,0>}
  }

Ver "Patrones con listas de colores" donde se describe cómo utiliza pigment una lista de color. Los mismos principios se aplican cuando la utilizamos en density.

6.8.3.3  Mapas de Densidad y Listas de Densidad

Además de especificar mezclas de color con un mapa de color se puede crear una mezcla de densidades utilizando un density_map. La sintaxis para un mapa de densidad es idéntica a la de un mapa de color excepto en que se especifica una densidad en cada entrada del mapa (en vez de un color).

La sintaxis para un density_map es como sigue:

MAPA_DENSIDAD:
    density_map { CUERPO_MAPA_DENSIDAD }
CUERPO_MAPA_DENSIDAD:
    IDENTIFICADOR_MAPA_DENSIDAD | ENTRADA_MAPA_DENSIDAD...
ENTRADA_MAPA_DENSIDAD:
    [ Valor CUERPO_DENSIDAD ]

Donde Valor es un valor flotante entre 0.0 y 1.0 inclusive y cada CUERPO_DENSIDAD es cualquier cosa que pueda ir dentro de una sentencia density(...). No es necesario especificar el identificador density ni las llaves {}.

Nota: los corchetes [] son parte de la misma ENTRADA_MAPA_DENSIDAD. No son símbolos de notación indicando partes opcionales. Los corchetes encierran cada una de las entradas dentro del mapa de densidad.

Puede haber desde 2 a 256 entradas en el mapa.

Se pueden anidar los mapas de densidad hasta el nivel de complejidad que se desee. Las densidades en un mapa pueden tener mapas de color o mapas de densidad o cualquier tipo de densidad que se quiera.

Se pueden usar densidades completas con patrones de bloque tales como checker, hexagon y brick. Por ejemplo...

  density {
    checker
    density { Flame scale .8 }
    density { Fire scale .5 }
  }

Nota: en el caso de los bloques de patrón la información relativa a density debe estar encerrada entre llaves.

También se utiliza un mapa de densidad con el tipo de densidad average. Ver "Average" para más detalles.

Se pueden declarar y usar identificadores de mapa de densidad pero la única forma de declarar una lista de bloques de patrón es declarar un identificador de densidad para la totalidad de la densidad.

6.8.3.4  Múltiples Densidades frente a Múltiples Medios

Se puede especificar más de un media por objeto, y es legal tener más de un density por media. Los efectos son bastante diferentes. Consideremos este ejemplo:

  object {
    MiObjeto
    pigment { rgbf 1 }
    interior {
      media {
        density { Una_densidad }
        density { Otra_densidad }
      }
    }
  }

Mientras el medio se muestrea, se realizan cálculos para cada patrón de densidad en cada punto de muestreo. Los muestreos resultantes para cada patrón de densidad se multiplican entre ellos. Supongamos que se devuelve una densidad de rgb<.8,.8,.4> y otra de <.25,.25,.0>. El color resultante es <.2,.2,0>.

Nota: en áreas en las que la densidad devuelve cero, la otra densidad quedará eliminada. El resultado final es que sólo las áreas de densidad que se solapan serán visibles. Esto funciona de forma parecida a la operación CSG de intersección.

Ahora consideremos el siguiente ejemplo:

  object { 
    MiObjeto
    pigment { rgbf 1 }
    interior {
      media {
        density { Una_densidad }
      }
      media {
        density { Otra_densidad }
      }
    }
  }

En este caso cada medio se computa de forma independiente. Los colores resultantes se suman unos a otros. Supongamos que se devuelven una densidad y un medio de <.8,.8,.4> por un lado y de <.25,.25,.0> por otro. El color resultante es rgb<1.05,1.05,.4>. El resultado final es que las áreas de densidad que se solapan serán especialmente brillantes y todas las áreas serán visibles. Esto funciona de forma parecida a la operación de CSG union. En la escena de muestra scenes\interior\media\media4.pov se puede encontrar un ejemplo que lo ilustra.