Once you take your first steps to create your own shader modules, it will be critical to understand
how a Simdify shader module is rendered. Let's take a look!
Please refer to the following definitions as you learn about document rendering.
Simdify shader module documents use a directed acyclic graph to store content. Most
of the time we'll refer to this as the hierarchy or the graph.
Since it's a directed acyclic graph, everything is node-based as you would expect.
Shader module document hierarchies are usually fairly flat, but that's not always the case.
It's also important to note that not every node needs to be rendered. Nodes are also
frequently used to do things such as organize content or build metadata into a document.
It can be helpful to think of traversal happening as you go from the top of the hierarchy to
the bottom. If a node visited during traversal has child nodes, they will be rendered if
certain conditions are met. These conditions are usually specified by the node itself.
Let's discuss traversal and rendering for this document. NOTE: Icons that
are grey usually indicate a node that invisible, unused, or disabled in some way.
- Application visits Module
Module is a node of type <EditModel3D>. This is the root node. Traversal and rendering always starts here at the
beginning of each frame. The first test checks if Module is visible or
not. If Module is visible, the application visits
Module's child nodes in order from top-to-bottom. If Module is invisible,
the traversal process starts again, which means nothing will be traversed
or rendered. In this case, Module is visible so
the software visits its child nodes.
- Application visits Dependencies
Dependencies is a node of type <Group>. This is the first child of the root node. This node is invisible
so its child nodes are not visited. This is a good example of using nodes to organize content and store metadata. Meaning,
the application uses these nodes for its own purposes that have nothing to do with rendering.
- Application visits Includes
Includes is a node of type <IncludePaletteNode>. This node is invisible and it doesn't have any child nodes to visit.
- Application visits Locals
Locals is a node of type <DataPaletteNode>. This node is invisible and it doesn't have any child nodes to visit.
- Application visits Inputs
Inputs is a node of type <ConstraintPaletteNode>. This node is invisible
so its child nodes are not visited. Note that this node and its children are used to add metadata
to the document that describes what inputs the shader module requires. This node is only necessary
if the shader module will be used in a workflow layout.
- Application visits Outputs
Outputs is a node of type <ConstraintPaletteNode>. This node is invisible
so its child nodes are not visited.
- Application visits Shaders
Shaders is a node of type <ShaderPaletteNode>. This node is invisible
so its child nodes are not visited.
- Application visits Textures
Textures is a node of type <TexturePaletteNode>. This node is invisible
so its child nodes are not visited.
- Application visits Geometry
Geometry is a node of type <GeometryPaletteNode>. This node is invisible
so its child nodes are not visited.
- Application visits Visual
Visual is a node of type <ShaderResourceNode>. This node is visible, but it has
constraints that determine whether or not its child nodes will be visited. First, this node
requires a certain version of GLSL to be available in the <Program> node to which it is
connected. Note that the connection is not visible in the document—but you can move the
mouse over the node to see the <Program> to which it is connected, or you can double click
this node and examine the property sheet. Second, this node may or may not require
certain OpenGL extensions to be available. So, even if this node is visible, there are
used-defined constraints that control whether or not its child nodes are traversed.
- Application visits Bind Visual
Bind Visual is a node of type <ProgramBindNode>. This node is visible and it doesn't
usually have children. When this node is visited, it renders the <Program> node to which it is
connected. This activates the corresponding program in the OpenGL context, which means it can be used for rendering.
This is where workload processing begins!
- Application visits uniform mat4x4 modelViewMatrix
uniform mat4x4 modelViewMatrix is a node of type <Float32MatrixNode>. This node doesn't have
a visible/invisible state, but instead has an enabled/disabled state. At present, the dark icon indicates
that the node isn't active on the rendering device. That's because it's declared in the vertex shader but not used. Note that
this node is used here as a fallback on certain platforms, but it's not strictly needed.
- Application visits uniform mat4x4 modelViewProjectionMatrix
uniform mat4x4 modelViewProjectionMatrix is a node of type <Float32MatrixNode>. This node doesn't have
a visible/invisible state, but instead has an enabled/disabled state. At present, the light-colored icon indicates
that the node is active on the rendering device. This node captures the model-view-projection-matrix concatenation
from the application's camera system and sets it as a uniform. The vertex shader uses those values to transform vertices
from worldspace to normalized device coordinates (-1.0 to 1.0).
- Application visits uniform int image_width
uniform int image_width is a node of type <Int32Node>. This node doesn't have
a visible/invisible state, but instead has an enabled/disabled state. At present, the dark icon indicates
that the node isn't active on the rendering device. This node captures the width of a <Texture> node
and sets it as a uniform. Note that this node is used here as a fallback on certain platforms. For example:
platforms that have bugs in the imageSize() function, or GLSL versions that do not support
imageSize() at all.
- Application visits uniform int image_height
uniform int image_height is a node of type <Int32Node>. This node doesn't have
a visible/invisible state, but instead has an enabled/disabled state. At present, the dark icon indicates
that the node isn't active on the rendering device. This node captures the height of a <Texture> node
and sets it as a uniform. Note that this node is used here as a fallback on certain platforms. For example:
platforms that have bugs in the imageSize() function, or GLSL versions that do not support
imageSize() at all.
- Application visits uniform float format_min
uniform float format_min is a node of type <Float32Node>. This node doesn't have
a visible/invisible state, but instead has an enabled/disabled state. At present, the light-colored icon indicates
that the node is active on the rendering device (because it has been initialized in the shader). This node sets the texture format minimum value as
a uniform. Note that this node is used here as a fallback for certain platforms.
- Application visits uniform float format_max
uniform float format_max is a node of type <Float32Node>. This node doesn't have
a visible/invisible state, but instead has an enabled/disabled state. At present, the light-colored icon indicates
that the node is active on the rendering device (because it has been initialized in the shader). This node sets the texture format maximum value as
a uniform. Note that this node is used here as a fallback for certain platforms.
- Application visits layout( binding = 0 ) uniform sampler2D pixel_data
layout( binding = 0 ) uniform sampler2D pixel_data is a node of type <SamplerNode>. This node doesn't have
a visible/invisible state, but instead has an enabled/disabled state. At present, the light-colored icon indicates
that the node is active on the rendering device. This node is connected to a <Texture> that it binds
to the texture unit specified by the layout( binding = 0 ) component of the sampler declaration in the GLSL.
This node is the last child in the child list, so traversal returns to the parent.
- Application visits Render
Render is a node of type <ShaderResourceNode>. This node is visible, but it has
constraints that determine whether or not its child nodes will be visited. First, this node
requires a certain version of GLSL to be available in the <Program> node to which it is
connected. Note that the connection is not visible in the document—but you can move the
mouse over the node to see the <Program> to which it is connected, or you can double click
this node and examine the property sheet. Second, this node may or may not require
certain OpenGL extensions to be available. So, even if this node is visible, there are
used-defined constraints that control whether or not its child nodes are traversed.
- Application visits Mesh
Mesh is a node of type <NodeLink>. This node is visible and will be rendered.
A <NodeLink> is like a pointer to another node in the document. In this case it
points at the <ParametricMesh> named Mesh. Rendering a mesh invokes a draw call
that causes the shader to execute its workload. Rendering a mesh is always required to initiate
rendering and produce a result unless you're using compute shaders.
Close all Simdify applications started during this exercise.