Passing Data from Stage to Stage (transfer data between the various stages of rendering pipeline)

So far, you have seen how to pass data into a vertex shader by creating a vertex attribute using the in keyword (until now, you've seen how to pass data through the vertex attribute to the vertex shader), how to communicate with fixed- function blocks by reading and writing built-in variables such as gl_VertexID and gl_Position, (how to read and write by using a fixed function such as gl_VertexID built-in communications and gl_Position it?) and how to output data from the fragment shader using the out keyword (how use the out modifier output data it through the fragment shader). However, it's also possible to send your own data from shader stage to shader stage using the same in and out keywords (of course, you can also use in and out of each rendering pipeline in transfer their data between stages). just as you used the out keyword in the fragment shader to create the output variable to which it writes its color values ​​(just as you used before, use the out keyword can make fragment shader output color),so you can also create an output variable in the vertex shader by using the out keyword (you can also let the vertex shader output data in the vertex shader using the out keyword). Anything you write to an output variable in one shader is sent to a similarly named variable declared with the in keyword in the subsequent stage (you are using a modified variable output data out of the written, will be passed to the variable modified with in the next stage of the rendering pipeline of the same name). For example , if your vertex shader declares a variable called vs_color using the out keyword (for example, you use out modifying a variable called vs_color's), it would match up with a variable named vs_color declared with the in keyword in the fragment shader stage (this and will be used in the fragment shader in the modified vs_color variable pairing is successful) (assuming no other stages were active in between between (assuming that vertex shader and fragment shader no other shader))Anything you write to an output variable in one shader is sent to a similarly named variable declared with the in keyword in the subsequent stage (you are using a modified output data variables out in writing, will be passed to the next rendering pipeline stage the same name used in modified variable). For example, if your vertex shader declares a variable called vs_color using the out keyword (for example, you use out modifying a variable called vs_color's), it would match up with a variable named vs_color declared with the in keyword in the fragment shader stage (which will be paired successfully with the use of variables in a modified vs_color in the fragment shader) (assuming no other stages were active in between between (assuming that vertex shader and fragment shader no other the shader))Anything you write to an output variable in one shader is sent to a similarly named variable declared with the in keyword in the subsequent stage (you are using a modified output data variables out in writing, will be passed to the next rendering pipeline stage the same name used in modified variable). For example, if your vertex shader declares a variable called vs_color using the out keyword (for example, you use out modifying a variable called vs_color's), it would match up with a variable named vs_color declared with the in keyword in the fragment shader stage (which will be paired successfully with the use of variables in a modified vs_color in the fragment shader) (assuming no other stages were active in between between (assuming that vertex shader and fragment shader no other the shader))it would match up with a variable named vs_color declared with the in keyword in the fragment shader stage (which will be modified in vs_color variable pairing is successful and in use in the fragment shader) (assuming no other stages were active in between (assuming that vertex shader and between the fragment shader no other shader))it would match up with a variable named vs_color declared with the in keyword in the fragment shader stage (which will be modified in vs_color variable pairing is successful and in use in the fragment shader) (assuming no other stages were active in between (assuming that vertex shader and between the fragment shader no other shader))

If we modify our simple vertex shader as shown in Listing 3.3 to include vs_color as an output variable (if we modified as shown Listing3.3 our vertex shader, outputs to vs_color as our data), and correspondingly modify our simple fragment shader to includevs_color as an input variable as shown in Listing 3.4, (and the corresponding Listing3.4 declare variables shown in the fragment shader vs_color as input data) we can pass a value from the vertex shader to the fragment shader (we can a pass variables from vertex shader to fragment shader). Then, rather than outputting a hard-coded value (as compared to a hard-coded data), the fragment can simply output the color passed to it from the vertex shader (fragment shader can now vertex shader output a pass from the colors over there)

#version 450 core
// 'offset' and 'color' are input vertex attributes
layout (location = 0) in vec4 offset;
layout (location = 1) in vec4 color;
// 'vs_color' is an output that will be sent to the next shader stage
out vec4 vs_color;
void main(void)
{
const vec4 vertices[3] = vec4[3](vec4(0.25, -0.25, 0.5, 1.0),
vec4(-0.25, -0.25, 0.5, 1.0),
vec4(0.25, 0.25, 0.5, 1.0));
// Add 'offset' to our hard-coded vertex position
gl_Position = vertices[gl_VertexID] + offset;
// Output a fixed value for vs_color
vs_color = color;
}
Listing 3.3: Vertex shader with an output

As you can see in Listing 3.3, we declare a second input to our vertex shader, color (this time at location 1), and write its value to the vs_output output. This is picked up by the fragment shader of Listing 3.4 and written to the framebuffer. This allows us to pass a color all the way from a vertex attribute that we can set with glVertexAttrib* () through the vertex shader, into the fragment shader, and out to the framebuffer. As a consequence, we can draw different-colored triangles!

#version 450 core
// Input from the vertex shader
in vec4 vs_color;
// Output to the framebuffer
out vec4 color;
void main(void)
{
// Simply assign the color we were given by the vertex shader to our output
color = vs_color;
}
Listing 3.4: Fragment shader with an input

Interface Blocks

Declaring interface variables one at a time is possibly the simplest way to communicate data between shader stages (a definition of a variable is perhaps the simplest rendering communication lines each stage). However, in most nontrivial applications (However, in many programs) , you will likely want to communicate a number of different pieces of data between stages (you will pass more data); these may include arrays, structures, and other complex arrangements of variables (these might include data arrays, structures, and other complex data). to achieve this, we can group together a number of variables into an interface block (to achieve this goal, we can put a number of variables are organized into a data block to). the declaration of an interface block looks a lot like a structure declaration (declaration block declaration with structure similar), except that it is declared using the in or out keyword depending on whether it is an input to or output from the shader (except for the block and o use in ut keywords to distinguish between data blocks are input data or output data it). An example interface block definition is shown in Listing 3.

#version 450 core
// 'offset' is an input vertex attribute
layout (location = 0) in vec4 offset;
layout (location = 1) in vec4 color;
// Declare VS_OUT as an output interface block
out VS_OUT
{
vec4 color; // Send color to the next stage
} vs_out;
void main(void)
{
const vec4 vertices[3] = vec4[3](vec4(0.25, -0.25, 0.5, 1.0),
vec4(-0.25, -0.25, 0.5, 1.0),
vec4(0.25, 0.25, 0.5, 1.0));
// Add 'offset' to our hard-coded vertex position
gl_Position = vertices[gl_VertexID] + offset;
// Output a fixed value for vs_color
vs_out.color = color;
}
Listing 3.5: Vertex shader with an output interface block

Note that the interface block in Listing 3.5 has both a block name (VS_OUT, uppercase) and an instance name (vs_out, lowercase) (note the code in simultaneous Listing3.5 name and the name of its instance data block objects) . Interface blocks are matched between stages using the block name (VS_OUT in this case) (when the data block is transmitted in the name of the rendering pipeline is one to one), but are referenced in shaders using the instance name (at the time of use , but it is the name of the referenced data block instance). thus, modifying our fragment shader to use an interface block gives the code shown in Listing 3.6 (so we have to be modified as Listing3.6 in accordance with our code of fragment shader) .

#version 450 core // Declare VS_OUT as an input interface block in VS_OUT { vec4 color; // Send color to the next stage } fs_in; // Output to the framebuffer out vec4 color; void main(void) { // Simply assign the color we were given by the vertex shader to our output color = fs_in.color; }

Listing 3.6: Fragment shader with an input interface block

Matching interface blocks by block name but allowing block instances to have different names in each shader stage serves two important purposes (using the name of the data block to do one to one, but allows data blocks instances have different names have two purposes). First, it allows the name by which you refer to the block to be different in each stage (the first object, which allows you to name the rendering pipeline references can be different), thereby avoiding confusing things such as having to use vs_out in a fragment shader (this avoids some strange things, such as the use of such names vs_out in the fragment shader). second, it allows interfaces to go from being single items to arrays when crossing between certain shader stages (second, which allows data transfer time into a set of data from a data), such as the vertex and tessellation or geometry shader stages (such as the vertex shader data to the tessellation or geometry shader, we will soon be seen to), as we will see in a short while.Note that interface blocks are only for moving data from shader stage to shader stage (note that only data blocks adapted to communicate data between various stages shader) -you can not use them to group together inputs to the vertex shader or outputs from the fragment Shader (you can not use a data block of vertex shader output data from the incoming data or fragment shader).

Translations of this day to get here, see you tomorrow, bye ~

Get the latest plot first time, please pay attention to the Eastern Han Dynasty academy and the heart of the public graphic No.

Han College, waiting for you to play Oh

Guess you like

Origin blog.51cto.com/battlefire/2420884