Hello,
I have an ubershader for my whole rendering pipeline system that supports the materials the objects use.
Therefore, certain properties which can be toggled/enabled such as having normal,flow,reflective maps or event certain preprogrammed effects (distortion displacement etc)
The way these effects are applied is by setting uniforms that are checked by an if/else in the shader code. Now I know the ifs should be avoided when using some of them mostly because of branching.
So I have 2 options,
- either perform the if/else in the shader (GPU)
- or perform the if/else in the program (CPU)
for the first one, branching can have an inpact on the performance depending on the hardware from what I’ve read, and what else more…?
for the second one, stante changing can have another impact on the performance, as I’ve also read that changing too much over shaders can have a huge rendering cost, and assuming I can’t sort the objects by shader when they already have a different sort criteria.
Thus my question, is there a middle ground to solve these issues, or should just try tocreate different shaders dynamically for each macro material type?
Here’s an example of what I’m talking about, with some of the branching
if(is_dithered(gl_FragCoord.xy, vTexI)){discard;return;}
if(object.splatting){
albedo = splatMix(object, object.sp_alb_textures[0], object.sp_alb_textures[1], object.sp_alb_textures[2], object.sp_alb_textures[3], textureLevel, false);
normal = splatMix(object, object.sp_nor_textures[0], object.sp_nor_textures[1], object.sp_nor_textures[2], object.sp_nor_textures[3], textureLevel, false);
emission = splatMix(object, object.sp_emi_textures[0], object.sp_emi_textures[1], object.sp_emi_textures[2], object.sp_emi_textures[3], textureLevel, false);
specular = splatMix(object, object.sp_spc_textures[0], object.sp_spc_textures[1], object.sp_spc_textures[2], object.sp_spc_textures[3], textureLevel, false);
} else {
albedo = object.albedo ? texture(object.textures[0], vTex1, textureLevel) : WHITE4;
normal = object.normal ? texture(object.textures[1], vTex1, textureLevel) : WHITE4;
emission = object.emission ? texture(object.textures[2], vTex1, textureLevel)*vec4(object.emissionColor, 1.0) : vec4(object.emissionColor, 1.0);
specular = object.specular ? texture(object.textures[3], vTex1, textureLevel)*vec4(object.specularColor, 1.0) : vec4(object.specularColor, 1.0);
}
...
if(object.rcv_fog){
result.rgb = fogShade(color, vPos, vVert, environment.fog, object.additive, object.fog_intensity);
if(emit > 0) emission = emission * fogValue(vPos, vVert, environment.fog, object.fog_intensity);
} else result.rgb = color;