|
FhSim
3.1.0
Marine systems simulation
|
Ray-marches a scalar field baked once into a 3-D texture.
Collaboration diagram for Scalar field volume:Visualization SimObject showing a whole region of a scalar field at once.
The field is evaluated onto a regular grid filling a NED axis-aligned box once, in RenderInit, 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. Nothing is evaluated per frame, so the cost is independent of Resolution once baked.
Opacity is corrected for step length against ReferenceLength, a fixed world-space length, so AlphaRange means the same thing here as on VisualScalarPlane and the apparent density does not change with Resolution or with view direction.
Only a time-invariant scalar field can be baked. A field that varies with time is refused unless VisualiseAsConstant is set.
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 |
|---|---|---|
| FieldName | 1 | Name of the scalar field to show, as registered by the Environment. (Required) |
| 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 VisualScalarPlane 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) |
| Resolution | 3 | Samples of the bake along each NED axis [x, y, z] - the NED frame, not the local [u, v] frame VisualScalarPlane 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, a spacing near 4194304 cells is derived) |
| 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, re-baking on a worker thread once it has moved far enough. 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) |
| ColorRange | 2 | Value span mapped across the full colour ramp [min, max]. (Default: probed from the field) |
| 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 VisualScalarPlane, 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. (Default: false) |
| VisualiseAsConstant | 1 | Bake a field that is not time-invariant anyway, showing it as it is at time zero. (Default: false) |
This SimObject is referred to as VisualScalarVolume