|
FhSim
3.1.0
Marine systems simulation
|
Ray-marches a field of the environment sampled into a 3-D texture.
Collaboration diagram for Field volume:Visualization SimObject showing a whole region of a field of the environment at once.
The quantity (as on VisualFieldPlane: a velocity of Terms, the wake deficit, the wave pressure, or a scalar field) is sampled onto a regular grid filling a NED axis-aligned box and uploaded as a 3-D texture. A box proxy is rasterised, and each fragment marches one ray through the texture, compositing colour and opacity front to back, so the region reads as a semi-transparent body of water rather than as a surface. The field is sampled again only when Refresh says so (see VisualFieldPlane); between samples the cost per frame does not depend on Resolution. A field sampled more than once gets a smaller default grid, near 64 x 64 x 64 cells, because every sample is paid for while the simulation waits.
Opacity is corrected for step length against ReferenceLength, a fixed world-space length, so AlphaRange means the same thing here as on VisualFieldPlane and the apparent density does not change with Resolution or with view direction.
A ray-march is a single fragment, so the whole ray is depth-tested at the depth of whichever box face was rasterised. The front face is rasterised, so the ray is tested where it enters the box, and the seafloor mesh - drawn opaque, with depth writes, ahead of any transparent geometry - hides the volume behind it. Two artefacts follow from the one depth value, are accepted, and are not solvable without depth-buffer sampling, which is out of scope:
max(nearIntersection, 0) clamp in the shader does not remove this: it moves where the ray starts, not the depth the fragment is tested at.None.
None.
| Name | Width | Description |
|---|---|---|
| Quantity | 1 | What is shown, as on VisualFieldPlane; Elevation is a surface quantity and an error here. (Default: Scalar with FieldName, Speed without) |
| Terms | 1 | The parts of the water velocity Speed and Component sum, as on VisualFieldPlane. (Default: Current, Waves, Wake, Jet) |
| Axis | 3 | Direction of Component, NED. Required with Component, an error otherwise. |
| FieldName | 1 | Name of the scalar field to show, as registered by the Environment. Required with Quantity Scalar, an error otherwise. |
| Refresh | 1 | When the field is sampled again, as on VisualFieldPlane. (Default: Auto) |
| RefreshPeriod | 1 | As on VisualFieldPlane [s]. (Default: 0) |
| BoxCentre | 3 | Centre of the sampled box in the NED frame [x, y, z] [m]. Ignored when CentreOnCamera is set: the first bake then centres on the camera. (Default: 0, 0, 100) |
| BoxSize | 3 | Extent of the sampled box along each NED axis [m]. (Default: 2000, 2000, 200) |
| Spacing | 3 | Grid spacing of the bake along each NED axis [x, y, z] [m] - the NED frame, not the local [u, v] frame VisualFieldPlane uses for the same parameter. Mutually exclusive with Resolution; configuring both is an error. A spacing coarser than BoxSize on an axis still gives at least two samples there, because the bake is always a 3-D texture. (Default: absent, a spacing near 4194304 cells is derived for a field sampled once, near 262144 otherwise) |
| Resolution | 3 | Samples of the bake along each NED axis [x, y, z] - the NED frame, not the local [u, v] frame VisualFieldPlane uses for the same parameter. Mutually exclusive with Spacing; configuring both is an error. The third entry is raised to 2 when it is 1, because the bake is always a 3-D texture. (Default: absent, as Spacing) |
| ReferenceLength | 1 | Path length over which AlphaRange is the opacity [m]. A fixed world-space length, so halving or doubling Resolution leaves the apparent density unchanged. It combines with AlphaRange over the whole path: a ray crossing L metres of visible field at per-ReferenceLength opacity alpha emerges at 1 - (1 - alpha)^(L / ReferenceLength). Worked example: AlphaRange 0.02, 0.35 with ReferenceLength 10 leaves the faint edges nearly clear while the densest core reaches about 1 - 0.65^6 = 0.9 opacity through a 60 m core. The default of 1 m saturates any ray crossing more than a few metres of visible field - at the default AlphaRange 0.3, 0.6 a 15 m path is already opaque and a 200 m box is solid - so ReferenceLength should normally be set to the scale of the structure being shown, as the shipped examples do with 10 and 20. (Default: 1) |
| CentreOnCamera | 1 | Move the box centre to follow the camera, sampling again once it has moved far enough: on a worker thread for a time-invariant, thread-safe scalar field, else while the simulation waits. The encoding range is fixed at the first bake and never revisited, so values at a later box position that fall outside it are silently clamped; a warning naming ColorRange and VisibleRange is logged when a re-bake clamps more than a few percent of its cells, and pinning those two parameters is the cure. (Default: false) |
| RebakeFraction | 1 | Fraction of BoxSize the camera must move on any axis before a CentreOnCamera re-bake starts. (Default: 0.25) |
| VisibleRange | 2 | Value span drawn at all [min, max]; values outside it are fully transparent. (Default: probed from the field and widened by one encoding code when it is sampled once, else ColorRange) |
| ColorRange | 2 | Value span mapped across the full colour ramp [min, max]. (Default: probed from the field when it is sampled once, else 0, 1) |
| AlphaRange | 2 | Opacity span applied across the visible range [min, max], stated over a path of ReferenceLength and clamped to [0, 1]: the lowest visible value gets min and the highest max. A ray accumulates it over its whole path as 1 - (1 - alpha)^(L / ReferenceLength), so it is the pair AlphaRange and ReferenceLength that decides how dense the result looks, never AlphaRange alone. It means the same thing on VisualFieldPlane, where a single fragment is one sample and no path correction applies. (Default: 0.3, 0.6) |
| ShowExtrapolated | 1 | Draw values the field flagged as inaccurate instead of masking them. Leaving it false has two surprising consequences. A DepthLayeredScalarField reports OUT_OF_RANGE_INACCURATE at every depth outside its profile, so a box below the deepest layer renders nothing. A ParametricScalarField returns the same status both for a position below the seabed when maskBelowSeabed is set and for a DepthProfile background clamped outside its layers, and the two cannot be told apart, so such a field masks everything outside that profile and not only what is below the seabed. A value the field reports with an error status (no data, such as no seabed depth there) is masked whatever this says. (Default: false) |
This SimObject is referred to as VisualFieldVolume