.. _json-desc-format: Model objects ************* Planets, moons, asteroids, etc. all use the model component ``Model`` (`Model `__), together with the ``ModelComponent`` record (`ModelComponent `__). These provide a series of utilities that make their JSON specifications look similar. .. _rotation: .. _orientation: Orientation =========== Orientations in Gaia Sky may be given in two different formats: - :ref:`Rigid rotation ` -- the orientation is described with basic rotation parameters such as the period, inclination, axial tilt, etc. - :ref:`Quaternion orientation ` -- the orientation of the object is sourced from an entity that provides quaternions. .. _rigid-rotation: **Rigid rotation** The ``rigidRotation`` map (aliased to ``rotation``) describes, as you may imagine, the rigid rotation of the body in question by means of a series of parameters. Rotations are stored in the :ref:`Orientation component `, and use the ``rigidRotation`` map. A rigid rotation is described by the following parameters: - ``period`` -- The rotation period in hours. Negative for retrograde bodies. - ``pole`` -- The rotation pole as ``[right ascension, declination]``, in degrees in the equatorial frame of J2000. When present, the body is oriented straight from it and ``axialTilt``, ``inclination`` and ``ascendingNode`` are ignored. See :ref:`the rotation pole `. - ``axialTilt`` -- The axial tilt is the angle between the equatorial plane of the body and its orbital plane. In degrees. Ignored when ``pole`` is given. - ``inclination`` -- The inclination is the angle between the orbital plane and the ecliptic. In degrees. Ignored when ``pole`` is given. - ``ascendingNode`` -- The ascending node in degrees. Ignored when ``pole`` is given. - ``meridianAngle`` -- The meridian angle in degrees. - ``angularVelocity`` -- The angular velocity in degrees/hour. .. _rigid-rotation-pole: **Rotation pole** .. raw:: html
Since 3.10.0
A body may give its rotation pole directly, as the right ascension and declination of its north pole in the equatorial frame of J2000, which is the form the IAU publishes. The orientation is then built from the pole with the same construction the :ref:`orbital reference planes ` use, so the equator the body is drawn with is the plane its satellites refer to. This replaces the chain of ascending node, reference plane and axial tilt, which can reach any axis but only by storing numbers that no longer mean anything: Saturn would need an axial tilt of :math:`-14.5` degrees instead of its :math:`26.7` degree obliquity, and a retrograde body would be given the opposite pole and a positive period, so the data would not carry the pole that was actually published for it. The pole carries the sense of the rotation: a retrograde body keeps its real north pole and gets a negative ``period``. Bodies without a pole keep the old chain, and both the ``meridianAngle`` and the ``angularVelocity`` work the same in either case. For instance, the rotation of Mars and of Venus, with the pole of the latter pointing almost to the north ecliptic pole and its period negative: .. code:: json { "rigidRotation": { "pole" : [317.681, 52.887], "period" : 24.622962156, "meridianAngle" : 155.132 } } .. code:: json { "rigidRotation": { "pole" : [272.76, 67.16], "period" : -5832.443616, "meridianAngle" : 321.335 } } .. _quaternion-orientation: **Quaternion orientation** Some objects like satellites are typically oriented using quaternions. Since every satellite may have its own attitude analytical implementation, we support a generic way of providing quaternions, based on the orientation provider and source. The orientation provider contains the name of a class that extends `OrientationServer `__. We provide two general implementations, based on the spherical linear interpolation of quaternions (`QuaternionSlerpOrientationServer `__) and on normalized linear interpolation (`QuaternionNlerpOrientationServer `__. These implementations read the quaternion data from a CSV file in the following format: .. code:: text time-iso-8601,x,y,z,w For example, a valid quaternion slerp file would be ``quaternions.csv``: .. code:: text #time,x,y,z,w 2020-01-01T12:00:00Z,0.0,0.0,0.0,1.0 2020-02-01T12:00:00Z,1.0,0.0,0.0,0.0 2020-03-01T12:00:00Z,0.0,1.0,0.0,0.0 2020-04-01T12:00:00Z,0.0,0.0,1.0,0.0 2020-05-01T12:00:00Z,0.0,0.0,0.0,1.0 Each line contains: - **Time [ISO-8601]** -- the time of the quaternion. - **x** -- x component. - **y** -- y component. - **z** -- z component. - **w** -- w component. Once we have the file, we can use it in our object by using the :ref:`comp-orientation` properties ``orientationProvider`` and ``orientationSource``. .. code:: json { "orientationProvider": "gaiasky.data.orientation.QuaternionSlerpOrientationServer", "orientationSource": "path/to/quaternions.csv" } We also offer a specific implementation of OrientationServer for Gaia in the form of the `GaiaAttitudeServer `__. .. _model: Model ===== This section describes the format to specify models, but omits the procedural generation attributes. These are documented in the :ref:`procedural generation section `. The model object describes the model which must be used to represent the entity. Models are described in the :ref:`Model component `, and can have two origins: - They may come from a **3D model file**. In this case, you just need to specify the file. .. code:: json { "model": { "args" : [true], "model" : "$data/default-data/models/gaia/gaia.g3db" } } - They may be **generated on the fly**. In this case, you need to specify the type of model, a series of parameters and the material. .. code:: json { "model": { "args" : [true], "type" : "sphere", "staticLight" : true, "useColor" : "false", "ambientLevel" : 0.5, "ambientColor" : [0.1, 0.3, 0.6, 1.0], "params" : { "quality" : 180, "diameter" : 1.0, "flip" : false }, "material" : { "diffuse" : "$data/default-data/tex/base/earth-day*.jpg", "diffuseCubemap" : "$data/default-data/tex/cubemap/earth-day*", "diffuseSVT" : { "location" : "$data/virtualtex-earth-diffuse/tex", "tileSize" : 1024 }, "specular" : "$data/default-data/tex/base/earth-specular*.jpg", "normal" : "$data/default-data/tex/base/earth-normal*.jpg", "emissive" : "$data/default-data/tex/base/earth-night*.jpg", "height" : "$data/default-data/tex/base/earth-height*.jpg", "heightScale" : 8.12, "reflection" : [ 1.0, 1.0, 0.0 ] } } - ``type`` -- the type of model. Possible values are ``sphere``, ``uvsphere``, ``icosphere``, ``cubesphere``, ``octahedronsphere``, ``plane``, ``patch``, ``surface``, ``billboard``, ``twofacedbillboard``, ``quad``, ``disc``, ``cylinder``, ``ring``, ``cone``, ``cube`` and ``box``. For a full list of types, check out `ModelType `__. - ``staticLight`` -- this attribute takes in a boolean (``true`` or ``false``) or a floating point number. If present, this disconnects the ambient light of this model from the global ambient level, **and** does not apply directional lighting to the model. If set to ``true``, the ambient level of this model is set to the default 0.6. Otherwise, it is set to the given floating-point value in [0,1]. - ``useColor`` -- a boolean that indicates that the object color (in the ``color`` attribute) is to be used as the model color. If this is true, the object color is set as a model diffuse color attribute. - ``ambientLevel`` -- a single floating-point value with the ambient light level (in [0,1]) to apply to this model. If present, the model is disconnected from the global ambient light setting. - ``ambientColor`` -- a 3- or 4-component color (RGB or RGBA) for the ambient light of this model. If present, the model is disconnected from the global ambient light setting. - ``params`` -- parameters of the model. Which parameters are accepted **depends on the type**: - ``sphere`` and ``uvsphere`` accept ``quality`` (the number of horizontal and vertical divisions). ``sphere`` also accepts ``oblateness``. - ``icosphere`` accepts ``recursion`` (the recursion level). - ``cubesphere`` and ``octahedronsphere`` accept ``divisions``. - ``plane``, ``patch``, ``surface``, ``billboard``, ``quad`` and ``cube`` accept ``divisionsu`` and ``divisionsv`` (plus ``width``/``height``, or ``size``). - ``disc``, ``cylinder``, ``cone``, ``ring``, ``box`` and ``cube`` accept ``diameter`` and, where meaningful, ``height``. - All types accept ``flip``, which indicates whether the normals should be flipped to face outwards. - The ``ring`` type also accepts ``innerradius`` and ``outerradius``. For a full list of parameters per type, check out `ModelCache `__. - ``material`` -- properties of the material, such as textures, reflections, elevation, etc. - ``diffuse`` -- the diffuse texture to use. - ``diffuseCubemap`` -- the location of the 6 sides of the diffuse cubemap to use. Takes precedence over ``diffuse``. The sides must be images with the ``_bk.jpg``, ``_ft.jpg``, ``_up.jpg``, ``_dn.jpg``, ``_rt.jpg``, ``_lf.jpg`` suffixes. The file formats can be JPG or PNG. Can be applied to all channels (specular, normal, emissive, height, metallic, roughness, etc.) More information on this can be found in the :ref:`cubemaps section `. - ``diffuseSVT`` -- an object with a ``location`` (path) and a ``tileSize`` (integer). Defines a diffuse virtual texture for this model. Can be applied to more channels. More information on this can be found in the :ref:`virtual textures section `. - ``specular`` -- the specular map to produce specular reflections. This attribute also accepts a specular index or a specular color (RGB). More than one can be specified. - ``normal`` -- normal map to produce extra detail in the lighting. - ``emissive`` -- emissive texture, color or value. For planets, this acts as the night texture, which is applied to the part of the model in the shade. This attribute also accepts an emissive color (RGB) and an emissive index. - ``height`` -- height map which will be represented with tessellation or parallax mapping (see :ref:`elevation (height) `) and whose scale is defined in ``heightScale`` (in Km). - ``heightScale`` -- indicates the extent, in Km, of the top mapping value in the height map (corresponding to full white, or RGB [1,1,1]). When the elevation multiplier slider is set to 1, the highest point in the height map is displaced by this amount of kilometers. - ``roughness`` -- roughness texture, color or value for the PBR shader. - ``metallic`` -- metallic texture or value for the PBR shader. - ``ao`` -- ambient occlusion texture for the PBR shader. - ``diffuseScattering`` -- a color (vec[3]) or a single floating point number with the diffuse scattering value for this model. Diffuse scattering weighs the diffuse color and re-emits it if there are no shadows. - ``occlusionMetallicRoughness`` -- occlusion/metallic/roughness texture (in R, G and B channels respectively) texture for the PBR shader. Follows the glTF specification. - ``volume0``, ``volume1``, ``volume2``, ``volume3`` -- path to a 3D volume to ray-march inside this model. See :ref:`volumes ` and the :ref:`3D texture format <3d-texture-format>`. - ``volumeDepthThreshold`` -- array of densities, one per volume slot, above which a volume is allowed to occlude. See :ref:`volumes `. - ``reflection`` -- specifies an index or a color. If this is present, the default skymap will be used to generate reflections on the surface of the material. Hint: look up the ``Reflections`` object in Gaia Sky. It is defined in ``satellites.json``. - ``colorIfTexture`` -- if set to ``true``, the color specified in the object's ``color`` attribute is set to the material and mixed with the diffuse texture in the shader. If set to ``false``, the color is not used if a diffuse texture is already present. Defaults to ``false``. Additionally, we may use the following attributes for **ringed** models, also in the ``material`` group: - ``ringDiffuse`` -- diffuse texture for the ring. - ``ringNormal`` -- diffuse texture for the ring. - ``ringDiffuseScattering`` -- a color (vec[3]) or a single floating point number with the diffuse scattering value for this model. Diffuse scattering weighs the diffuse color and re-emits it if there are no shadows. .. _clouds: Clouds ====== This defines the clouds layer (see :ref:`Cloud component `). It can be :ref:`procedurally generated ` or described with textures. Here we deal only with the textures mode. Let's see: .. code:: json "cloud" : { "size" : 6395.0, "diffuseCubemap": "$data/default-data/tex/cubemap/earth-cloud*", "params" : { "quality" : 200, "diameter" : 2.0, "flip" : false } } Contains the ``size`` of the cloud model, its ``parameters`` (``quality``, ``diameter``, etc.) and the texture to use for the clouds. Clouds support only the diffuse channel, in any of its variations: - ``diffuse`` -- diffuse equirectangular texture path. - ``diffuseCubemap`` -- diffuse cubemap path. See :ref:`cubemaps `. - ``diffuseSVT`` -- diffuse Sparse Virtual Texture path. See :ref:`virtual textures `. The clouds are combined with the planet using the equation: .. math:: \bar{C}_{result} = \bar{C}_{source} \times \bar{F}_{source} + \bar{C}_{destination} \times \bar{F}_{destination} where :math:`\bar{F}_{source}` is 1, and :math:`\bar{F}_{destination}` is :math:`1 - \bar{C}_{source}`. .. raw:: html
Since 3.6.12
Additionally, it is possible to pull up-to-date clouds textures from online resources. For instance, the `live-cloud-maps `__ repository offers high-resolution almost-live (updated every 3 hours) cloud texture maps. To make use of those for the Earth object, you need to add the ``url`` parameter: .. code:: json "cloud": { "size": 6385.0, "url": "https://clouds.matteason.co.uk/images/8192x4096/clouds.jpg", "params": { "quality": 200, "diameter": 2.0, "flip": false } } Once this is done, Gaia Sky will attempt to pull the texture from the given URL and apply it as the cloud layer. If the ``url`` parameter is specified, it takes preference over the regular texture channels (``diffuse``, ``diffuseCubemap``, etc.) .. _atmospheric-parameters-description: .. _atmospheric-scattering: Atmospheric scattering parameters ================================= Planet atmospheres can also be defined using this object (see :ref:`Atmosphere component `). The ``atmosphere`` object gets a number of physical quantities that are fed in the atmospheric scattering algorithm (`Sean O'Neil, GPU Gems `__). .. code:: json { "atmosphere" : { "size" : 6600.0, "wavelengths" : [0.650, 0.570, 0.475], "m_Kr" : 0.0025, "m_Km" : 0.0015, "m_eSun" : 1.0, "fogdensity" : 2.5, "fogcolor" : [1.0, 0.7, 0.6], "o3OpticalDepth": 0.4, "params" : { "quality" : 180, "diameter" : 2.0, "flip" : true } } } The parameters are the following: - ``size`` -- radius of the sphere model used for the atmosphere, in km. - ``wavelengths`` -- the values of :math:`1\over{\lambda^4}` for the red (:math:`\lambda_0`), green (:math:`\lambda_1`) and blue (:math:`\lambda_2`) channels. These are the Rayleigh scattering rates of different light wavelengths. - ``m_Kr`` -- Rayleigh scattering constant. - ``m_Km`` -- Mie scattering constant. - ``m_eSun`` -- the brightness of the illuminating star. - ``fogdensity`` -- density of the simulated fog when inside the atmosphere. - ``fogcolor`` -- the color of the fog. - ``o3OpticalDepth`` -- strength of ozone (:math:`O_3`) absorption in the atmosphere. Set to 0 to disable it. (The old key ``o3strength`` is deprecated.) - ``mieAsymmetryG`` -- the asymmetry parameter of the Mie scattering phase function. - ``scaleDepth`` -- the scale height of the atmosphere, as a fraction of the planet radius. .. _mesh-objects: Mesh objects ============ Gaia Sky supports arbitrary galaxy-sized meshes. These are usually used to represent iso-density surfaces for stars, dust or HII regions, among others. Mesh objects have all the regular attributes of model bodies (``name``, ``description``, ``color``, ``size``, etc.). Additionally, we offer three shading modes for meshes: - ``additive`` -- renders the mesh with transparency via additive blending. The DR2 hot star and HII density meshes use this shading mode. - ``dust`` -- renders an opaque mesh. An opacity value is computed for the edges (:math:`V \cdot N`), where :math:`V` is the pixel view vector from the camera and :math:`N` is the normal vector at that pixel. Opacity is rendered using dithering to avoid sorting issues. - ``regular`` -- renders the mesh with the regular, general-purpose per-pixel lighting shader. The shading mode is set with the top-level attribute ``"shading" : "additive|dust|regular"``: .. code:: json { "name" : "DR3 star density", "description" : "Star density iso-surface based on DR3 data", "color" : [0.95, 0.2, 0.2, 0.75], "size" : 3.0856775814913705E7, "labelcolor" : [0.95, 0.1, 0.1, 1.0], "shading" : "regular", "labelposition" : [1000.0, 0.0, 0.0], "componentType" : "Meshes", "fadeout" : [60000.0, 90000.0], "parent" : "Universe", "archetype" : "MeshObject", "transformName" : "galacticToEquatorialF", "model" : { "args" : [true], "staticLight" : true, "model" : "$data/mesh-dr3-stardenstiy/meshes/dr3/star_density.obj" } } .. _volumes: Volumes ======= .. raw:: html
Since 3.9.0
Gaia Sky can render volumetric data by ray-marching a three-dimensional grid of voxels, instead of drawing it with particles or as an iso-surface. Volume objects use the :ref:`Volume ` archetype, which extends :ref:`ModelBody `, so they accept every regular attribute (``name``, ``color``, ``size``, ``coordinates``, ``fadeIn``/``fadeOut``, ``parent``, etc.) plus the volume-specific ones described below. Up to four volumes can be declared per object, and all of them are ray-marched and composited in a single pass. Here is the volumetric Milky Way of the default data pack: .. code:: json { "name": "Milky Way (volume)", "color": [1.0, 1.0, 1.0, 1.0], "sizePc": 26000.0, "componentType": "MilkyWay", "transformName": "galacticToEquatorial", "fadeIn": [1.0e3, 7.0e3], "fadeOut": [15e4, 60e4], "parent": "Milky Way", "archetype": "Volume", "label": false, "focusable": false, "cameraCollision": false, "vertexShader": "shader/pbr.vertex.glsl", "fragmentShader": "shader/volume.galaxy.fragment.glsl", "raymarchIterations": [50, 70, 90, 110], "coordinates": { "impl": "gaiasky.util.coord.StaticCoordinates", "transformName": "galToEqF", "positionPc": [0.0, 0.0, 0.0] }, "model": { "args": [true], "type": "sphere", "useColor": true, "blendMode": "additive", "params": { "flip": true, "diameter": 1.3, "quality": 30 }, "material": { "volume0": "$data/default-data/galaxy/volume/gal*/galaxy_emissive_rgba.raw.gz", "volume1": "$data/default-data/galaxy/volume/gal*/galaxy_occlusive_rgba.raw.gz", "volumeDepthThreshold": [0.0, 0.015] } } } The volume-specific attributes, described in the :ref:`Volume component `, are: - ``vertexShader`` -- vertex shader used by the model. Defaults to the PBR vertex shader. - ``fragmentShader`` -- fragment shader that ray-marches the volume. Defaults to ``shader/volume.fragment.glsl``, a generic shader which draws any stack of additive volumes. Both shaders can live in a dataset by prefixing the path with ``$data/``. - ``iterations`` (aliases ``raymarchIterations``, ``iterationCount``) -- number of ray-marching steps. Takes either a single integer, used for all graphics quality settings, or an array of four integers, one per quality setting (low, normal, high, ultra). Values below 40 are raised to 40. - ``writeDepth`` -- whether the volume writes to the depth buffer, which it does by default, so that it hides whatever is drawn after it (labels, grids, stars, planets). Set it to ``false`` to always see through the volume. The model is only the shell the ray-marcher starts from: it must be a closed mesh, typically a sphere with ``"flip": true`` so that its faces point inwards. The volume data itself comes from the material slots. .. _volume-files: Volume files ------------ Each ``volume0`` to ``volume3`` material slot points to a data file, which Gaia Sky binds as a 3D texture, and to a small text sidecar named after it that declares the resolution of the grid and the box it occupies. Both files, and the voxel layouts they can hold, are described in the :ref:`3D texture format <3d-texture-format>` section. Two sidecar keys shape the result. ``Grid size:`` is what makes a non-cubic grid possible: a flattened structure such as a galactic disc stores a small number of slices for the same voxel size, and without the key the loader can only infer a cube from the file length. ``Volume bounds:`` is the box the grid fills, in units of the object's ``size``, so bounds from ``-0.5`` to ``0.5`` make the box exactly as large as the object; the shader normalises the texture over them, so they need not match the size of the object. The loader crops the empty shell of the grid at load time, which shrinks both the box the rays traverse and the memory the texture takes. Volume materials and occlusion ------------------------------ Paths in the material accept the ``*`` wildcard, which is replaced by the suffix of the current graphics quality (``-low``, ``-med``, ``-high``, ``-ultra``), so that a single attribute can select a different resolution of the same volume per quality setting. This is what ``gal*/`` does in the example above. Emissive and absorbing volumes are combined by the shader. An emissive volume adds light, which requires additive blending. An absorbing volume (dust) emits nothing and only attenuates what is behind it, which requires the shader to know about the two volumes together, as ``shader/volume.galaxy.fragment.glsl`` does. A volume can also act as an occluder for the rest of the scene: the fragment shader writes the depth of the first sample whose density is above a threshold, and everything drawn afterwards is tested against it. The threshold is set per slot in ``volumeDepthThreshold``, a density in the same units as the alpha channel of the volume: - ``0.0`` (the default) means that the slot never occludes. This is the right value for emissive volumes, whose faint outer haze is not opaque and would cut a hard hole in the star field behind it. - A positive value means that only the voxels above that density occlude, so that the dense lanes of a dust volume hide the stars behind them while its diffuse tail does not. ``writeDepth`` enables or disables the depth pre-pass of the whole object. Rendering --------- The ray-marcher takes the step count from the ``iterations`` attribute and derives the step size from the length of the ray path through the box, so every ray samples the whole volume with the same number of steps. Empty space is skipped with a two-level scheme: the loader builds an occupancy grid with one texel per 4x4x4 brick of voxels, holding the maximum density of the brick, and the shader skips over the bricks that hold nothing. Volumes need a GPU with 3D texture support (OpenGL 3.3 core), which is already a hard requirement of Gaia Sky, and memory proportional to the grid: a ``798 x 80 x 800`` RGBA grid is about 200 MB once decompressed, per volume.