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

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
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.

Windows

Default Panel

../../../Modules/Inventor/SoGVR/mhelp/Images/Screenshots/SoGVRShaderFunction._default.png

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

Enabled

name: enabled, type: Bool, default: TRUE

If checked, the shader function is enabled.

Modification Type

name: modificationType, type: Enum, default: ADD_AFTER

Defines the modification type of the shader pipeline by the custom function.

../../../Modules/Inventor/SoGVR/mhelp/Images/PipelineCustom.png

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.

Function Name

name: functionName, type: String

Sets a unique custom function name.

Function Body

name: functionBody, type: String

Sets the custom function body to be implemented.

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.

Replaced1

name: replaced1, type: String

Sets a substring to be replaced by the replacement in the function name string, function body string, substep string, and parameter declaration string.

Replacement1

name: replacement1, type: String

Sets the replacement string.