SoGVRShaderFunction¶
-
InventorModule
¶ author MeVis Medical Solutions AG
package MeVisLab/Standard
dll SoGVR
definition SoGVRShaderPipeline.def see also SoGVRVolumeRenderer
,SoGVRShaderDiagnosis
,SoGVRShaderInclude
keywords pipeline
Purpose¶
The SoGVRShaderFunction
allows for adding of custom GLSL shader code into the shader pipeline of the SoGVRVolumeRenderer
module.
Usage¶
Connect the module before the SoGVRVolumeRenderer
module in the scene graph and implement custom shader code to be added.
Details¶
Based on the SuperShader concept, the rendering shader is divided into a dynamic shader pipeline that allows for the interactive addition of custom shader code to volume rendering. A pipeline step is modeled as a subset of several shader pipeline functions, which contain the GLSL shader code.
![../../../Modules/Inventor/SoGVR/mhelp/Images/PipelineStep.png](../../../Modules/Inventor/SoGVR/mhelp/Images/PipelineStep.png)
For most steps, the GVR uses only one shader pipeline function at a time. This function is named after the step. For some steps, multiple functions can be active simultaneously (e.g., in shading for multiple lights). In this case, each function is considered a substep, and the function has a suffix in its name to reflect this.
For example: For lighting, the step is named ShadingLight, and the substeps are named ShadingLight_Light1, ShadingLight_Light2, and so on.
Since pipeline functions have no return value, a globally defined struct is used for communication. The struct is passed as both an input and output parameter (state) to the pipeline functions. Input values are read from the struct, while output values are written to it.
The SoGVRShaderFunction
module allows for implementing a custom pipeline function, where both the function body and the parameters can be edited. Thus, custom pipeline functions can be attached to a pipeline step to add or replace shader code (see modification type).
You can add custom uniforms and texture samplers using the GLSL shader framework of MeVisLab,
such as SoShaderParameter3f
, SoGVRShaderParameterPosition
, and SoMLSampler3D
.
Coordinate Systems¶
For shader development, it is important to understand the different coordinate systems:
![../../../Modules/Inventor/SoGVR/mhelp/Images/CoordinateSystems.png](../../../Modules/Inventor/SoGVR/mhelp/Images/CoordinateSystems.png)
- Device:
- Device coordinates are accessible via
gl_FragCoord
in the fragment shader and are useful for tasks such as jittering and screen position-dependent effects. - Eye/View:
- The eye coordinate system has the eye/camera position at (0, 0, 0) and is measured in mm units. It is useful for light calculations and distance-based effects.
- World:
- The world coordinate system serves as the reference coordinate system for all volumes and is identical to the DICOM patient coordinate system. It is expressed in mm units, making it useful for calculating distances in mm.
- Voxel:
- The voxel coordinate system places the center of the voxel at (x + 0.5, y + 0.5, z + 0.5) for a given volume. The world position of a voxel depends on the voxelToWorld matrix of the dataset. In the case of the GVR, voxel coordinates refer to the primary volume unless noted otherwise.
- ScaledVoxel:
- The scaled voxel coordinate system scales the voxel coordinate system by the voxel size. This results in a coordinate system expressed in mm units, similar to the world and eye coordinates. In the GVR, the viewing direction, light vectors, and gradient are given in scaled voxel coordinates to facilitate light calculations in the scaled voxel space, thereby avoiding the need to transform the gradient into eye coordinates.
- Tex:
- The texture coordinate system scales and translates the sampling position to a space suitable for
texture3D()
texture fetches. It is typically used only for sampling, and its concrete definition depends on the render mode (e.g., slicer, ray caster, bricked, non-bricked).
State variables¶
GVR state variables and their coordinate systems:
Variable | Coordinate System | Usage |
---|---|---|
state.primaryVolumePosition_tex | Tex | Texture sampling of primary volume |
state.maskVolumePosition_tex | Tex | Texture sampling of mask volume |
state.tagVolumePosition_tex | Tex | Texture sampling of tag volume |
state.gradientVolumePosition_tex | Tex | Texture sampling of gradient volume |
state.[*]Position_tex | Tex | Texture sampling of secondary/transformed volume ([*] = name of volume) |
state.viewingDirection_scaledVoxel | ScaledVoxel | Used for light/silhouette calculations |
state.primaryVolumePosition_eye | Eye | The primary sampling position in eye coordinates |
state.primaryVolumePosition_world | World | The primary sampling position in world coordinates |
state.primaryVolumePosition_voxel | Voxel | The primary sampling position in voxel coordinates |
state.primaryVolumePosition_scaledVoxel | ScaledVoxel | The primary sampling position in scaled voxel coordinates |
Transformation matrices¶
The GVR provides transformation matrices for common transformations that may be required. The matrices follow this convention:
sourceName_sourceSystem_to_targetName_targetSystem
where sourceName and targetName are provided only for voxel/scaledVoxel and tex matrices. The matrices are provided as mat4, except for the inverse transformed matrices, which are provided as mat3.
Name | Usage |
---|---|
world_to_eye | Transforms world to eye |
world_to_primaryVolume_voxel | Transforms world to primaryVolume voxel |
eye_to_world | Transforms eye to world |
eye_to_primaryVolume_voxel | Transforms eye to primaryVolume voxel |
primaryVolume_voxel_to_world | Transforms primaryVolume voxel to world |
primaryVolume_voxel_to_eye | Transforms primaryVolume voxel to eye |
primaryVolume_scaledVoxel_to_eye_inverseTransposed | Used to transform normals from scaledVoxel to eye (mat3) |
primaryVolume_voxel_to_[*]_tex | Transforms primaryVolume voxel to [*] mask/transformed volume tex coordinates |
Uniform variables¶
Have a look at the SoGVRShaderDiagnosis
module for a complete overview. The following table list some useful uniforms:
Type | Name | Usage |
---|---|---|
float | sliceDistance_voxel | Rendered slice distance in voxel units |
ivec3 | primaryVolumeSize | The size of the primary volume |
vec3 | primaryVolumeVoxelSize | The voxel size (in millimeters) of the primary volume |
vec3 | primaryVolumeVoxelSizeInv | The inverse voxel size |
vec3 | primaryVolumeTextureSize | The texture size (depending on the render mode) |
vec4 | primaryVolumeTextureSizeInv | The inverse texture size and 0. in w (depending on the render mode; useful as gradient offset) |
vec3 | centralViewingDirection_scaledVoxel | The viewing direction at the center of the screen (as opposed to the correct viewing direction at each pixel that is given by state.viewingDirection_scaledVoxel) |
vec3 | eyePosition_scaledVoxel | The eye position |
float | lutTextureHeightInv | The inverse of the height of the LUT texture (for 2D LUTs) |
sampler3D | primaryVolumeTexture | The primary volume texture |
sampler3D | tagVolumeTexture | The tag volume texture |
sampler3D | gradientVolumeTexture | The gradient volume texture |
sampler3D | maskVolumeTexture | The mask volume texture |
samplerXD | lutTexture | The main LUT texture (1D-3D) |
Varying variables¶
Although varyings are fully supported and can be passed from the vertex program to the fragment program, they only make sense for a pure slicing render mode, as a GPU ray caster does not use the vertex program for interpolation of sampling positions. All built-in GVR varyings start with varying_, and it is common practice to utilize the positions provided by the state instead of directly using the varyings. This approach allows shader code to function on both the slicer and the ray caster. In some situations, it may still be beneficial to add custom varyings to the vertex shader and use them in the fragment shader, such as to implement pre-integrated rendering with the slicer.
Built-in includes¶
The GVR has a number of built-in includes that are listed in the SoGVRShaderDiagnosis
panel. All these includes start with the gvr_ prefix.
Tips¶
Depending on the settings of the SoGVRVolumeRenderer
and its extensions, different pipeline steps become activated, and various uniforms and texture samplers become available.
Your best friend for introspecting the current shader pipeline is the SoGVRShaderDiagnosis
module, which lists all active uniforms.
The best way to start using the SoGVRShaderFunction
module is to build the GVR scene you wish to modify and add a SoGVRShaderDiagnosis
to inspect the resulting pipeline state and uniforms.
Output Fields¶
self¶
-
name:
self
, type:
SoNode
¶ A node that must be put in front of the
SoGVRVolumeRenderer
Parameter Fields¶
Field Index¶
Enabled : Bool |
Program : Enum |
Fragment Step : Enum |
Replaced1 : String |
Function Body : String |
Replacement1 : String |
Function Display : String |
Substep (optional) : String |
Function Name : String |
Vertex Step : Enum |
Modification Type : Enum |
|
Needs Active Step : Bool |
|
Parameter Declaration : String |
Visible Fields¶
Modification Type¶
-
name:
modificationType
, type:
Enum
, default:
ADD_AFTER
¶ Defines the modification type of the shader pipeline by the custom function.
Values:
Title | Name | Description |
---|---|---|
Add After | ADD_AFTER | Adds the custom function after the selected pipeline (sub)step. |
Add Before | ADD_BEFORE | Adds the custom function before the selected pipeline (sub)step. |
Replace | REPLACE | The custom function replaces the selected pipeline (sub)step. |
Remove | REMOVE | The selected pipeline (sub)step is removed from the shader pipeline. |
Add Before Inorder | ADD_BEFORE_INORDER | Like ADD_BEFORE but keeps the order of functions. |
Program¶
-
name:
program
, type:
Enum
, default:
Fragment Program
¶ Defines the use of the fragment or vertex program.
Vertex Step¶
-
name:
vertexStep
, type:
Enum
, default:
START
¶ Defines the pipeline step of the vertex pipeline to be modified.
Similar to the fragment shader, the vertex shader is structured as a pipeline. However, the vertex shader currently does not utilize the state struct or substeps.
Fragment Step¶
-
name:
fragmentStep
, type:
Enum
, default:
START
¶ Defines the pipeline step of the fragment pipeline to be modified.
The following table shows which values a step reads from and writes to the state struct, as well as which substeps exist.
Values:
Title | Name |
---|---|
Raycast Entryexit Fetch | RAYCAST_ENTRYEXIT_FETCH |
Raycast Depth Peel | RAYCAST_DEPTH_PEEL |
Substep (optional)¶
-
name:
substep
, type:
String
¶ Sets a substep of the current pipeline step via suffix of the function name.
E.g., choose the string “Light1” in Shading Light to modify the shading substep of Light1.
Needs Active Step¶
-
name:
needsActiveStep
, type:
Bool
, default:
FALSE
¶ If checked, the pipeline will be modified only if the selected step is active in the current rendering configuration of the GVR.
Parameter Declaration¶
-
name:
parameterDeclaration
, type:
String
¶ Sets parameters used in the custom function body.
Possible parameters:
- uniform: for a GLSL uniform parameter
- varying: for a GLSL varying parameter
- state: for a input/output pipeline struct parameter
- include: for a custom shader header or pipeline library function
Using uniform, varying, and state adds the declared variable declaration to the header string. Using include will add the declaration of the specified include to the header.
Syntax:
uniform TYPE identifier; uniform TYPE identifier [size]; varying TYPE identifier; state TYPE identifier; state TYPE identifier = DEFAULTVALUE; include name;
Entries in the parameter declaration field are separated by newlines. The ; and = characters can be omitted. TYPE can be any GLSL type, while identifier can be any GLSL identifier (e.g., variable name). DEFAULTVALUE can be a GLSL statement to initialize a variable that matches the respective type and can be used in a struct constructor. For includes, name is a user-defined identifier for the include. In each line, characters after the expected number of words are ignored, which can be utilized for comments, for example.
You can either use the built-in GVR includes (see Tips and Tricks) or define your own includes with the
SoGVRShaderInclude
module.
Function Display¶
-
name:
functionDisplay
, type:
String
, persistent:
no
¶ Shows an overview of the function described by the current settings. This can be used, for example, to check the defined replacements.