I have been working on how the GPU does parellel processing, and branching. However I am not yet to the point where I know how to make this shader more efficent. Essentially I dont know enough about how it works.
Anyway I have the following shader:
precision highp float;
varying vec3 o_color; //Color it should be
varying vec2 texture_coord; //Interpolated value 0-1
varying float ratio_out; //This is the height / width of the capsule on screen
varying float rdistOut; //This number is used to fill in all pixels when particle is slow enough for the geometry to be a square but still has some distance from last position.
void main()
{
vec2 yCoord = vec2(0.5);
float yScale = ratio_out;
vec2 my = texture_coord * vec2(1.0, yScale);
vec2 del = yCoord - my;
float len = del.x * del.x + del.y * del.y;
if ((!(my.y > 1.0) && (len < 0.25)) || (my.y > yCoord.y && my.y < rdistOut))
{
gl_FragColor = vec4(o_color, 1.0);
}
else
{
gl_FragColor.a = 0.0;
}
}
What it does is draw capsules on the screen. Basically these capsules connect where the particle was to where it is.
On the cpu I compute the vertices of this with some linear algebra, but in screen space terms the rectangle we will be shading has a maximum width of W
and a minimum height of W
. If the capsule is moving faster then W/2
then the capsules geometry will start to get longer to accommodate.
Here are some diagrams of what is going on:
This is an image of a single capsule. Because the distance between the current and last position is not large enough so the screen-space geometry is a square. You can see that to compensate that lighter area is shaded in as well to connect the two points.
Here are some more examples of what could happen
The thing is these capsules are all individual, sometimes every capsule will be elongated, sometimes it will only be a small percent. This shader needs to be as steady fps as possible.
Now here are some tips that are useful and might help make things more efficent:
- The dot product is NEVER needed past the point where the circle part is done.
- If the scaleFactor is greater then 1 then the dot product is never needed past the center of the circle.
This is shown in this diagram. In this case none of the grey area needs to preform the dot product.
Explanation of variables:
o_color: is the color that that particle is
texture_coord: these are the exact same as if you were going to texture this, they go from 0-1
ratio_out: height / width. Will never be less then 1
Inside the main function to get the coordinates in screen scale we simply multiply the y texture coordinate by the scale factor. That makes the center of the circle part a 0.5, 0.5.
rdistOut is the tiny area that the particle sometimes has when it is a square but still moving. Things should be shaded from 0.5-rdistOut.
Could you please help me remove un-needed dot product computations and comparisons as well as get rid of branching?
Please include an explanation of how you got the GPU to skip dot product calculations or why you did what you did. Next time I hope to be able to do this myself.