Today I'll show you what face culling is, and how it affects performance.
We are also gonna measure this performance change by making an FPS counter.
So face culling is a step in the graphics pipeline that decides if a triangle will move on to the fragment shader (aka, if the triangle will be drawn or not).
OpenGL decides this by seeing which side of the triangle is currently facing the camera.
Generally speaking, in most 3D graphics programs, it is the front side of a triangle that is sent to the fragment shader, and the back side of a triangle that is discarded.
In a counter-clockwise framework, if the order of the indices of a triangle are counter-clockwise when facing us, then the side we see, is the front side.
Likewise, if the order of the indices of a triangle are clockwise when facing us, then the side we see, is the back side.
For a clockwise framework it's the exact opposite.
Most graphics programs use a counter clockwise standard, but don't expect all of them to use this.
the code is very simple.
//Main.cpp
// Enables the Depth Buffer
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glFrontFace(GL_CCW);
glFrontFace(GLenum mode);
CW is Clock-Wise, CCW is Counter-Clock-Wise;
we use the usual one, CCW.
Finally, the FPS (Frame per second).
To do that we just need to get the current time in seconds using glfwGetTime, the time difference, and increment the counter. Then if the difference is higher or equal to a 30th of a second, we go ahead with the measurement of the FPS.
The FPS will simply be equal to 1 divided by the time difference, which is the amount of frames in a second that this time difference gives, but the time difference contains multiple frames, which are equal to the counter, so we also need to multiply it with the counter as well.
//Main.cpp
double prevTime = 0.0;
double crntTime = 0.0;
double timeDiff;
unsigned int counter = 0;
// Main while loop
while (!glfwWindowShouldClose(window))
{
crntTime = glfwGetTime();
timeDiff = crntTime - prevTime;
counter++;
if (timeDiff >= 1.0 / 30.0)
{
std::string FPS = std::to_string((1.0 / timeDiff) * counter);
std::string ms = std::to_string((timeDiff / counter) * 1000);
std::string newTitle = "OPGT " + FPS + "FPS / " + ms + "ms";
glfwSetWindowTitle(window, newTitle.c_str());
prevTime = crntTime;
counter = 0;
}
If they are stuck on 60, then that means that you have VSync on, which tries to keep your FPS constant to 60 frames per second.
If you wish to disable this, then write glfwSwapInterval(0) in your main function. (but don't do that)
but if you want do that handle user inputs are put into an if statement that works periodically.
Transparency and Blending
for transparency, we can simply implement that by change our fragment shader.
set the alpha threshold(0.1f), and if the alpha value is smaller than threshold, discard that.
don't forget the alpha is color opacity.
//fragment shader
vec4 direcLight()
{
// ambient lighting
float ambient = 0.20f;
// diffuse lighting
vec3 normal = normalize(Normal);
vec3 lightDirection = normalize(vec3(1.0f, 1.0f, 0.0f));
float diffuse = max(abs(dot(normal, lightDirection)), 0.0f); // absolute helps with grass shading
// specular lighting
float specularLight = 0.50f;
vec3 viewDirection = normalize(camPos - crntPos);
vec3 reflectionDirection = reflect(-lightDirection, normal);
float specAmount = pow(max(dot(viewDirection, reflectionDirection), 0.0f), 16);
float specular = specAmount * specularLight;
if (texture(diffuse0, texCoord).a < 0.1)
discard;
return (texture(diffuse0, texCoord) * (diffuse + ambient) + texture(specular0, texCoord).r * specular) * lightColor;
}
Blending
This is the formula OpenGL uses for blending different colors together.
All the C terms stand for Color, while the T terms stand for transparency.
And then the source color is the color in the fragment shader, while the destination color is the color in the color buffer.
These transparencies can have different formulas.
The most common one is that in which the source gets its transparency value from the alpha part of the source color, while the destination's transparency is (1 - the alpha value of the source).