Jump to content
  • Advertisement
Sign in to follow this  
spek

Performance; Shader parameter passing in an efficient way

This topic is 2520 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Trying to improve performance, and yet another pain in the ass are shader parameters (using Cg here btw). Although I already try to sort on material as much as possible, there are still hundreds of vectors and textures
passed each cycle, giving quite a serious hit. Pretty much every material has a couple of parameters, a typical example would be:

sampler2D albedoMap
sampler2D normalMap
float4 specularColor_andShininessFactor
float4 ReflectivityParameters
float3 somethingElse_DependingOnChosenShader

And, pretty much all shaders also refer to common variables such as the current camera position.


Now I don't know how to decrease the impact from texture switches, asides from sorting and grouping as much as possible. But for the other vector parameters...

1- Using arrays or structs
Is it faster to send a single array or struct with all vector parameters? Some of the parameters are used on almost every shader, so I can make a struct or array with these "fixed" parameters, + a number of custom ones. Then pass them with a single command.

2- Sharing parameters
In Cg I use cgConnectParameter on common "shared" variables such as the camera position. That means if I update the camera position once, it will be done in all shaders that refer to this shared parameter. Yet I'm not sure if this is the best way to share. But that's probably a question specific on Cg...

3- Not re-sending the parameters if they didn't change
AFAIK, parameters stay with their program. So if I have a single object with 1 shader, I only have to pass the parameters once (until their values change). However, in my case lot's of objects share the same shader-program, but with different parameters.

4.- Storing parameters on the GPU?
Since we can store textures and geometry on the GPU instead of passing them from the CPU, isn't this possible with parameters too? Let's say I have 300 different materials, each with a custom set of parameters. Now upload the bastards to the GPU, and let the shaders look there (they need to know where to look though).

5.- Any other tips on shader parameters?


Cheers

Share this post


Link to post
Share on other sites
Advertisement
Thanks, I'll start reading. And most probably, I will have questions :P T/Cbuffers, is that also available in OpenGL btw?

From my little understanding so far, you just stuff one (or more) big buffers with all the parameters you desire ONCE, then just activate that buffer when going rendering, so you don't have to stop and adjust parameters before rendering another object. So:

// The old way
myShader.activate;
for each object in renderQueue
myShader.parameter(0).set( object.parameter1 );
myShader.parameter(1).set( object.parameter2 );
object.render
--------------------------
<new way>
fill tbuffer with all the parameters we'll need
...

myShader.activate;
tbuffer,activate
for each object in renderQueue
object.render

So far, so good?

Share this post


Link to post
Share on other sites

From my little understanding so far, you just stuff one (or more) big buffers with all the parameters you desire ONCE, then just activate that buffer when going rendering, so you don't have to stop and adjust parameters before rendering another object. So:
...snip...
So far, so good?


Yeah. Its a restructure so the CPU and GPU both do as little work as they need to. CBuffers don't exist in OpenGL, but i beleive the concept of register-index bound parameters is readily available in either GL3.0 or Cg.

Share this post


Link to post
Share on other sites
From what I can tell, uniform buffer objects are in some ways similar to cbuffers in D3D. They let you update uniforms in blocks, in the same way as you would to update a vertex buffer, and the block can be shared between shader programs.

Share this post


Link to post
Share on other sites
Never heard of uniform buffer objects, but that's why they invented Google :) Is a similiar thing also available for textures (directX tbuffer) btw?

Share this post


Link to post
Share on other sites

Is a similiar thing also available for textures (directX tbuffer) btw?


A texture array, arguably.

Share this post


Link to post
Share on other sites
Looks like there's a texture buffer object in OpenGL 3.1+ as well. I don't know what tbuffers are like in Direct3D, but in OpenGL a texture buffer object acts like a texture except you can't specify any texture parameters on them, so it's literally a huge array of data in the form of a texture.

Share this post


Link to post
Share on other sites
In HLSL a tbuffer is used and declared exactly like a constant buffer. The only difference is on the app side of things, where you create a texture resource and bind that to the device rather than a constant buffer resource. Ultimately it just ends up being a bit of syntatic sugar.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!