I’m reading the chapter in the OF book about ofPath and Arturo writes, “you can set the color per vertex on every shape or use a shader to specify a color…”
Im trying to get my head around when you would want to do this per vertex in OF versus writing a separate little shader program, conceptually. Just starting to learn about shaders and trying to understand when and how to jump to them (yes, I’ve worked through the chapter on shaders in the book).
Hello @80l08. It depends on your needs. If you are just getting started with openFrameworks, just set the color per vertex, in order to get familiar with it.
Once you get through this part have a look into shaders, there is a really nice chapter in the of book about it. A shader is like a skin that you apply to your a path. Every pixel of that path, will receive the same information stored in the “skin”. The skin is known as “material” in every 3D program, from Blender to Maya, and OF has a class too, called ofMaterial, that is just a shader. You can write your own “skins” using ofShader.
The key point in the previous sentence is the word “same”. While setting the color per vertex you are giving to each pixel an information about which color it shoulds have, using shaders each pixel receives the same information. This does not not mean that using shaders a path will always be monochromatic, there are different ways to change the color of a rendered geometry using a shaders, but you will see this when you go through the ofBook chapter.
I think you can do almost the same things with and without shaders, it’s mostly a matter of frame rate and how easy or hard you want it to be
A practical example in which I needed shaders: I had a 3D mesh. I wanted this mesh to deform and glow as a result of a shockwave (an imaginary growing sphere). I could do this by manipulating all the vertices in OF (changing their positions and colors) but that would mean updating all the vertices on every animation frame and sending them to the GPU, which is slow. Instead, I can keep the mesh in the GPU, and only send a few values to the shader: the center of the shockwave (a vec3) and the radius (a float, which grows quickly as time passes). The shader can then brighten the colors of the vertices and displace them if they are near the shockwave radius. In this case I used both colored vertices (the original vertex colors sent from OF) and altering of those colors in the shader.
I think if you want to change the properties of thousands of vertices on every animation frame you should probably do it in the shader.
Shaders also have limitations. For instance, a vertex in a shader can not know anything about the neighboring vertices. They are isolated. So if you want to color mesh vertices in a way that they influence each other, you probably need to do it before the data is sent to the GPU.
These are some examples of a plain sphere with colors set in a shader:
so if I wanted to draw hundreds of circles/spheres, each like the “color based on normals” example but changing colours and slightly differently, using shaders would be more effiecient?
It depends. There are different things that can slow down frame rate but they say “premature optimization is the root of all evil” maybe first try in any way you know how to do this, and later iterate and improve as needed?
In any case I’ll try to explain. Two things happen when you draw on the screen: you upload data to the GPU, and then you ask it to draw that data (vertices, colors, textures). One trick to make things fast is to upload less data by uploading things once, then drawing them many times (reusing) in one animation frame and across frames. So instead of uploading spheres all the time, you would upload one spheres but draw it in different positions, scales, and colors. In this case you upload less data on every frame (maybe only the positions if the spheres are moving or colors if they are changing colors, but not all the vertices and normals).
The “easy” way is to just call ofSphere() many times and be done with it. Faster ways may involve using ofVbo and instancing (examples/gl/vboMeshDrawInstancedExample).
A shader that uses the normals as colors might be about 1 line of code
brb, exploring all those things :’) (except calling ofSphere many times, bc I also want to be able to do this with “diy”/irregular shapes, tho “instancing” those is a new idea to me…)