Create Additive Blend Shader

You need the following Simdify® modules to complete this exercise: Simdify® Free Edition

In this exercise you'll learn to use the Outline app and the Module app to create a shader module that implements additive blending. The following table shows the skills required to complete this exercise.

Skill Description
Starting Applications You need to be able to access the Windows Start Menu, find applications, and start them.
Opening Files You need to be able to open files from disk.
Tree View You need to be able use a Windows tree view to expand and contract nodes. You need to be able to right click on the nodes to access node command menus.
Text Editor You need to be able to start a text editor such as Notepad, Notepad++, or Visual Studio and open a text file from the hard disk. You need to be able to edit the text file and save the changes.

Open Simdify Data Project

  1. Start the Outline app. (Start > Programs > Scenomics > Outline) or (Windows® key and then type 'Outline' to find the app icon.)

    The application displays a splash screen and then the application desktop appears.

    This is a picture of the Outline application desktop.
  2. Select File > Open from the main menu.

    The application presents the file open dialog in the Outline application library folder.

    This is a picture of the file open dialog in the Outline application library.
  3. Enter the directory named Simdify Data and open Simdify Data.box. This is a picture of the Simdify Data.box opened in the Outline application.
  4. Select Graph > Set View Compact from the main menu. This is a picture of the hierarchy with a compact view.
  5. Right click over the <LibraryConfigNode> named Application Documents and select Find Module Library Folder from the listed options.

    This finds the Module library folder and selects it so that it's easy to see.

    This is a picture of the hierarchy with the application documents folder expanded.

    The Simdify Data project contains all the information associated with your Simdify installation. Think of it like the 'north star' for everything you're doing with Simdify. In this project you can always find all your documents.

Create New Shader Module

  1. Right click over the <FolderConfigNode> named Module and select New > Folder from the listed options. This is a picture of the hierarchy with the FolderConfigNode command menu showing the New commands popup.The software presents a dialog that allows you to set the name of the new folder.

    This is a picture of EnterTextDialog prompting you to set the name of the new folder.
  2. Type FBO Image Processing Tiles and click OK or hit ENTER when you are finished.

    Copy Text To Clipboard

    FBO Image Processing Tiles

    The software creates the folder on disk and adds a new folder to the hierarchy.

    This is a picture of the hierarchy showing the new folder.
  3. Right click over the <FolderConfigNode> named FBO Image Processing Tiles and select New > Blank Shader Module from the listed options.

    The software presents a dialog that allows you to create a new shader module.

    This is a picture of the hierarchy with the FolderConfigNode command menu showing the New commands popup.
  4. Set Module Name to Additive-Blend-Module

    Copy Text To Clipboard

    Additive-Blend-Module
  5. Set Module Info to Implements a shader module for additive blending.

    Copy Text To Clipboard

    Implements a shader module for additive blending.
  6. Set Usage Hint to Usage-Shader-Tile-Module.
  7. Set GLSL Version to 430 (or the highest version listed).
  8. Click OK or hit ENTER when you are finished.

    The application creates the new shader module.

Open Shader Module

  1. Right click over the <FolderConfigNode> named FBO Image Processing Tiles and select Expand All from the listed options.

    You can see all the files associated with the new shader module.

    This is a picture of the hierarchy with the new FolderConfigNode fully expanded.
  2. Right click over the <FileConfigNode> named Additive-Blend-Module-430.box and select Open File from the listed options.

    The Module application starts and loads the file.

    This is a picture of the Module application desktop.

Examine Additive Blend Document

  1. Select Graph > State > Expand All Tree Items from the main menu.

    The hierarchy editor displays the contents of your shader module, which gives you information about when shader module items are executed. The rendering loop starts at the root of the document and traverses nodes using a breadth-first search, rendering each node as it is traversed. This means you can make certain assumptions about how your shader module behaves by looking at the hierarchy.

    This is a picture of the hierarchy showing the new shader module.

    The hierarchy is delineated into two main sections: Data and Execution. The Data section refers to data such as textures and meshes that do not need an active shader program to operate. There are other data such as storage containers for inputs and outputs. These will be used to specify input and output constraints if this shader module is used in a workload layout.

    The Execution section requires an active shader program. Notice that the nodes in the execution section are stored below <ShaderResourceNode> objects. You can see the <ProgramBindNode> named Bind Visual is the first useful item in the Execution section. After the shader program is bound, you can see that we are able to set uniforms and do other things related to that shader program. We could bind another shader program and then do similar things. The pattern is pretty clear: bind a shader program and then do work. This basic process is how you build all shader modules.

    This is a picture of the hierarchy showing the data and execution sections with colored overlays.

    Finally, order of operations definitely matters. You usually want to adhere to the structure of the Data section shown in this document. Of course, you are free to be much more creative in the Execution section as long as you make sure to follow the basic pattern of binding a shader program and then binding its resources.

Modify Fragment Shader Source

  1. Right click over the the <Program> node named Visual and select Copy Source Path > Fragment Shader from the listed options.

    The software displays a dialog that allows you to select the source file you wish to open. This includes any files #included by the shader. (While GLSL itself doesn't automatically support preprocessing shader source code, Simdify design applications DO allow you to use #include to create modular shaders.)

    This is a picture of the select source dialog.
  2. Left click fragment_shader.glsl and click OK or hit ENTER when you are finished.

    The application displays a dialog box that informs you the path has been copied to the clipboard.

    This is a picture of the select source dialog.
  3. Start a text editor such as Notepad, Notepad++, or Microsoft Visual Studio.
  4. Select the menu option to open a file from disk.
  5. Use CTRL + V to paste the path from the clipboard into the field that allows you to specify the path and filename.

    You'll see path such as: C:\Users\Installer Test 0\Documents\Scenomics\Library\Module\FBO Image Processing Tiles\Additive-Blend-Module\430\fragment_shader.glsl

  6. Open the fragment shader.

    All shaders are separated into two sections. Declarations are stored at global scope. The fragment shader itself is stored inside void main(void). Later, when we add nodes to the document to build our shader module, we're only going to be concerned with things declared at global scope. The body of all shaders is effectively invisible to Simdify design applications such as Module.

    // #version 430
    // The version number is automatically injected by the application.
    // It is included above for reference purposes only.
    #include <SPA_Version.glsl>
    #include <SPA_Constants.glsl>
    #include <Modules/SPA_EditStateFragmentColorOverride.glsl>
    #include "vertex_attributes.glsl"
    
    in Data { vertexData attributes; } DataIn;
    out vec4 fragColor;
    
    void main(void)
    {
       fragColor = vec4( 1.0, 0.0, 0.0, 1.0 );
       SPA_EditStateFragmentColorOverride( fragColor );
    }

    Although you can't see it in your shader code, the OpenGL shader compiler on your machine also "inserts" built-in variables so they are visible to your shader.

  7. Find the following line:
    fragColor = vec4( 1.0, 0.0, 0.0, 1.0 );

    This line assigns red to the fragment shader output.

  8. Replace it with the following:

    Copy Text To Clipboard

    fragColor = vec4( 0.0, 1.0, 0.0, 1.0 );

    This line assigns green to the fragment shader output.

  9. Save the changes to the fragment shader source code and return to the running Module application. This is a picture of the Module application rendering the geometry with green instead of red.
  10. Return to the text editor that contains the fragment shader source code.
  11. Replace the entire fragment shader with the following:

    Copy Text To Clipboard

    // #version 430
    // The version number is automatically injected by the application.
    // It is included above for reference purposes only.
    #include <SPA_Version.glsl>
    #include <SPA_Constants.glsl>
    #include <Modules/SPA_EditStateFragmentColorOverride.glsl>
    #include "vertex_attributes.glsl"
    
    in Data { vertexData attributes; } DataIn;
    
    layout( binding = 0 ) uniform sampler2D lhs;
    layout( binding = 1 ) uniform sampler2D rhs;
    uniform float blend_opacity;
    
    out vec4 fragColor;
    
    vec4 add_images( vec4 base, vec4 blend, float opacity )
    {
       return ( base * opacity ) + blend * ( 1.0 - opacity );
    }
    
    void main(void)
    {
       vec4 lhs_sample = texture( lhs, DataIn.attributes.texcoord );
       vec4 rhs_sample = texture( rhs, DataIn.attributes.texcoord );
    
       vec4 res = add_images( lhs_sample, rhs_sample, blend_opacity ); // Performs additive blending using a standard algorithm.
    
       fragColor = res;
       SPA_EditStateFragmentColorOverride( fragColor );
    }
  12. Examine the following code in the fragment shader declarations.
    layout( binding = 0 ) uniform sampler2D lhs;
    layout( binding = 1 ) uniform sampler2D rhs;
    uniform float blend_opacity;

    In the next section, we'll create nodes that represent these declarations.

  13. Save the changes to the fragment shader source code and return to the running Module application.

Build Fragment Shader Resources

  1. Examine the worksheet.

    The new shader code is running, but we haven't provided the textures and uniforms needed to generate a result. You might see white or black depending on your GPU.

    This is a picture of the Module application rendering the geometry with the additive blend shader.
  2. Right click over the the <ProgramBindNode> node named Bind Visual and select Create Source Code Item from the listed options.

    The software presents a dialog that shows you items that have been declared in your shader.

    This is a picture of the source code items dialog box.
  3. Left click layout( binding = 0 ) uniform sampler2D lhs.
  4. Hold down CTRL and left click layout( binding = 0 ) uniform sampler2D rhs and uniform float blend_opacity. This is a picture of the source code items dialog box with source code items selected.
  5. Click OK or hit ENTER when you are finished.

    The software adds the items to the hierarchy. You'll notice some of the new items have red lines underneath them. This means that there is an error.

    This is a picture of the source code items added to the hierarchy.

    Move your mouse over the <SamplerNode> named layout( binding = 0 ) uniform sampler2D lhs. You'll see a tooltip appear that displays information the error.

    This is a picture of the SamplerNode validation tooltip displaying an error message.

    To make a long story short, both of the <SamplerNode> objects expect a <Texture>.

  6. Right click over the <SamplerNode> named layout( binding = 0 ) uniform sampler2D lhs and select Load Texture From Disk from the listed options. This is a picture of the open file dialog in the texture library.

    Enter the folder named IPF_8888_ARGB.

    Copy Text To Clipboard

    IPF_8888_ARGB
  7. Select IPF_8888_ARGB.png from the listed options.

    Copy Text To Clipboard

    IPF_8888_ARGB.png
  8. Click Open or hit ENTER when you are finished.

    The software adds a <Texture> node to the document and connects the <SamplerNode> to the new <Texture> node.

    Note that the box in the middle of the worksheet may change color. It may become black. This is because we've provided only a single texture and the shader requires two textures.

  9. Select Graph > State > Expand All Tree Items from the main menu.

    You can see the new <Texture> node named IPF_8888_ARGB.

    This is a picture of the hierarchy showing the new texture.