Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Better to change uniforms or change program?

Tags:

webgl

Using webgl I need to perform 3 passes to render my scene. Each pass runs the same geometry and shaders but has differing values for some uniforms and textures.

I seem to have two choices. Have a single "program" and set all of the uniforms and textures for each pass. Or have 3 "programs" each containing the same shaders, and set all the necessary uniforms/shaders once per program, and then just switch programs for each pass. This means that I will do one useProgram call per pass instead of man setUniform calls for each pass.

Is this second technique likely to be faster as it will avoid very many setuniform calls, or is changing the program very expensive? I've done some trials but with the very simple geometry I have at the moment I don't see any difference in performance because setup costs overwhelm any differences.

Is there any reason to prefer one technique over the other?

like image 885
jcoder Avatar asked Dec 18 '13 16:12

jcoder


2 Answers

Just send different values via glUniform if the shader programs are the same.

Switching between programs is generally slower than change value of uniform. Anyway Uber Shader Program (with list of uniforms like useLighting, useAlphaMap) in most cases aren't good.

@gman We are talking about WebGL (GLES 2.0) where we don't have UBO. (uniform buffer object)

@top Summing try to avoid rebinding shader programs (but it's not end of the world) and don't create one uber shader!

like image 106
trebor Avatar answered Oct 21 '22 04:10

trebor


When you have large amouts of textures to rebind, texture atlasing should be the fastest solution, so you don't need to rebind textures, don't need to rebind programs. Textures can be switched by modifying uniforms representing texCoord offsets.

Modifying such uniforms can be optimized even further:

You should consider moving frequently modified uniforms to attributes. Usualy their data source are provided using attribPointers but you can also use constant values when they are disabled. Instead of unformXXX() use attribXXX() functions to specify their constant values.

I think best example is light position. Normaly you'd have to specify uniform values for it every time light position changes to ALL programs that make use of it. In contrast, when using 'attributed' uniforms you can specify attribute value once globaly when your light moves.

-pros: This method is best suited when you have many programs which would like to share uniforms, as we know we can't use uniform buffers in WebGL, it seams to be the only reasonable solution.

-cons:

Of course available size of such 'attributed' uniforms will be much smaller than using regular uniforms, but it still can speed things up a lot if you do it to some part of your uniforms.

like image 29
Anonymous Avatar answered Oct 21 '22 04:10

Anonymous