HalRiyami
Member
I'm currently implementing a post processing stack, similar to Unity's "Combined Stack" in this link. I understand this is done through compute shaders (not sure how those work but maybe you can dynamically add/remove compute passes depending on which effect is enabled). Since we don't have access to those, I can do one of two things: combine all my effects into a single fragment shader with a bunch of if statements to keep it modular or create a shader wrapped in an if check for each effect to act as my passes.
If I were to use a single shader, then my if statements would go inside the fragment shader like this:
I know that if statements are generally frowned upon in shaders as their impact is high, but would it be the case here since this isn't divergent (all fragments end up running the exact same code)?
The other option would look like this:
I assume this is slower since every effect causes a texture swap and does a full surface render, but if only 1 or 2 effects are active this might be faster.
Anyone with more experience in shaders know which is preferable in this situation?
If I were to use a single shader, then my if statements would go inside the fragment shader like this:
GML:
/// GML code
// Render view surface to the back buffer
shader_set(shd_effect_combined);
draw_surface(...);
shader_reset();
/// Fragment shader
uniform bool doEffect1;
uniform bool doEffect2;
uniform bool doEffect3;
void {
color = texture2D(..., uv);
if (doEffect1) {color = Effect1(color, ...);}
if (doEffect2) {color = Effect2(color, ...);}
if (doEffect3) {color = Effect3(color, ...);}
gl_FragColor = color;
}
The other option would look like this:
GML:
/// GML code
// Render surface A on surface B using effect 1 shader
if doEffect1 {
shader_set(shd_effect_1);
surface_set_target(surface_b);
draw_surface(...);
surface_reset_target();
shader_reset();
}
// Render surface B on surface A using effect 2 shader
if doEffect1 {
shader_set(shd_effect_2);
surface_set_target(surface_a);
draw_surface(...);
surface_reset_target();
shader_reset();
}
// Render surface A on surface B using effect 3 shader
if doEffect3 {
shader_set(shd_effect_3);
surface_set_target(surface_b);
draw_surface(...);
surface_reset_target();
shader_reset();
}
Anyone with more experience in shaders know which is preferable in this situation?