Horde3D

Next-Generation Graphics Engine
It is currently 26.11.2024, 22:38

All times are UTC + 1 hour




Post new topic Reply to topic  [ 10 posts ] 
Author Message
 Post subject: Setting Uniforms
PostPosted: 28.03.2011, 14:41 
Offline

Joined: 08.03.2011, 18:29
Posts: 17
I have two questions that came up when trying to learn how to write shaders.

1. I have a scene with the two simple quads. Both quads share the same dimensions, material and UV-Coordinates, but are completely separate entities with different positions and use. They are created independently of each other.
But I do not want them to look the same. Is it possible for me to give each of them different values for uniforms so the shader can draw them differently? I can only find h3dSetMaterialUniform() - and that would obviously affect both quads since they share the same material.

2. All of my textures require a time uniform of some sort for animations. Let's say I have 64 materials. Is it really necessary that I cycle through all these materials every frame to update their individual uniform timer with h3dSetMaterialUniform()?
There was some talk about changing this before - is there something planned (or was already done)?


Top
 Profile  
Reply with quote  
 Post subject: Re: Setting Uniforms
PostPosted: 29.03.2011, 07:40 
Offline

Joined: 08.11.2006, 03:10
Posts: 384
Location: Australia
1) You can use h3dCloneResource to duplicate your material and make a unique version for each of the quads.

IMHO, I'd rather be able to attach uniforms to the quads themselves... but that discussion deserves a thread of it's own ;)
At work, we annotate different uniforms/samplers as belonging to the object, the material or the scene/camera. When drawing an object the renderer fetches the uniforms from those 3 locations. Usually the object sets things like the world matrix, the material sets textures and the scene sets fog/etc, but it can be used in many ways.

2) In your pipeline, you can attach a material to a 'stage' element. IIRC, this material then provides global data for everything in that stage.


Top
 Profile  
Reply with quote  
 Post subject: Re: Setting Uniforms
PostPosted: 30.03.2011, 02:18 
Offline

Joined: 15.02.2009, 02:13
Posts: 161
Location: Sydney Australia
Hi polygoff,

Is it at all possible to combine these quads to the one geo resource and just use bones/skinning to set their positions and unique 'material' based on their weight/bone? This might be a solution however you can only stock up to 75 of them into the one geo, but you have like 3x vec4's (or was it vec3's?) in there, theoretically per-quad (but they are used for translate,rotate,scale, maybe you could just use 1 scale float value and use the other 2 or 3 values for your own stuff). If you want to kill off visibility to some, scale the joint by 0...

I assume the particles system works in a similar way, or is there no access per-quad? *shrugs*

_________________
-Alex
Website


Top
 Profile  
Reply with quote  
 Post subject: Re: Setting Uniforms
PostPosted: 30.03.2011, 08:09 
Offline

Joined: 08.03.2011, 18:29
Posts: 17
Thanks for your replies.

DarkAngel wrote:
1) You can use h3dCloneResource to duplicate your material and make a unique version for each of the quads.

The documentation says "In the cloning process a new resource with the specified name is added to the resource manager and filled with the data of the specified source resource.". Doesn't that mean that cloning the resource duplicates the necessary physical ressources? So if I add 1000 objects, the data is put 1000 times into memory?

Quote:
IMHO, I'd rather be able to attach uniforms to the quads themselves... but that discussion deserves a thread of it's own ;)

That's the thing. I admit I have next to no experience with shaders, but in the tutorials I read uniforms are thrown around much more liberally. I have an entity system in my engine and if I could have every entity have its health, etc. represented by the shader, that would just be great. And it does not (yet?) make a lot of sense to me to have values like health be set per material.

Quote:
At work, we annotate different uniforms/samplers as belonging to the object, the material or the scene/camera. When drawing an object the renderer fetches the uniforms from those 3 locations. Usually the object sets things like the world matrix, the material sets textures and the scene sets fog/etc, but it can be used in many ways.
[/quote
Yes, this is the layout that most tutorials cover. :) I take it you do not use Horde3D at work?

Quote:
2) In your pipeline, you can attach a material to a 'stage' element. IIRC, this material then provides global data for everything in that stage.


Sounds good if that is the case, but are there any demos for this?

MistaED wrote:
Is it at all possible to combine these quads to the one geo resource

Sadly not since they are entirely independent and move off screen often. :(


Top
 Profile  
Reply with quote  
 Post subject: Re: Setting Uniforms
PostPosted: 30.03.2011, 10:10 
Offline

Joined: 24.03.2010, 10:17
Posts: 55
polygoff wrote:
2. All of my textures require a time uniform of some sort for animations. Let's say I have 64 materials. Is it really necessary that I cycle through all these materials every frame to update their individual uniform timer with h3dSetMaterialUniform()?
There was some talk about changing this before - is there something planned (or was already done)?

As DarkAngel pointed out, you can use the pipeline to reference/apply "global" materials.
In our setup, we use the following setup:
Code:
<Pipeline>
   <CommandQueue>
      <Stage id="Geometry" link="scene01/pipelines/globalSettings.material.xml">
         <!-- normal drawing follows here like DrawGeometry-->
         <DrawGeometry context="AMBIENT" class="~Translucent" order="STATECHANGES"/>
      </Stage>
   </CommandQueue>
</Pipeline>               

The globalSettings.material.xml itself looks like this:
Code:
<Material link="$EngineGlobals">
   <Sampler name="ambientMap" map="scene01/models/cubemaps/ambientMap.dds" />
</Material>

This means, that all Shaders which have "ambientMap" as sampler, use the texture defined in globalSettings.material.xml.
If you want to change the ambientMap for all materials, just do it here.

As Material linking is recursive, we added a link called "$EngineGlobals" (we use the dollar sign to denote that this material is created in C++ code).
Our $EngineGlobals looks like this (simplified):
Code:
const char* gGlobalMaterialXML =
"<Material>\n"
"   <Uniform name=\"g_TimeParams\" a=\".0\" b=\".0\" c=\".0\" d=\".0\" />\n"     //  a=CurTime
"   <Uniform name=\"g_ZBufferParams\" a=\".0\" b=\".0\" c=\".0\" d=\".0\" />\n"  // a=near b=far c=(1-far/near)/2 d=(1+far/near)/2
"</Material>\n"
In C++ we create an instance of it like this:
Code:
gGlobalMatRes = ::h3dAddResource(H3DResTypes::Material, "$EngineGlobals", 0);
::h3dLoadResource(gGlobalMatRes, gGlobalMaterialXML, strlen(gGlobalMaterialXML)+1));
Each frame we update the material like this:
Code:
::h3dSetMaterialUniform(gGlobalMatRes, "g_TimeParams", getCurrentTime(), 0.0f, 0.0f, 0.0f);
Additionally we set the ZBufferParams (used for Depth reconstruction, for example).
In your shader code, you need to define the $EngineGlobals (sadly, this has to be done in every shader, as there is no include for the setup-section for shaders) like this:
Code:
float4 g_ZBufferParams;
float4 g_TimeParams;

As a side-note: if you use commands in your stage like
Code:
<DrawQuad material="scene01/pipelines/postFX.material.xml" context="TRANSFER" />
and your stage has no link to the "$EngineGlobals", make sure you add a link to the "$EngineGlobals" material inside the postFX.material.xml as well, otherwise the uniforms/samplers will not be picked up.

I agree, that global or per-instance uniforms would come handy.
Also, the order of material linking is important: once a uniform/sample is set in a link, you cannot override it locally (if I remember correctly), e.g. you cannot assign a different texture in your shader's material for the ambientMap example above. The globalSettings.material.xml will always override it.

Hope this helps.


Top
 Profile  
Reply with quote  
 Post subject: Re: Setting Uniforms
PostPosted: 30.03.2011, 22:31 
Offline

Joined: 08.03.2011, 18:29
Posts: 17
Thank you AlexL. That does help very much! :)

I wish one of the engine designers would weigh in on this topic in general. Uniforms per mesh/entity and global uniforms seem kind of a central point of shader based architectures from what I keep on reading. There seem to be quite a lot of interesting techniques that are based on differentiating entities based on their shaders alone.

But judging by the great work you guys did on the rest of the engine layout, there is probably a deeper reason for this omission. ;)


Top
 Profile  
Reply with quote  
 Post subject: Re: Setting Uniforms
PostPosted: 31.03.2011, 01:37 
Offline

Joined: 08.11.2006, 03:10
Posts: 384
Location: Australia
Quote:
Doesn't that mean that cloning the resource duplicates the necessary physical ressources? So if I add 1000 objects, the data is put 1000 times into memory?
Yes, but only the *material* resource itself will be duplicated (i.e. just the data in the XML file, not any of the textures etc that it references).
Quote:
I take it you do not use Horde3D at work?
I write our own proprietary graphics engine at work ;)
I use Horde3D at home for experiments / hobby projects.


Top
 Profile  
Reply with quote  
 Post subject: Re: Setting Uniforms
PostPosted: 08.04.2011, 11:06 
Offline

Joined: 08.03.2011, 18:29
Posts: 17
Okay, I'm currently working around the limitations by having a "materialManager" class that keeps a copy of the material for each single entity.

I can't say I like this layout, but I guess this is the way to go.


Top
 Profile  
Reply with quote  
 Post subject: Re: Setting Uniforms
PostPosted: 04.06.2011, 09:36 
Offline

Joined: 22.06.2010, 19:21
Posts: 26
I have run into this problem as well, but wasn't as successful at resolving it.

I'm drawing 10000 units (simple quads) on screen - all with the same basic material. Said material has multiple uniforms that make it do fancy stuff. A simple example would be something like
Code:
<Uniform name="recolor" a="1.0" b="0.0" c="0.0" d="1.0" />
in combination with
Code:
if (albedo.r == 0.0 && albedo.g == 0.0) { // RGB=0000XX
         albedo.rgb = albedo.b*recolor.rgb;
}
in the pixelshader allows me to recolor everything that is blue in my units texture to red (useful for team colors and various stats). Rendering 10000 units with this shader is a task that Horde3D handles without breaking a sweat.

Now comes the interesting part. When I want to set uniforms for each unit individually (thus giving them all a different color), I have to h3dCloneResource() the material and assign it to each different unit. If I now try to render the scene, everything grinds to a halt because the CPU has to switch between 10000 materials and render each unit individually.

Is this an expected, unresolvable limitation with no workarounds? Or am I not thinking straight (highly possible)? From this thread, I understand that setting uniforms per object instead of per material is not possible. Is it in other engines or do shaders not work that way?


Top
 Profile  
Reply with quote  
 Post subject: Re: Setting Uniforms
PostPosted: 04.06.2011, 16:16 
Offline

Joined: 15.02.2009, 02:13
Posts: 161
Location: Sydney Australia
Hi johannes, welcome to draw call overhead! :)

What you might need to do is batch them to a more manageable set of draw calls while keeping in mind how many uniforms you can pass down a shader (GPU-dependent). So instead of passing 10,000 draw calls with one uniform each, you can reduce this down to perhaps 100 draw calls with 100 uniforms each, or better yet 10 draw calls with 1000 uniforms. You then have a vertex attribute stream which works like an ID to those uniforms so it knows which vertices to change colour, or if they're all separated quads do a vertex order count in the shader so after the 4th vert making up a single quad, have a different uniform attached so no need for that additional attribute stream while keeping your dynamic control via uniforms.

_________________
-Alex
Website


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group