You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// shader() sets the active shader, which will be applied to what is drawn next
64
+
shader(myShader);
65
+
// apply the shader to a rectangle taking up the full canvas
66
+
rect(0,0,width,height);
67
+
}
75
68
</code></pre>
76
69
70
+
<h2>Shading Language</h2>
71
+
77
72
<p>So now you might be wondering what we actually write in these shader files! Shader files are written in a
78
-
different language and have a very difference syntax and structure than we are familiar with. First let's
79
-
look at a basic vertex shader:</p>
73
+
shading language and have a very different syntax and structure than we are familiar with. WebGL Shading
74
+
language has a syntax that resembles C, which means it comes with a handful of concepts that aren't present in
75
+
JavaScript.
76
+
</p>
77
+
<p>For one, the shading language is much more strict about types. Each variable you create has to be labeled with
78
+
the kind of data it is storing. Here is a list of some of the common types
79
+
</p>
80
+
<pre><codeclass="language-javascript">
81
+
vec2(x,y) // a vector of two floats
82
+
vec3(r,g,b) // a vector of three floats
83
+
vec4(r,g,b,a) // a vector of four floats
84
+
float // a number with decimal points
85
+
int // a whole number without decimal points
86
+
sampler2D // a reference to a texture
87
+
</code></pre>
88
+
<p>In general the shading language is much more strict than JavaScript. A missing semicolon for example is not
89
+
allowed and will result in an error message. You also can't use floats and integers interchangeably.
90
+
</p>
91
+
<p>First let's look at a basic vertex shader:</p>
80
92
81
93
<pre><codeclass="language-javascript">
82
-
// shader.vert
83
-
// this is an attribute sent to the shader by p5
84
-
// it contains all of our vertex position information
85
-
// it is a vec3, meaning it contains x, y, and z data
86
-
// attribute signals that this is a global variable sent by the sketch
87
-
// it is read only, meaning it cannot be changed directly (you can copy it though)
88
-
// attributes exist in vertex shaders only
89
-
90
-
/*
91
-
an attribute is used to communicate certain information about the vertices being processed.
92
-
p5.js handles most of these attributes for you, you just need to define it here
93
-
94
-
vec3 is the type of data, in this case a vector of three numbers (x,y,z)
95
-
*/
96
-
attribute vec3 aPosition;
97
-
98
-
/*
99
-
all vertex shaders need a main() function. this function needs to have a value assigned
100
-
to gl_Position
101
-
102
-
'void' means that this function doesn't return anything
103
-
*/
104
-
void main() {
105
-
// copy the position data into a vec4, using 1.0 as the w component
106
-
vec4 positionVec4 = vec4(aPosition, 1.0);
107
-
108
-
// scale the rect by two, and move it to the center of the screen
109
-
// if we don't do this, it will appear with its bottom left corner in the center of the sketch
110
-
// try commenting this line out to see what happens
111
-
positionVec4.xy = positionVec4.xy * 2.0 - 1.0;
112
-
113
-
// send the vertex information on to the fragment shader
114
-
gl_Position = positionVec4;
115
-
}
94
+
// shader.vert
95
+
// this is an attribute sent to the shader by p5
96
+
// it contains all of our vertex position information
97
+
// it is a vec3, meaning it contains x, y, and z data
98
+
// attribute signals that this is a global variable sent by the sketch
99
+
// it is read only, meaning it cannot be changed directly (you can copy it though)
100
+
// attributes exist in vertex shaders only
101
+
102
+
/*
103
+
an attribute is used to communicate certain information about the vertices being processed.
104
+
p5.js handles most of these attributes for you, you just need to define it here
105
+
106
+
vec3 is the type of data, in this case a vector of three numbers (x,y,z)
107
+
*/
108
+
attribute vec3 aPosition;
109
+
110
+
/*
111
+
all vertex shaders need a main() function. this function needs to have a value assigned
112
+
to gl_Position
113
+
114
+
'void' means that this function doesn't return anything
115
+
*/
116
+
void main() {
117
+
// copy the position data into a vec4, using 1.0 as the w component
118
+
vec4 positionVec4 = vec4(aPosition, 1.0);
119
+
120
+
// scale the rect by two, and move it to the center of the screen
121
+
// if we don't do this, it will appear with its bottom left corner in the center of the sketch
122
+
// try commenting this line out to see what happens
123
+
positionVec4.xy = positionVec4.xy * 2.0 - 1.0;
124
+
125
+
// send the vertex information on to the fragment shader
126
+
gl_Position = positionVec4;
127
+
}
128
+
Don't worry if this doesn't make a ton of sense yet. The vertex shader plays an important role but it is often just responsible for making sure what we create in our fragment shader displays properly on the geometry. You'll probably find yourself reusing the same vertex shaders in many of your projects.
129
+
The fragment shader on the other hand is responsible for the color output of our shader and is where we will do a lot of our shader programming. Here is a very simple fragment shader that will just display the color red:
130
+
/*
131
+
the fragment shader begins with a line specifying the float 'precision'.
132
+
this value you can either be lowp, mediump, or highp, although you will likely
133
+
use mediump, or highp in certain situations
134
+
*/
135
+
precision mediump float;
136
+
137
+
/*
138
+
the fragment shader has to have a main() function, where you will do most of your
139
+
programming. main() is responsible for setting the color of the current pixel, by
140
+
assigning a vec4 (r,g,b,a) to the built-in gl_FragColor.
141
+
*/
142
+
void main() {
143
+
144
+
// this vector is just the color red
145
+
// colors are between 0.0 and 1.0, instead of 0 and 255
146
+
vec4 myColor = vec4(1.0, 0.0, 0.0, 1.0);
147
+
148
+
// and now this color is assigned to the current pixel
149
+
gl_FragColor = myColor;
150
+
}
116
151
</code></pre>
117
152
118
-
<p>Don't worry if this doesn't make a ton of sense yet. The vertex shader plays an important role but it is often just responsible for making sure what we create in
119
-
our
120
-
fragment shader displays properly on the geometry. You'll probably find yourself reusing the same vertex shaders
121
-
in many of your projects.</p>
122
153
123
-
<p>The fragment shader is responsible for the color output of our shader and is where will do a lot of our shader programming.</p>
154
+
<p>Now that we have a vertex shader and a fragment shader, these can be saved to separate files (shader.vert and
155
+
shader.frag respectively), and loaded into our sketch using loadShader().
156
+
</p>
157
+
158
+
<h2>Uniforms</h2>
159
+
<p>A simple shader like this can be useful by itself, but there are times when it's necessary to communicate
160
+
variables from the p5.js sketch to a shader. This is when uniforms come in. Uniforms are special variables that
161
+
can be sent from a sketch to a shader. These make it possible to have much more control over a shader, including
162
+
give it motion. A shader can be set up at the top of a shader, outside of main(). In this following example
163
+
fragments shader, we are creating a color uniform that will allow us to change the color from our sketch.
164
+
</p>
124
165
125
166
<pre><codeclass="language-javascript">
126
-
/*
127
-
the fragment shader begins with a line specifying the float 'precision'.
128
-
this value you can either be lowp, mediump, or highp, although you will likely
129
-
use mediump, or highp in certain situations
130
-
*/
131
-
precision mediump float;
132
-
133
-
/*
134
-
the fragment shader has to have a main() function, where you will do most of your
135
-
programming. main() is responsible for setting the color of the current pixel, by
136
-
assigning a vec4 (r,g,b,a) to the built-in gl_FragColor.
137
-
*/
138
-
void main() {
139
-
140
-
// this vector is just the color red
141
-
vec4 myColor = vec4(1.0, 0.0, 0.0, 1.0);
142
-
143
-
// and now this color is to the current pixel
144
-
gl_FragColor = myColor;
145
-
}
167
+
168
+
precision mediump float;
169
+
170
+
uniform vec3 myColor;
171
+
172
+
void main() {
173
+
174
+
// this vector is just the color red
175
+
vec4 myColor = vec4(myColor, 1.0);
176
+
177
+
// and now this color is assigned to the current pixel
178
+
gl_FragColor = myColor;
179
+
}
146
180
</code></pre>
147
181
148
-
<p>A few other things that you should know about the syntax of these shader files. First of all, the shading language
149
-
requires you to specify a <em>type</em> of data you are storing in a variable. Here is a list of the common types
150
-
182
+
<p>Back in our sketch, this color can now be sent using setUniform():
183
+
</p>
184
+
185
+
<strong>EXAMPLE SHOWING UNIFORM</strong>
186
+
187
+
<h2>Conclusion</h2>
188
+
<p>With these skills you will be able to create some basic shaders, but shader programming can go incredibly deep,
189
+
and there are many shader topics that go beyond this tutorial. Shaders in p5.js can be a powerful tool for
190
+
creating visuals, effects, and even textures that can be mapped to your 3D geometry.
151
191
</p>
152
192
153
-
<pre><codeclass="language-javascript">
154
-
vec2(x,y) // a vector of two floats
155
-
vec3(r,g,b) // a vector of three floats
156
-
vec4(r,g,b,a) // a vector of four floats
157
-
float // a number with decimal points
158
-
int // a whole number without decimal points
159
-
sampler2D // a reference to a texture
160
-
</code></pre>
161
193
162
-
<p>
163
-
The shading language is much more strict than JavaScript. A missing semicolon for example is not allowed and will
164
-
result in an error message.
194
+
<p>The following websites are great resources for shader programming:
165
195
</p>
166
196
167
-
{{!-- <p>Shaders are separate programs that run on the graphics card, and as a result, they have a very different
168
-
syntax
169
-
and structure than what we are familiar with in p5.js. They are written in a shader language, which has a syntax
170
-
similar to the programming language, C. They are also programs that run on a single pixel, and as a result, they
171
-
sometimes require you to think a little bit differently. </p> --}}
0 commit comments