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.

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

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:

../../../Modules/Inventor/SoGVR/mhelp/Images/CoordinateSystems.png
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.

Windows

Default Panel

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

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

Enabled

name: enabled, type: Bool, default: TRUE

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

Function Name

name: functionName, type: String

Specify a unique custom function name.

Function Body

name: functionBody, type: String

The custom function body to be implemented.

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.

Replaced1

name: replaced1, type: String

Defines 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

The replacement string.