This article assumes you’ve read many of the other articles starting with the fundamentals. If you have not read them please start there first.
I don’t really know what to file this article under because it has two purposes.
Show you the smallest WebGL programs.
These techniques are super useful for testing something or when making an MCVE for Stack Overflow or when trying to narrow down a bug.
Learning to think outside the box
I hope to write several more articles on this to help you see the bigger picture rather than just the common patterns. Here’s one.
Here’s the smallest WebGL program that actually does something
All this program does is clear the canvas to red but it did actually do something.
Think about it through. With just this you can actually test some things. Let’s say you are rendering to a texture but things aren’t working. Let’s say it’s just like the example in that article. You’re rendering 1 or more 3D things into a texture then rending that result onto a cube.
You’re not seeing anything. Well, as a simple test, stop rendering to the texture with shaders are just clear the texture to a known color.
Now render with the texture from the framebuffer. Does your cube turn magenta? If not then your issue is not the rendering to the texture part it’s something else.
SCISSOR_TEST
and gl.clear
The SCISSOR_TEST
clips both drawing and clearing to some sub rectangle of the canvas (or current framebuffer).
You enable the scissor test with
and then you set the scissor rectangle in pixels relative to the bottom left corner. It uses the same parameters
as gl.viewport
.
Using that can draw rectangles using the SCISSOR_TEST
and gl.clear
.
Example
Not saying that particular one is all that useful but still it’s good to know.
gl.POINTS
As most of the examples show, the most common thing to do in WebGL is create buffers. Put vertex data in those buffers. Create shaders with attributes. Set up the attributes to pull data from those buffers. Then draw, possibly with uniforms and texture also used by your shaders.
But sometimes you just want to test. Let’s say you want just see something draw.
How about this set of shaders
And here’s the code to use it
No buffers to create, no uniforms to setup, and we get a single point in the middle of the canvas.
About gl.POINTS
: When you pass gl.POINTS
to gl.drawArrays
you’re also
required to set gl_PointSize
in your vertex shader to a size in pixels. It’s
important to note that different GPU/Drivers have a different maximum point size
you can use. You can query that maximum size with
The WebGL spec only requires a max size of 1.0. Fortunately most if not all GPUs and drivers support a larger size.
After you set gl_PointSize
then when the vertex shader exits, whatever value you set on gl_Position
is converted
to screen/canvas space in pixels, then a square is generated around that position that is +/- gl_PointSize / 2 in all 4 directions.
Okay, I can hear you thinking so what, who wants to draw a single point.
Well, points automatically get free texture coordinates. They are available in the fragment
shader with the special variable gl_PointCoord
. So, let’s draw a texture on that point.
First let’s change the fragment shader.
Now to keep it simple let’s make a texture with raw data like we covered in the article on data textures.
Because WebGL defaults to using texture unit 0 and because uniforms default to 0 there is nothing else to setup
This can be a great way to test texture related problems. We’re still using no buffers, no attributes, and we didn’t have to look up and set any uniforms. For example if we loaded an image, it’s not showing up. What if we try the shader above, does it show the image on the point? We rendered to a texture and then we want to view the texture. Normally we’d setup some geometry via buffers and attributes but we can render the texture just by showing it on this single point.
POINTS
Another simple change to the example above. We can change the vertex shader to this
attributes have a default value of 0, 0, 0, 1
so with just that
change the examples above would still continue to work. But, now
we gain the ability to set the position if we want.
Before we run it lets make the point smaller
And lets make it so we can set the color of the point. (note: I switched back to the code without a texture).
and we need to lookup the color location
And use them
And now we get 5 points with 5 colors and we still didn’t have to setup any buffers or attributes.
Of course this is NOT the way you should draw lots of points in WebGL. If you want to draw lots of points you should do something like setup an attribute with a position for each point, and a color for each point and draw all the points in a single draw call.
BUT!, for testing, for debugging, for making an MCVE it’s a great way to minimize the code. As another example let’s say we’re drawing to textures for a post processing affect and we want to visualize them. We could just draw one large point for each one using the combination of this example and the previous one with a texture. No complicated step of buffers and attributes needed, great for debugging.