volume (lx_volume.hpp)

From The Foundry MODO SDK wiki
Jump to: navigation, search
There are security restrictions on this page


Introduction

This module implements the volumetric interface that can be used to add volumetric samples along a ray.

Volumetric Engine

The volumetric engine offers a set of functions to use in a raytracing context. These functions allow multiple volumetric items to collect their samples in a stack. When all volumetric items have contributed to the ray, the resulting scattering and attenuation can be computed by flattening the ray.

Evaluation Flags

Volumetric evaluation flags specify the context in which volumetric rays are evaluated. More info about the context can be gathered from the raytrace flags.

(1) SDK: Declarations
 #define LXfVOLUME_RAY_COLOR             (1<<0) // color ray
 #define LXfVOLUME_RAY_OPACITY           (1<<1) // shadow ray

Volume Samples

Volume rendering splits a volume into pieces. Each piece is called a volume sample. It has a color corresponding to the light scattering at that point, an opacity corresponding to the light attenuation, a distance which is the position of the sample on the ray (measured from the origin of the ray), and a stride which is the size of the sample (still measured on the ray).

(2) SDK: LXtVolumeSample struct
 double          dist;
 double          color[3];
 double          opacity[3];
 double          stride;

Solid rendering returns a LXtSurfFragment structure which holds the information resulting from the intersection between the given ray and the solid and the subsequent surface shading. This includes the distance to the origin of the ray, the surface normal, the color and opacity resulting from shading, and the object and surface IDs. Note: Additionnal information that the client would like to set (for special render buffers) can bet set manually by checking the result of the addSolid() method which returns true if the LXtSurfFragment can contribute to the buffers.

(3) SDK: LXtSurfFragment struct
 double          dist;
 double          color[3];
 double          transparency[3];

Raymarching Interface

The raymarching interface allows volume elements to contribute to raytracing by adding volume samples to the ray. Once all the volume elements have been evaluated the ray is 'flattened' and the resulting opacity and scattering values are passed to the raytracer.

AddVolume adds a volume sample to the ray. The volume sample has scattering and opacity values
as well as a size (along the ray) called 'stride'.
AddSurface adds a surface sample to the ray. The surface sample is a sample with 0 stride and
is handled differently when computing the transmittance function.
GetOpacity at any point during raymarching it is possible to evaluate the opacity for a given distance
along the ray.
ShaderEvaluate samples can be shaded using the default shader using this function. The resulting values
will be in the ShadeOutput packet.
Jitter1D to avoid aliasing patterns it is better to jitter the sample positions. This function can be used
to produce a good jitter value which will be different for every pixel and for every successive call.

(4) SDK: ILxRaymarch interface
         LXxMETHOD(  LxResult,
 AddVolume) (
         LXtObjectID              self,
         LXtObjectID              vector,
         LXtVolumeSample         *vs);
 
         LXxMETHOD(  LxResult,
 AddSurface) (
         LXtObjectID              self,
         LXtObjectID              vector,
         LXtSurfFragment         *ss);
 
         LXxMETHOD(  LxResult,
 GetOpacity) (
         LXtObjectID              self,
         LXtObjectID              vector,
         double                   dist,
         double                  *opa);
 
         LXxMETHOD(  LxResult,
 ShaderEvaluate) (
         LXtObjectID              self,
         LXtObjectID              vector,
         LXtObjectID              shader);
 
         LXxMETHOD(  LxResult,
 Jitter1D) (
         LXtObjectID              self,
         LXtObjectID              vector,
         float                   *offset);

(5) SDK: Declarations
 #define LXu_RAYMARCH            "1E84C5A8-C002-4120-BAB0-9EEB1722688B"
 #define LXa_RAYMARCH            "raymarch"
 #define LXsP_RAYMARCH           "raymarch"

Empty Raymarch Python user class.

(6) PY: Raymarch method
 pass

Voxel interface

Volumetric items can use and\or present a voxel interface to access volumetric data or export their own volumetric data to other items.

This is done with the voxel graph:

(7) SDK: Declarations
 #define LXsGRAPH_VOXEL  "volumeVoxel"

(8) SDK: Declarations
 #define LXsPKG_VOXEL_CHANNEL    "volumeVoxel.channel"

FeatureCount, FeatureByIndex: returns the number and name of features in the voxel grid.
BBox: Specifies the region in world space where the data is located.
NextPos: During raymarching we need to march through the data efficiently. The NextPos method returns the next position in the voxel data that needs to be sampled, it will skip void regions to go directly to the next grid cells along the ray.
Sample: The grid data can be sampled by position. This will return the data for the given position and feature index, the nature of the data depends on the feature type.
VDBData: We directly expose a vdbData object pointer that can be passed around. If the volume data comes from an OpenVdb file this pointer can be passed to other items for operations such as filtering , meshing, etc.
RayIntersect: This allows raycasting to be performed on the voxel data.
RayRelease: This will be called to release any data allocated by the RayIntersect method.

(9) SDK: ILxVoxel interface
         LXxMETHOD(  LxResult,
 FeatureCount) (
         LXtObjectID              self,
         unsigned                *num);
 
         LXxMETHOD(  LxResult,
 FeatureByIndex) (
         LXtObjectID              self,
         unsigned                 index,
         const char              **name);
 
         LXxMETHOD(  LxResult,
 BBox) (
         LXtObjectID              self,
         LXtTableauBox            bbox);
 
         LXxMETHOD(  LxResult,
 NextPos) (
         LXtObjectID              self,
         float                    currentPos,
         unsigned                 currentSegment,
         float                    stride,
         float                   *segmentList,
         unsigned                *nextSegment,
         float                   *nextPos);
 
         LXxMETHOD(  LxResult,
 Sample) (
         LXtObjectID              self,
         const LXtFVector         pos,
         unsigned                 index,
         float                   *val);
 
         LXxMETHOD(  LxResult,
 VDBData) (
         LXtObjectID              self,
         void                    **ppvObj);
 
         LXxMETHOD(  LxResult,
 RayIntersect) (
         LXtObjectID              self,
         const LXtVector          origin,
         const LXtFVector         direction,
         unsigned                *numberOfSegments,
         float                   **Segmentlist);
 
         LXxMETHOD(  LxResult,
 RayRelease) (
         LXtObjectID              self,
         unsigned                 numberOfSegments,
         float                   **Segmentlist);

(10) SDK: Declarations
 #define LXu_VOXEL               "A2B024D6-4D03-4FA0-B3CA-A7949D7F7B7A"
 #define LXa_VOXEL               "voxel"