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 subdivided into a dynamic shader pipeline which allows for an interactive addition of custom shader code to the volume rendering. A pipeline step is modeled as a subset of several shader pipeline functions, which contain the GLSL shader code.
For most steps, the GVR only uses one shader pipeline function at a time. This function is named like the step. For some steps, multiple functions are active at a time (e.g. in shading light for multiple lights). In this case, each function is considered to be a substep, and the function has a suffix in its name to reflect this. 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 input and output parameter (state) to the pipeline functions. Input values are read from the struct, output values are written into the struct.
The module SoGVRShaderFunction
allows to implement a custom pipeline function, where the function body as well as the parameters can be edited. Thus, custom pipeline functions can be attached to a pipeline step in order to add or replace shader code (see modification type).
You can add your own uniforms and texture samplers using the GLSL shader framework of MeVisLab,
e.g. SoShaderParameter3f
, SoGVRShaderParameterPosition
and SoMLSampler3D
.
Coordinate Systems¶
For shader development, it is important to understand the different coordinate systems:
- Device:
- Device coordinates are readable via gl_FragCoord in the fragment shader and are useful for things like jittering and screen position depended effects
- Eye/View:
- The eye coordinate system has the eye/camera position at (0,0,0) and is in mm units. It is useful for light calculations and distance based effects.
- World:
- The world coordinate system is used as the reference coordinate system for all volumes and is identical with the DICOM patient coorinate system. It is given in mm units, so it is useful for calculation of distances in mm.
- Voxel:
- The voxel coordinate system places the center of voxel (x,y,z) of a volume at (x + 0.5, y + 0.5, z + 0.5). It is defines for a given volume, so the world position of a voxel position depends on the voxelToWorld matrix of the dataset. In the case of the GVR, voxel coordinates refer to the primary volume if not noted otherwise.
- ScaledVoxel:
- The scaled voxel coordinate system scales the voxel coordinate system by the voxel size. This results in a coordinate system that is given in mm units, like the world and eye coordinates. In the GVR, the viewing direction, the light vectors and the gradient are given in scaled voxel coordinates to allow light calculation in the scaled voxel space, which avoids transforming the gradient into eye coordinates.
- Tex:
- The texture coordinate system scales/translates the sampling position to a space that can be used for texture3D() texture fetches. It is typically only used for sampling and its concrete definition depends on the render mode (slicer/raycaster/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 the common transformations that might be required. The matrices follow the following convention:
sourceName_sourceSystem_to_targetName_targetSystem
where sourceName and targetName are only given for voxel/scaledVoxel and tex matrices. The matrices are given as mat4, except for the inverse transformed, which are given 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 mm) of the primary volume |
vec3 | primaryVolumeVoxelSizeInv | The inverse voxel size |
vec3 | primaryVolumeTextureSize | The texture size (depended on the render mode) |
vec4 | primaryVolumeTextureSizeInv | The inverse texture size and 0. in w (dependend 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 vertex program to fragment program, they only make sense for a pure slicing rendermode, since a GPU ray caster does not use the vertex program for interpolation of sampling positions. All builtin GVR varyings start with varying_ and it is common practice to make use of the positions privided by the state instead of directly using the varyings. This allows shader code to work on both the slicer and the ray caster. In some situations, it still makes sense to add own varyings to the vertex shader and use them in the fragment shader, e.g. to implement preintegrated rendering with the slicer.
Builtin includes¶
The GVR has a number of builtin includes which are listed in the SoGVRShaderDiagnosis
panel. The includes all start with the gvr_ prefix.
Tips¶
Depending on the settings of the SoGVRVolumeRenderer
and its extensions,
different pipeline steps become activated and different uniforms and texture samplers are available.
Your best friend in introspecting the current shader pipeline is the SoGVRShaderDiagnosis
module,
which lists all active uniforms.
The best way to start using the SoGVRShaderFunction
is to build the GVR scene that you wish to modify
and adding a SoGVRShaderDiagnosis
to inspect the resulting pipeline state and uniforms.
Output Fields¶
self¶
-
name:
self
, type:
SoNode
¶ a node that should 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 will be removed from the shader pipeline |
Add Before Inorder | ADD_BEFORE_INORDER | Like ADD_BEFORE, but keeps order of functions |
Program¶
-
name:
program
, type:
Enum
, default:
Fragment Program
¶ Select the fragment or the vertex program.
Vertex Step¶
-
name:
vertexStep
, type:
Enum
, default:
START
¶ Select the pipeline step of the vertex pipeline to be modified. Like the fragment shader, the vertex shader is structured as a pipeline. The vertex shader currently does not use the state struct, or substeps.
Fragment Step¶
-
name:
fragmentStep
, type:
Enum
, default:
START
¶ Select 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, and which substeps exist.
Values:
Title | Name |
---|---|
Raycast Entryexit Fetch | RAYCAST_ENTRYEXIT_FETCH |
Raycast Depth Peel | RAYCAST_DEPTH_PEEL |
Substep (optional)¶
-
name:
substep
, type:
String
¶ Specify a substep of the current pipeline step via suffix of the function name. E.g. chose the string Light1 in Shading Light to modify the shading substep of Light 1.
Needs Active Step¶
-
name:
needsActiveStep
, type:
Bool
, default:
FALSE
¶ The pipeline will be modified only if the selected step is active in the current rendering configuraton of the GVR.
Parameter Declaration¶
-
name:
parameterDeclaration
, type:
String
¶ Allows to declare parameters which are 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 will add 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 newline. The ; and = characters can be ommitted. TYPE can be any GLSL type, identifier can be any GLSL identifier (e.g. variable name). DEFAULTVALUE can be a GLSL statement to initialize a variable which matches the respective type and can be called in a struct constructor. For includes, name is a user defined identifier for the include. In every line, character after the expected number of words are ignored, which can e.g. be used for comments.
For includes, you can either use the GVR builtin includes (see Tips and Tricks), or define your own includes with the
SoGVRShaderInclude
module.
Function Display¶
-
name:
functionDisplay
, type:
String
, persistent:
no
¶ Displays an overview over the function described by the current settings. Can e.g. be used to check the defined replacements.