Create Gaussian Blur Shader

You need the following Scenome® modules to complete this exercise: Scenome® Platform Binaries, Scenome® Compute Module, Scenome® Buffer Module

In this exercise you'll learn to implement a compute shader that performs a Gaussian blur. This exercise requires GLSL version 400 or higher.

Start The Application

  1. Start the Shader app. (Start » <Program>s » Scenomics » Shader) or (Windows® key and then type 'Shader' to find the app icon.)

    The application displays a splash screen and then the application desktop appears. The main menu is composed of three items that contain commands relevant to the current context (which is an empty document). As you will see, the interface changes when you create a new file or load a file from disk.

    This is a picture of the desktop.

Create A New Shader

  1. Select File » New » Shader from the main menu.

    The software displays a wizard that allows you to specify the parameters of your new shader.

    This is a picture of the new project dialog.
  2. Set the Name field to User Gaussian Blur.

    Copy Text To Clipboard

    User Gaussian Blur
  3. Set Profile to the highest value available such as 460 core.

    Note that your GPU must support GLSL 400 or higher to proceed. Otherwise you will not be able to set Add Compute Support to true and you cannot proceed with this exercise.

  4. Set Add Compute Support to True.
  5. Hit ENTER or click OK when you are finished.

    The application creates a new shader document and the main menu options change. You can see the hierarchy on the left, the rendered shader with geometry in the middle, and the property sheet on the right. Application messages, such as shader compiler error messages, are shown in the output window below.

    This is a picture of the workspace.

    If the shader compiled successfully, you should see a red square in the center of the worksheet.

  6. Select File » Save from the main menu.

Examine The Document

  1. Examine the main menu and select Graph » State » Expand All Tree Items. ( Or hit ALT + X ).

    This expands the graph so that you can see all the nodes. As you can see, this shader is a composite data structure made from a set of atomic types. The template document used to create the new file was built with a Scenome application named Graph.

    You can hover over each node icon, in the image below, for a description of the node and its function.

    That covers the basic information about the graph.

Rename 'Compute Resources'

  1. Return to the running Shader app.
  2. Examine the graph and find the <ShaderResourceNode> named Compute Resources. This is a picture of the hierarchy.
  3. Right click over Compute Resources and select Rename... from the listed options.

    The software presents the rename dialog.

    This is a picture of the rename dialog.
  4. Type Horz Pass Resources and click OK or hit ENTER when you are finished.

    Copy Text To Clipboard

    Horz Pass Resources

Rename 'Execute Compute'

  1. Examine the graph and find the <ProgramExecute> node named Execute Compute.

    It's near the bottom of the graph. You may have to scroll to find it.

    This is a picture of the hierarchy.
  2. Right click over Execute Compute and select Rename... from the listed options.
  3. Type Execute Horz Pass and click OK or hit ENTER when you are finished.

    Copy Text To Clipboard

    Execute Horz Pass

    Note Using clear, precise names helps you learn faster and understand more.

  4. Select File » Save from the main menu.

Copy Compute Shader Path

  1. Examine the hierarchy and find the <Program> node named Compute.

    It's near the top of the hierarchy.

    This is a picture of the hierarchy.
  2. Right click over the <Program> node named Compute and select Copy Source Path » Compute Shader from the listed options.

    This displays a dialog that allows you to select GLSL shader source code (and any include files). The file path of the source item you select will be copied to the Windows® clipboard so you can open it in a text editor.

  3. Select user_gaussian_blue_compute_shader.glsl and click OK or hit ENTER when you are finished.

    This copies the absolute path to the compute shader source code to the Windows® clipboard. For example, a file path like the following: D:\Release6\Content\Library\Shader\User Gaussian Blur\460\user_gaussian_blur_compute_shader.glsl is copied to the clipboard.

Implement Gaussian Blur Compute Shader

  1. Start a text editor of your choice and select the option to open a file from disk.
  2. Select CTRL + V to paste the fragment shader file path (into the place in the dialog where you specify the file to open) and open the file.

    This is the basic compute shader. Note that your #version 460 declaration might be different, depending on the highest GLSL version on your machine.

    // #version 460
    // The version number is automatically injected by the application.
    // It is included above for reference purposes only.
    
    #extension GL_ARB_compute_variable_group_size : enable
    #ifdef GL_ARB_compute_variable_group_size
       layout( local_size_variable ) in;
    #else
       layout( local_size_x = 32, local_size_y = 32, local_size_z = 1 ) in;
    #endif
    
    void main(void)
    {
    }
    
  3. Replace the entire compute shader with the following code:

    Copy Text To Clipboard

    #extension GL_ARB_compute_variable_group_size : enable
    #ifdef GL_ARB_compute_variable_group_size
       layout( local_size_variable ) in;
    #else
       layout( local_size_x = 32, local_size_y = 32, local_size_z = 1 ) in;
    #endif
    
    layout( rgba32f ) uniform image2D src_image;
    layout( rgba32f ) uniform image2D dst_image;
    
    // Uniforms, constants, and buffers that
    // configure the Gaussian kernel values,
    // and allow us to dynamically resize the
    // Gaussian kernel without changing the
    // shader code.
    uniform int kernel_dimension = 21;
    int kernel_start = kernel_dimension / 2;
    uniform ivec4 delta;
    
    layout( shared ) buffer gaussian_filter
    {
       float values[];
    };
    
    void main(void)
    {
       ivec2 pos = ivec2( gl_GlobalInvocationID );
       ivec2 src_dims = imageSize( dst_image );
    
       vec4 accum_results = vec4( 0.0 );
       int filter_index_x = 0;
       //vec4 tempsrc = imageLoad( src_image, pos );
       //vec4 tempdst = imageLoad( dst_image, pos );
    
       for( int i = -kernel_start; i < kernel_start; ++i )
       {
          ivec2 read_coord = pos + delta.xy * i;
          read_coord = clamp( read_coord, ivec2( 0 ), src_dims - 1 );
    
          accum_results += imageLoad( src_image,
          read_coord ) * values[ filter_index_x ];
          ++filter_index_x;
       }
    
       // Store the results in the second image sampler.
       // We will perform the second pass on these values.
       imageStore( dst_image, pos, accum_results );
    }
    

    This is the Gaussian blur compute shader. It performs the Gaussian blur in the horizontal or vertical direction depending on the value of uniform ivec4 delta. Since this compute shader only performs the blur in a single direction at a time, we'll need to implement two compute passes to compute the complete horizontal and vertical blur. We won't delve into the details of the blurring algorithm since you have the full source code and can examine this later.

  4. Use the text editor to save the shader code to disk and return to the Shader application.

    Now that we've modified the shader source code, we'll need to rebuild the document so we can configure the resources specified by the shader.

  5. Return to the running Shader application.

    Depending on your GPU, your on screen results may disappear or change when you return. Do not worry about this.

Rebuild The Document

  1. Select Graph » Build All from the main menu.

    The software presents the build warning dialog.

    The software warns you that rebuilds can cause changes to shader appearance. During a rebuild, the shader source for all <Program> nodes and ( and <Program> nodes specified by <ProgramExecute> nodes ) in the document is traversed and converted into a .BOX file that contains nodes representing all declared uniforms, uniform buffers, shader buffers, and structs. This information is used to automatically add the correct resources to the document and to delete obsolete resources.

  2. Click OK to proceed.

    The software rebuilds the shaders and adds resources to the document.

    --- <Building Project 'D:\Release6\Content\Library\Shader\User Gaussian Blur\User Gaussian Blur.box'> ---
    
    Rebuilding Shader Resource Documents...
    
    Rebuild succeeded: D:\release6\content\library\shader\user gaussian blur\460\user_gaussian_blur_compute_shader.glsl
    Rebuild succeeded: D:\release6\content\library\shader\user gaussian blur\460\user_gaussian_blur_vertex_shader.glsl
    Rebuild succeeded: D:\release6\content\library\shader\user gaussian blur\460\user_gaussian_blur_fragment_shader.glsl
    
    Updating document contents...
    
    Creating <ShaderBufferBindNode> for <ShaderBufferNode> : buffer gaussian_filter
    Adding to <UniformPaletteNode> 'Uniforms' <Int32Node> 'uniform int kernel_dimension'
    Adding to <UniformPaletteNode> 'Uniforms' <Int32VectorNode> 'uniform ivec4 delta'
    Adding to <SamplerPaletteNode> 'Samplers' <SamplerNode> 'layout( rgba32f ) uniform image2D src_image'
    Adding to <SamplerPaletteNode> 'Samplers' <SamplerNode> 'layout( rgba32f ) uniform image2D dst_image'
    
    Build completed.
    
  3. Select File » Save from the main menu.

Examine The Document

  1. Select Graph » State » Expand All Tree Items from the main menu. ( Or hit ALT + X )

    You can see new nodes in the graph.

    This is a picture of the graph.

    In Includes there is a <FileNode> named user gaussian blur.compute.glsl.objects.box.bld, and a <NodeLink> named buffer gaussian_filter that will store the Gaussian kernel values.

    In Compute Shader there is a <ShaderBufferBindNode> named gaussian_filter, and a <Float32ArrayNode> named values[0] that will store the Gaussian kernel values.

    In the Horz Pass Resources section of the graph there is a new <Int32Node> named uniform int kernel_dimension, and a new <Int32VectorNode> named uniform ivec4 delta.

    Finally there are two new <SamplerNodes> with red underlines named layout( rgba32f ) uniform image2D src and layout( rgba32f ) uniform image2D dst. Note that all the resource names exactly match the names of the declarations in the compute shader source code. In the Shader application, you can move the mouse over the new <SamplerNode> to see that these <SamplerNodes> need to be connected to <Texture> nodes.

    This is a common situation. You have samplers, but no textures. The Shader app allows you to create new textures that are compatible with a specific <SamplerNode>, or to load compatible textures from disk and connect them to a specific <SamplerNode>. We'll do both in this exercise.

Load Source <Texture>

  1. Examine the hierarchy and find the <SamplerNode> named layout( rgba32f ) uniform image2D src_image. Note that its icon is grayed out. This means that it isn't binding any <Texture> to the GPU. This is a picture of the graph.
  2. Right click over the <SamplerNode> named layout( rgba32f ) uniform image2D src_image and select Load Texture From Disk... from the listed options.

    The software displays a dialog box that displays a list of folders for each pixel format. This is a picture of the file open dialog.

  3. Type IPF_FP32x4 and click Open to go into the folder containing 32-bit, 4-channel floating point textures.

    Copy Text To Clipboard

    IPF_FP32x4

    The dialog displays a list of textures:

    This is a picture of the file open dialog.
  4. Type IPF_FP32x4.image and click OK or hit ENTER when you are done.

    Copy Text To Clipboard

    IPF_FP32x4.image

    The application creates a new <Texture> node and adds it to the document.

  5. Select File » Save from the main menu.

Rename The <Texture>

  1. Select Graph » State » Expand All Tree Items from the main menu. ( Or hit ALT + X )
  2. Examine the hierarchy.

    There is a new <Texture> node named IPF_FP32x4.

    This is a picture of the graph.

    If you examine the hierarchy, you can see the <SamplerNode> icon is no longer grayed out. This means it is downloading the associated <Texture> to the GPU.

    This is a picture of the graph.
  3. Right click over the <Texture> node named IPF_FP32x4 and select Rename... from the listed options.
  4. Set the name of the node to source and click OK or hit ENTER when you are finished.

    Copy Text To Clipboard

    source
  5. Select File » Save from the main menu.

Create Destination <Texture>

  1. Examine the hierarchy.
  2. Right click over the <SamplerNode> named layout( rgba32f ) uniform image2D dst_image and select Create Texture... from the listed options.

    The software displays the create texture dialog. Note that some of the options are disabled. This is because the wizard knows what type of texture format, topology, and binding are required by the <SamplerNode> we selected. We've already specified the source texture, which the compute shader will read, and now we're going to create the destination texture into which the compute shader will write.

    This is a picture of the create texture dialog.
  3. Set Name to horz_pass.

    Copy Text To Clipboard

    horz_pass
  4. Left click the Preset... button on the right side of the Choose Preset field.

    The software displays a dialog that allows you to load preset values from disk.

  5. Left click fill_image_halfs.txt and click Open or hit ENTER when you are finished.

    The channel values are automatically filled with the values 0.5, 0.5, 0.5, 0.5.

  6. Set Texture Width to 256.
  7. Set Texture Height to 256.
  8. Click OK or hit ENTER when you are finished.

    The software asks if you wish to save the texture to disk:

    This is a picture of the save to disk query dialog.
  9. Select Yes from the listed options.

    The software displays the file save dialog.

  10. Type user_gaussian_blur_horz_pass.image and click SAVE or hit ENTER when you are finished.

    Copy Text To Clipboard

    user_gaussian_blur_horz_pass.image

    The software saves the new texture to disk and adds a <Texture> node named horz_pass.

  11. Select File » Save from the main menu.

Examine The Document

  1. Examine the hierarchy.

    There is a new <Texture> node named horz_pass.

    This is a picture of the graph.
  2. The new <Texture> will store the results from the horizontal pass of the Gaussian blur. Note that the <SamplerNode> named layout( rgba32f ) uniform image2D dst_image was connected to the new <Texture> node named horz_pass when we created the new <Texture>.

Configure Horizontal Pass Uniforms

  1. Examine the hierarchy and find the <ShaderResourceNode> named Horz Pass Resources. This is a picture of the graph.
  2. Examine the hierarchy and double click the <Int32VectorNode> named uniform ivec4 delta.

    This displays node properties in the property editor on the right side of the workspace.

  3. Scroll down and find the property group named Vector Parameters.
  4. Set int32[0] to 1.

    This configures the compute shader to perform a horizontal blur.

  5. Select File » Save from the main menu.

Create Vertical Pass

  1. Examine the hierarchy and find the <ProgramExecute> node named Execute Horz Pass.

    It's near the bottom of the graph. You may have to scroll to find it.

    This is a picture of the graph.
  2. Right click over the <ProgramExecute> node named Execute Horz Pass and select Clone Compute Pass from the listed options.

    The software presents the clone pass dialog to allow you to configure the clone operation.

    This is a picture of the clone compute dialog.
  3. Set New Resource Group Name to Vert Pass Resources.

    Copy Text To Clipboard

    Vert Pass Resources
  4. Set New <ProgramExecute> Name to Execute Vert Pass.

    Copy Text To Clipboard

    Execute Vert Pass
  5. Leave Insert Memory Barrier set to true.
  6. Click OK or hit ENTER when you are finished.

    The software adds new resources to the document.

  7. Select File » Save from the main menu.

Examine The Document

  1. Select Graph » State » Expand All Tree Items from the main menu. ( Or hit ALT + X )

    You can see new nodes in the Vert Pass Resources section of the graph. This is essentially a clone of the resources used by the first pass. We're going to modify these to implement a second compute pass that will generate the vertical component of the blur.

    This is a picture of the graph.

Configure Memory Barrier

  1. Examine the hierarchy and look near the bottom.
  2. Right click over the <MemoryBarrierNode> named Memory Barrier and select Set Flags... from the listed options.

    The software displays a dialog that allows you to configure memory barrier flags. Note that only the most comonly used memory barrier flags are displayed here. You can double click the <MemoryBarrierNode> to set flags not shown here. You can also review the OpenGL documentation for these flags.

    This is a picture of the graph.
  3. Set the first option, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT to true and click OK or hit ENTER when you are finished.

    This memory barrier tells OpenGL to ensure image writes in the first pass are finished before the second pass starts.

Clean Vert Pass Resources

  1. Examine the hierarchy and find the <ShaderResourceNode> named Vert Pass Resources.
  2. Examine the hierarchy and find the <TexturePaletteNode> named Textures that is below Vert Pass Resources. This is a picture of the graph.
  3. Right click over the <Texture> named source and select Delete from the listed options.
  4. Right click over the <Texture> named horz_pass and select Delete from the listed options. This is a picture of the graph.
  5. Select File » Save from the main menu.

Create Source <Texture> For Second Pass

  1. Examine the hierarchy and find the <ShaderResourceNode> named Vert Pass Resources. This is a picture of the graph.
  2. Right click over the <TexturePaletteNode> named Textures and select Clone Texture... from the listed options.

    The software presents a dialog that allows you to create a clone of an existing <Texture> in the document. You can create a direct clone which references the same file on a disk, a direct clone that references create a copy of the texture source file on disk, or a clone that creates a <NodeLink> (which is a hyperlink) to a <Texture> in this document. In this case, we'll create a <NodeLink> to an existing <Texture> in the document.

    This is a picture of the clone texture dialog.
  3. Select horz_pass from the Select <Texture> To Clone drop down menu.
  4. Set New Name to vert_pass.

    Copy Text To Clipboard

    vert_pass
  5. Click OK or hit ENTER when you are finished.

    The software adds a <NodeLink> named vert_pass to the hierarchy. This allows us to use the results of the first pass of the compute shader (which is the horizontal blur) as the input to the second pass of the compute shader (which will perform the vertical blur).

    This is a picture of the graph.

    A <NodeLink> is a hyperlink to another node, or you can also think of it as a pointer if you are more comfortable with that nomenclature. In this case, we are using a <NodeLink> because we want to use the results of the first compute pass (the horizontal blur) as the input for the second compute pass (the vertical blur). The <NodeLink> refers to the same OpenGL resource so that the compute shader can perform the vertical blur on the correct data.

    You can distinguish <NodeLinks> from regular nodes by the dotted outline around the node icon. When you move the mouse over the node, a <NodeLink> to a <Texture> displays different hint text than than a <Texture>.

Create Destination <Texture> For Second Pass

  1. Examine the hierarchy and find the <ShaderResourceNode> named Vert Pass Resources. This is a picture of the graph.
  2. Right click over the <TexturePaletteNode> named Textures and select Clone Texture... from the listed options.

    The software presents a dialog that allows you to create a clone of an existing <Texture> in the document. In this case, we'll create a <Texture> that points to a clone of an existing file on disk.

    This is a picture of the clone texture dialog.
  3. Select horz_pass from the Select <Texture> To Clone drop down menu.
  4. Set New Name to results.

    Copy Text To Clipboard

    results
  5. Select Clone To New File from the Select Clone Operation drop down menu.
  6. Click OK or hit ENTER when you are finished.

    The software presents a dialog that allows you to set the name of the new file on disk.

  7. Type user_gaussian_blur_vert_pass.image and click Save or hit ENTER when you are ready.

    Copy Text To Clipboard

    user_gaussian_blur_vert_pass.image

    The software adds a new <Texture> named results to the graph.

    This is a picture of the graph.

    The new <Texture> icon is grayed out. This means that it is not resident on the GPU. Notice also that both <SamplerNode> icons are grayed out. This lets us know that the <SamplerNode> objects are not binding anything to the GPU.

Connect First <SamplerNode>

  1. Examine the hierarchy and find the <ShaderResourceNode> named Vert Pass Resources. This is a picture of the graph.
  2. Right click over the <SamplerNode> named layout( rgba32f ) uniform image2D src_image and choose Select Texture from the listed options.

    The software presents a dialog that allows you to select a <Texture> or <NodeLink> to a <Texture>.

    This is a picture of the graph.
  3. Left click the <NodeLink> named vert_pass ( which is the last item in the list ) and click OK or hit ENTER when you are finished.

Connect Second <SamplerNode>

  1. Examine the hierarchy and find the <ShaderResourceNode> named Vert Pass Resources. This is a picture of the graph.
  2. Right click over the <SamplerNode> named layout( rgba32f ) uniform image2D dst_image and choose Select Texture from the listed options.

    The software presents a dialog that allows you to select a <Texture> or <NodeLink> to a <Texture>.

  3. Left click the <Texture> named results and click OK or hit ENTER when you are finished.

    The hierarchy looks like this:

    This is a picture of the graph.

    The new <Texture> icon is no longer grayed out. This means that it is resident on the GPU. Notice also that both <SamplerNode> icons are no longer grayed out. This lets us know that the <SamplerNode> objects are binding <Texture> objects to the GPU.

Configure Vertical Pass Uniforms

  1. Examine the hierarchy and find the <ShaderResourceNode> named Vert Pass Resources. This is a picture of the graph.
  2. Right click over the <Int32Node> named uniform int kernel_dimension and select Toggle GPU Download from the listed options. This is a picture of the graph.

    You'll notice the icon turns gray. This disables GPU download since we're already setting the value of this uniform in one place and we don't want or need to set it for the second compute pass.

  3. Examine the hierarchy and double click the <Int32VectorNode> named uniform ivec4 delta. Note that this is the node below Vert Pass Resources.
  4. Scroll down and find the property group named Integer Vector Parameters.
  5. Set int32[0] to 0.
  6. Set int32[1] to 1.

    This configures the compute shader to perform a vertical blur.

  7. Select File » Save from the main menu.

Copy Fragment Shader Path

  1. Examine the hierarchy and find the <ShaderResourceNode> named Visual Shader.

    It's toward the bottom of the hierarchy.

    This is a picture of the graph.
  2. Find the <Program> node named Program and select Copy Source Path » Fragment Shader from the listed options.

    This displays a dialog that allows you to select GLSL shader source code (and any include files). The file path of the source item you select will be copied to the Windows® clipboard so you can open it in a text editor.

  3. Select user_compute_exercise_fragment_shader.glsl and click OK or hit ENTER when you are finished.

    This copies the absolute path to the compute shader source code to the Windows® clipboard. For example, a file path like the following: D:\Release6\Content\Library\Shader\User Gaussian Blur\460\user_gaussian_blur_compute_shader.glsl is copied to the clipboard.

Modify Fragment Shader

  1. Return to the running text editor that contains the compute shader and select the option to open a file from disk.
  2. Select CTRL + V to paste the fragment shader file path (into the place in the dialog where you specify the file to open) and open the file.

    This is the fragment shader. Note that your #version 460 declaration might be different, depending on the highest GLSL version on your machine.

    // #version 460
    // 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 "user_gaussian_blur_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 );
    }
    
  3. Replace the fragment shader with the following:

    Copy Text To Clipboard

    // #version 460
    // 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 "user_gaussian_blur_attributes.glsl"
    
    in Data { vertexData attributes; } DataIn;
    
    uniform sampler2D dst_image;
    
    out vec4 fragColor;
    
    void main(void)
    {
       vec4 diffuse = texture( dst_image, DataIn.attributes.texcoord );
       fragColor = diffuse;
       SPA_EditStateFragmentColorOverride( fragColor );
    }
    
  4. Save the file in the text editor and return to the running Shader application.

    The results on screen are going to change, turning black or white depending on your GPU. This is normal.

Rebuild The Document

  1. Select Graph » Build All from the main menu.

    The software presents the build warning dialog.

  2. Click OK to proceed.

    The software rebuilds the shaders and adds resources to the document.

    --- <Building Project 'D:\Release6\Content\Library\Shader\User Gaussian Blur\User Gaussian Blur.box'> ---
    
    Rebuilding Shader Resource Documents...
    
    Rebuild succeeded: D:\release6\content\library\shader\user gaussian blur\460\user_gaussian_blur_compute_shader.glsl
    Rebuild succeeded: D:\release6\content\library\shader\user gaussian blur\460\user_gaussian_blur_vertex_shader.glsl
    Rebuild succeeded: D:\release6\content\library\shader\user gaussian blur\460\user_gaussian_blur_fragment_shader.glsl
    
    Updating document contents...
    
    Adding to <SamplerPaletteNode> 'Samplers' <SamplerNode> 'uniform sampler2D dst_image'
    
  3. Select File » Save from the main menu.

Connect Visual Resources <SamplerNode>

  1. Select Graph » State » Expand All Tree Items from the main menu. ( Or hit ALT + X )

    You can see there is a new <SamplerNode> named uniform sampler2D dst_image below Visual Resources.

    This is a picture of the graph.
  2. Right click over the <SamplerNode> named uniform sampler2D dst_image and choose Select Texture from the listed options.

    The software presents a dialog that allows you to select a <Texture> or <NodeLink> to a <Texture>.

  3. Left click the <Texture> named results and click OK or hit ENTER when you are finished.

Declaring A Local Variable

  1. Examine the hierarchy and find the <DataPaletteNode> node named Locals.

    It's near the top of the hierarchy.

    This is a picture of the graph.

    We need to declare a local variable that will let us set the strength of the blur. Yes, we could declare this in our shader code, but it's not really necessary to do that.

  2. Right click over the <DataPaletteNode> node named Locals and select Add Local Variable... from the listed options.

    The software displays a list of variable types.

    This is a picture of the local variable type select dialog.
  3. Type Int32Node and click OK when you are finished.

    The software adds an <Int32Node> as a child of Locals.

  4. Select Graph » State » Expand All Tree Items from the main menu. ( Or hit ALT + X ).
  5. Examine the hierarchy and find the new <Int32Node> named UNNAMED. This is a picture of the graph.
  6. Right click over the <Int32Node> named UNNAMED and select Edit... from the listed options. from the listed options.

    The software presents a dialog that allows you to edit the <Int32Node>. Note that the <Int32Node> Name value is not the same as the name of the <Int32Node>. This is a picture of the Int32Node edit dialog.

  7. Set Name to sigma.
  8. Set Fill Value to 5 and click OK or hit ENTER when you are finished. This is a picture of the graph.

Add Event Handling To <Float32ArrayNode> 'values[0]'

  1. Examine the hierarchy and find the <Float32ArrayNode> node named values[0]. This is a picture of the graph.

    Note that this is declared as an unsized array in the compute shader source code. We're going to implement event handling that controls the size of this array and changes the Gaussian kernel values based on changes to other nodes in the document.

  2. Right click over the <Float32ArrayNode> node named values[0] and select Events » Add Event Handler... from the listed options.

    The software displays a dialog that allows you to select predefined event handlers.

    This is a picture of the event handler wizard.
  3. Select OnNotifyKernelDimensionChanged from the Event Name drop down list.

    The dialog updates with settings specific to the event.

    This is a picture of the event handler wizard.
  4. Select the first entry for uniform int kernel_dimension from the Source 'Kernel Dimension' drop down list
  5. Click OK or hit ENTER when you are finished.

    The software adds an event to values[0] and connects the event to the <Int32Node> named uniform int kernel_dimension. The node values[0] will update itself when it receives a notification that the <Int32Node> named uniform int kernel_dimension has changed.

Add Event Handling To <Int32Node> 'uniform int kernel_dimension'

  1. Examine the hierarchy and find the <ShaderResourceNode> named Horz Pass Resources.
  2. Examine the hierarchy and find the first <Int32Node> node named uniform int kernel_dimension. This is a picture of the graph.
  3. Right click over the <Int32Node> node named uniform int kernel_dimension and select Events » Add Event Handler... from the listed options.

    The software displays a dialog that allows you to select predefined event handlers.

    This is a picture of the graph.
  4. Select OnNotifySigmaChanged from the Select <Int32Node> Event drop down list.
  5. Select int sigma from the Select <Int32Node> Event Source drop down list
  6. Click OK or hit ENTER when you are finished.

    The software adds an event to uniform int kernel_dimension and connects the event to the <Int32Node> named int sigma. The node uniform int kernel_dimension will update itself when it receives a notification that the <Int32Node> named int sigma has changed.

  7. Select File » Save from the main menu.

Evaluate Results

  1. Examine the worksheet: This is a picture of the worksheet.

    The on-screen results now show us the image being written by the compute shader. You can see the Gaussian blur is correct. However because of the sizes of various <Texture> nodes, the blur only works for <Texture> nodes that match the dimensions of this source image, which is 256×256 pixels. We can create additional event handlers to resize images as needed so that this works with different sized source images. Note also that the Gaussian blur only works on 4-channel floating point textures. That is going to remain a requirement. It's better to write another shader if you need to apply a Gaussian blur to a different image format.

Add Event Handling To <Texture> 'horz_pass'

  1. Examine the hierarchy and find the <ShaderResourceNode> named Horz Pass Resources.
  2. Examine the hierarchy and find the <Texture> node named horz_pass. This is a picture of the graph.
  3. Right click over the <Texture> node named horz_pass and select Events » Add Event Handler... from the listed options.

    The software displays a dialog that allows you to select predefined event handlers.

    This is a picture of the event handler wizard.
  4. Select OnNotifySourceDimChanged from the Select <Texture> Event drop down list.
  5. Leave the <Texture> named source selected in the <Texture> Event Source drop down list.
  6. Click OK or hit ENTER when you are finished.

    The software adds an event to the <Texture> node horz_pass and connects the event to the <Texture> named source. The node <Texture> node named horz_pass will update itself when it receives a notification that the <Texture> named source has changed.

Add Event Handling To <Texture> 'results'

  1. Examine the hierarchy and find the <ShaderResourceNode> named Vert Pass Resources.
  2. Examine the hierarchy and find the <Texture> node named results. This is a picture of the graph.
  3. Right click over the <Texture> node named results and select Events » Add Event Handler... from the listed options.

    The software displays a dialog that allows you to select predefined event handlers.

    This is a picture of the graph.
  4. Select OnNotifySourceDimChanged from the Select <Texture> Event drop down list.
  5. Leave the <Texture> named source selected in the <Texture> Event Source drop down list.
  6. Click OK or hit ENTER when you are finished.

    The software adds an event to the <Texture> node named results and connects the event to the <Texture> named source. The node <Texture> node named results will update itself when it receives a notification that <Texture> named source has changed.

  7. Select File » Save from the main menu.

Modify Blurriness

  1. Examine the hierarchy and find the <Int32Node> named sigma.

    It's near the top of the hierarchy.

  2. Examine the hierarchy and double click the first <Int32Node> named uniform int sigma.

    This displays node properties in the property editor.

  3. Examine the property editor and scroll down until you find the Value property group.
  4. Change the value of the property field named int from 5 to 8.

    The blurriness increases.

    This is a picture of the worksheet.

    Right now the visual shader shows us the results, but we can also view the source <Texture> node and the first pass <Texture> node separately for debugging.

View Source <Texture>

  1. Examine the hierarchy and find the <ShaderResourceNode> named Visual Resources.
  2. Find the <SamplerNode> named uniform sampler2D dst_image. This is a picture of the worksheet.
  3. Right click over the <SamplerNode> node named uniform sampler2D dst_image and choose Select Texture from the listed options.

    The software displays a list of compatible <Texture> nodes.

  4. Select source from the listed options. This is a picture of the worksheet.

    This is the source imagery used as the input to the Gaussian blur.

View Horz Pass <Texture>

  1. Again right click over the <SamplerNode> node named uniform sampler2D dst_image and choose Select Texture from the listed options.

    The software displays a list of compatible <Texture> nodes.

  2. Select horz_pass from the listed options and click OK or hit ENTER when you are finished. This is a picture of the worksheet.

    This is the horizontal pass generated by the compute shader.

View Results Image

  1. Again right click over the <SamplerNode> node named uniform sampler2D dst_image and choose Select Texture from the listed options.

    The software displays a list of compatible <Texture> nodes.

  2. Select results from the listed options and click OK or hit ENTER when you are finished. This is a picture of the worksheet.

    This is the vertical pass generated by the compute shader, and it contains the final results of the Gaussian blur.

Create Readback

  1. Examine the hierarchy and find the <ShaderResourceNode> named Vert Pass Resources. This is a picture of the graph.
  2. Right click over the <Texture> node named results and select Readback from the listed options.

    The software displays a list of compatible readback object types.

  3. Choose <Texture> from the listed options.

    This will read the OpenGL® texture into a <Texture> object that we can inspect with the Magnifier tool.

  4. Click OK or hit ENTER when you are finished.

    The software creates the readback node items and adds them to the end of the document.

  5. Select Graph » State » Expand All Tree Items from the main menu. ( Or hit ALT + X ) This is a picture of the graph.

Verify Results

  1. Select Tool » Magnifier from the main menu.

    The Magnify editor appears.

    This is a picture of the workspace.
  2. Examine the Magnify editor and select results_readback from Texture to magnify list.
  3. If you move the mouse over the rendered geometry, you can see the values written by the compute shader.

    This is a picture of the Magnify editor.
  4. Select File » Save from the main menu.