SoShaderPipelineFunction¶
-
InventorModule
¶ author MeVis Medical Solutions AG
package MeVisLab/Standard
dll SoShaderPipeline
definition SoShaderPipeline.def
Purpose¶
The SoShaderPipelineFunction
allows to extend the SoShaderPipeline
with
custom steps.
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.
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 SoShaderPipelineFunction
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, texture samplers and vertex attributes using the GLSL shader framework
shader framework of MeVisLab,
e.g. SoShaderParameter3f
, SoGVRShaderParameterPosition
and SoMLSampler3D
.
Details¶
The following state is available in a default pipeline shader (with per-fragment shading):
Vertex Shader State¶
Initial state:
state vec4 vertexPosition
state vec4 vertexColor
state vec3 vertexNormal
After eye transformation:
state vec3 vertexEyeNormal
state vec4 vertexEyePosition
After projection:
state vec4 projectedPosition
Fragment Shader State¶
Initial state:
state vec4 vertexEyePosition
state vec3 vertexEyeNormal
state vec4 vertexColor
state vec3 eyeViewingDirection
After surface shader setup:
state float surfaceShininess
state vec3 surfaceDiffuse
state float surfaceAlpha
state vec3 surfaceSpecular
After lighting:
state vec4 resultColor
Lighting¶
The lighting is calculated in eye space. This is so because the OpenGL fixed function lights are in eye space by default and it was straight forward to work in eye space. This means that you should use the vertexEyePosition, vertexEyeNormal and eyeViewingDirection for custom lighting calculations.
Future versions might do lighting in tangent space as well, this would make sense if normal mapping is used in a surface shader. This would mainly be a performance optimization, because if light positions/dirs, view dir etc. would all be in tangent space, the per pixel fetch of the normal would not require to be mapped to eye space.
Shader version and extensions¶
Inside of the function or the include, you can place a:
#version GLSLVersion
directive to indicate, which GLSL version you want to use. The shader pipeline will parse these and use the highest shader version that is requested.
In addition to that, you can use the the standard #extension directive in your function. All extension directives will be moved to the top of the resulting shader.
- Example::
- #version 120 #extension GL_EXT_texture_array : enable
The highest GLSL version that can be used with the SoShaderPipeline
is 130.
Starting with shader version 140, all OpenGL state uniforms in the shader have been removed.
A future version of the shader pipeline (and Open Inventor) might set alternative uniforms that match the deprecated OpenGL state, so that using newer GLSL versions become possible.
Transferring state between shaders¶
To avoid the manual creation of varying variable, there is an automatism that transfers state values from the vertex shader state to the fragment shader state automatically. This works by automatically transferring any vertex state that starts with vertex to the fragment shader. How this happens is transparent to the user. So if you add a new state to the vertex shader, e.g. vertexCurvature, you can just use the same state in the fragment shader, by using the same name.
Vertex attributes can be added manually, but it is also possible to prefix a state variable name with vertexArray_. For instance, adding the state variable vertexArray_NodeCurvature will automatically add a NodeCurvature attribute to the shader and copy its value to the state. If the state is used in the fragment shader, it is automatically transfered as a varying.
Tips¶
To get started, have a look at the SoShaderPipelineDiagnosis
to see how a generated shader looks and what kind of state variables and steps are available by default.
Parameter Fields¶
Field Index¶
Enabled : Bool |
Program : Enum |
Fragment Step : Enum |
Vertex Step : Enum |
Function Body : String |
|
Function Display : String |
|
Function Name : String |
|
Modification Type : Enum |
|
Needs Active Step : Bool |
|
Parameter Declaration : String |
Visible Fields¶
Function Body¶
-
name:
functionBody
, type:
String
¶ The implementation of the function body. The state variable contains the current pipeline state.
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
- attribute: for a GLSL vertex attribute 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; attribute 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 SoShaderPipeline builtin includes (see Tips and Tricks), or define your own includes with the
SoShaderPipelineInclude
module.
Modification Type¶
-
name:
modificationType
, type:
Enum
, default:
ADD_AFTER
¶ Defines which operation is applied.
Values:
Title | Name | Description |
---|---|---|
Add After | ADD_AFTER | Add function after the given step. |
Add Before | ADD_BEFORE | Add function before the given step. |
Replace | REPLACE | Replace the given step with this function. |
Remove | REMOVE | Remove the given step. |
Add Before Inorder | ADD_BEFORE_INORDER | Like ADD_BEFORE, but keeps order of functions |
Program¶
-
name:
program
, type:
Enum
, default:
Fragment Program
¶ Selects the shader program type of the function.
Values:
Title | Name |
---|---|
Fragment Program | Fragment Program |
Vertex Program | Vertex Program |
Vertex Step¶
-
name:
vertexStep
, type:
Enum
, default:
START
¶ Selects the vertex step.
Values:
Title | Name |
---|---|
Start | START |
Calculate Eye Position | CALCULATE_EYE_POSITION |
Calculate Texture Coord | CALCULATE_TEXTURE_COORD |
Vertex Surface Shader | VERTEX_SURFACE_SHADER |
Vertex Lighting | VERTEX_LIGHTING |
Project Vertex | PROJECT_VERTEX |
Calculate Point Sprite Size | CALCULATE_POINT_SPRITE_SIZE |
End | END |
Vertex Add Ambient | VERTEX_ADD_AMBIENT |
Vertex Add Emissive | VERTEX_ADD_EMISSIVE |
Fragment Step¶
-
name:
fragmentStep
, type:
Enum
, default:
START
¶ Selects the fragment step.
Values:
Title | Name |
---|---|
Start | START |
Point Sprite Setup | POINT_SPRITE_SETUP |
Depthpeel Discard | DEPTHPEEL_DISCARD |
Fragment Surface Setup | FRAGMENT_SURFACE_SETUP |
Fragment Surface Shader | FRAGMENT_SURFACE_SHADER |
Fragment Lighting | FRAGMENT_LIGHTING |
Texturing | TEXTURING |
Fog | FOG |
Write Fragment | WRITE_FRAGMENT |
End | END |
Fragment Add Ambient | FRAGMENT_ADD_AMBIENT |
Fragment Add Emissive | FRAGMENT_ADD_EMISSIVE |