Shader limitations
I've been tuning my game's renderer for my laptop, which has a Radeon HD 3850. This chip has a decent amount of processing power, but rather limited memory bandwidth, so I've been trying to move more shader work into fewer passes.
Previously, I was using a simple multipass model:
-
Bind and clear FP16 blend buffer (with depth buffer)
- Depth-only pass
- For each light, do an additive light pass
-
Bind backbuffer, use blend buffer as a texture
- Tone mapping pass
In an attempt to improve the performance of this method, I wrote a n开发者_如何转开发ew rendering path that counts the number and type of lights to dynamically build custom GLSL shaders. These shaders accept all light parameters as uniforms and do all lighting in a single pass. I was expecting to run into some kind of limit, so I tested it first with one light. Then three. Then twenty-one, with no errors or artifacts, and with great performance. This leads me to my actual questions:
Is the maximum number of uniforms retrievable?
Is this method viable on older hardware, or are uniforms much more limited?
If I push it too far, at what point will I get an error? Shader compilation? Program linking? Using the program?
Shader uniforms are typically implemented by the hardware as registers (or sometimes by patching the values into shader microcode directly, e.g. nVidia fragment shaders). The limit is therefore highly implementation dependent.
You can retrieve the maximums by querying GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB
and GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB
for vertex and fragment shaders respectively.
See 4.3.5 Uniform of The OpenGL® Shading Language specs:
There is an implementation dependent limit on the amount of storage for uniforms that can be used for each type of shader and if this is exceeded it will cause a compile-time or link-time error. Uniform variables that are declared but not used do not count against this limit.
It will fail at link or compile-time, but not using the program.
For how to get the max number supported by your OpenGL implementation, see moonshadow's answer.
For an idea of where the limit actually is for arbitrary GPUs, I'd recommend looking at which DX version that GPU supports.
DX9 level hardware:
vs2_0
supports 256 vec4.ps2_0
supports 32 vec4.vs3_0
is 256 vec4,ps3_0
is 224 vec4.
DX10 level hardware:
vs4_0/ps4_0
is a minumum of 4096 constants per constant buffer - and you can have 16 of them.
In short, It's unlikely you'll run out with anything that is DX10 based.
I guess the maximum number of uniforms is determined by the amount of video memory, as it's just a variable. Normal varaibles on the cpu are limited by your RAM too right?
精彩评论