sales@scenomics.com +1 650 396 9674

Create Gaussian Blur Shader

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 » 2D 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.
  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, a message is shown at the end of the output window like the following: Compiling Program 0x000002B69B9DC7D0 0x0000000000000000 <Program>. ( The hexadecimal codes in your message may not match exactly. ) If the shader didn't compile, you might see the grid, a black square, or a white square, depending on your GPU and the nature of the error. Please send an email to support@scenomics.com if you need technical support.

  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.

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.

    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 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 sigma = 3;
    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' <Int32Node> 'uniform int sigma'
    Adding to <UniformPaletteNode> 'Uniforms' <Int32VectorNode> 'uniform ivec4 delta'
    Adding to <SamplerPaletteNode> 'Samplers' <SamplerNode> 'layout( rgba32f ) uniform image2D SPA_Image0'
    Adding to <SamplerPaletteNode> 'Samplers' <SamplerNode> 'layout( rgba32f ) uniform image2D SPA_Image1'
    
    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 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, a new <Int32Node> named uniform int sigma, 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. 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 allows you to select the texture to load from disk:

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

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

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

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.

    This is a picture of the create texture dialog.
  3. Set Name to horz_pass
  4. Select F32 RGBA from the Pixel Format selector.

    Now that you've chosen the correct pixel format, let's use a preset to set the values here.

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

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

  7. Set Texture Width to 256.
  8. Set Texture Height to 256.
  9. 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.
  10. Select Yes from the listed options.

    The software displays the file save dialog.

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

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

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 is automatically connected to the new <Texture> node named horz_pass. The hierarchy looks like this:

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.
  4. Set New <ProgramExecute> Name to 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.

    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.
  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.
  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.
  5. Click OK or hit ENTER when you are finished.

    The software adds a <NodeLink> named horz_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.

Create Destination <Texture> For Second Pass

  1. Examine the hierarchy and find the <ShaderResourceNode> named Vert Pass Resources.
  2. Right click over the empty <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.
  5. Select Clone To New File from the Select <Texture> To Clone 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.

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

    This is a picture of the graph.

Connect First <SamplerNode>

  1. Examine the hierarchy and find the <ShaderResourceNode> named Vert Pass Resources.
  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 horz_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.
  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.

Configure Vertical Pass Uniforms

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

    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. Right click over the <Int32Node> named uniform int sigma and select Toggle GPU Download from the listed options.

    This disables GPU download since we're not going to use this as a uniform but we will use its value here for a different purpose.

    The hierarchy looks like this:

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

    This configures the compute shader to perform a vertical blur.

  8. Select File » Save from the main menu.

Copy Fragment Shader Path

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

    It's in the middle 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 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 "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 );
    }
    
  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 "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;
    }
    
  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.

    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.

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 node named values[0] and select Functions » Load Event Handler Preset from the listed options.

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

    This is a picture of the graph.
  3. Select OnNotifyKernelDimensionChanged from the Select <Float32ArrayNode> Event drop down list.
  4. Select the first entry for uniform int kernel_dimension from the Select <Int32Node> Event Source 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 <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 node named uniform int kernel_dimension and select Functions » Load Event Handler Preset 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 the first entry for uniform 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 uniform int sigma. The node uniform int kernel_dimension will update itself when it receives a notification that <Int32Node> named uniform int sigma has changed.

  7. Select File » Save from the main menu.

Evaluate Results

  1. The worksheet looks like this:

    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.

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 node named horz_pass and select Functions » Load Event Handler Preset 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. The <Texture> named source is already 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 horz_pass and connects the event to the <Texture> named source. The node 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 node named results and select Functions » Load Event Handler Preset 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. The <Texture> named source is already 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 results and connects the event to the <Texture> named source. The node 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 <ShaderResourceNode> named Horz Pass Resources.
  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 3 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 and the first pass separately for debugging.

View Source Image

  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 image used as the input to the Gaussian blur.

View Horz Pass 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 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 image 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 image 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 variable types.

  3. Choose <Float32VectorArrayNode> from the listed options.

    This will read the texture into an array of floating point vectors. This is a good choice since each pixel in the format rgba32f is a vector of floats.

  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. Examine the hierarchy and double click the <Float32VectorArrayNode> named vec4 results_read_back[65536].

    This displays node properties in the property editor.

  2. Scroll to the bottom of the property editor to see the values.

    There are more values here than you can easily review in the property sheet, but it's pretty easy to get a look at the data and see if the values are rational.

    This is a picture of the property editor.
  3. Right click over the <Float32VectorArrayNode> node named vec4 results_read_back[65536] and select Dump To Output from the listed options.

    The software dumps the <Float32VectorArrayNode> to a text file and opens an Explorer window to its location. You can open this file in a text editor and view its contents.

  4. Return to the running Shader application.
  5. Select File » Save from the main menu.

Explore Project Structure On Disk

  1. Select File » Open Containing Folder from the main menu.

    You can see the shader document and the folders containing GLSL source code.

    This is a picture of the directory that contains your new shader document.
  2. Enter the folder named 460.

    The software opens the directory containing the shader source code for GLSL #version 460. There are quite a few files here that will be explained below. You might be working in a different folder depending on the GLSL profile you specified when you created the new shader document, but this folder contains the same files as the other folders so we can look at it for the purposes of this example. Note that you can always access your shader code in these folders.

    This is a picture of the directory that contains your shader source code.
    File Description
    USER_GAUSSIAN_BLUR_ATTRIBUTES.GLSLThis GLSL source code file contains a struct that aggregates per-vertex attributes.
    USER_GAUSSIAN_BLUR_COMPUTE_SHADER.BOX.BLDContains nodes that represent all declared GLSL constructs such as uniform variables, shader buffers, uniform buffers, and structs. These files are automatically updated whenever you rebuild a shader document. This file is managed by the application and is not managed by the user.
    USER_GAUSSIAN_BLUR_COMPUTE_SHADER.GLSLThe GLSL source code for the compute shader.
    USER_GAUSSIAN_BLUR_FRAGMENT_SHADER.BOX.BLDContains nodes that represent all declared GLSL constructs such as uniform variables, shader buffers, uniform buffers, and structs. These files are automatically updated whenever you rebuild a shader document. This file is managed by the application and is not managed by the user.
    USER_GAUSSIAN_BLUR_FRAGMENT_SHADER.GLSLThe GLSL source code for the fragment shader.
    USER_GAUSSIAN_BLUR_VERTEX_SHADER.BOX.BLDContains nodes that represent all declared GLSL constructs such as uniform variables, shader buffers, uniform buffers, and structs. These files are automatically updated whenever you rebuild a shader document. This file is managed by the application and is not managed by the user.
    USER_GAUSSIAN_BLUR_VERTEX_SHADER.GLSLThe GLSL source code for the vertex shader.

    New documents that manage shader source code elements and document dependencies are added to this directory by the application from time-to-time.

  3. Close the Explorer® window.

    This exercise is complete. Return to tutorials.