• Create Account

### #ActualHodgman

Posted 10 March 2013 - 11:54 PM

In my renderer, I don't even have a material class. A material is just a bunch of data (cbuffers, textures, shaders) and a bunch of commands that bind that data to the pipeline (PSSetConstantBuffers, etc).
I have classes for resources like cbuffers/textures/etc, and I also have a class called StateGroup, which can hold commands to set rendering states (which includes binding resources).
I can use StateGroup to represent a material, as well as other things, e.g.

StateGroup objectStates;   // binds cbuffer with world matrix
StateGroup materialStates; // binds shader, sets blend mode, binds textures, binds material cbuffer
StateGroup lightingStates; // binds cbuffer with light positions
StateGroup* states[3] = { &objectStates, &materialStates, &lightingStates };
Draw( mesh, states, 3 );

This shader resources a material holds, is it a single permutation of a shader, or a material can access all of the permutation of the shader it references?

I always reference a particular "technique", which internally may have many different permutations that can be chosen by the renderer right before each draw call.

Say I have a cube with a material, if my cube changes environment, so that the number of lights change, do I need to just use another permutation on the material(material holds a permutation info), the shader itself updates its permuation info(so all material with this shader now will use the new permutation),  do I need to change the cube material (another material with the right permutation)? or do I need to update the shader on the material(so the material got a new shader)?

If the lighting environment has changed, I wouldn't make any changes to the material or the shader. The material references a particular shader, and that shader contains techniques for different lighting enironments.
When drawing the cube, with this material/shader/lighting environment, the renderer can select the appropriate premutation at the last moment, when it has all this information available to it.

Also, when is that a material finds out what cbuffers slots to use? This is shader stuff, say you know what cbuffers a shader use cause youre using reflection at asset loading time, materials comes from models right? Not from HLSL files..I fail to see when things get linked up (shader permutations compilation, models loading, environment lighting info being updated to shader cbuffers..)

I do all of this in the tools, during "data compilation" time.
First I compile the shaders, which tells me their cbuffer layouts (which variables are in which cbuffer structures, and which slots/stagse each structure should be bound to).
Then I parse the artists material descriptions (which for me, are in the COLLADA files), and use the above structure information to create byte-arrays of cbuffer data.
Then I create binding commands, to bind these structures to the appropriate slots/stages (e.g. bind cbuffer structure #1 to pixel shader slot #3).
Then I save these cbuffers and binding commands into a "material file", which contains links to other resource files (textures, shaders, etc) and contains StateGroups and cbuffers to be used as "materials".

### #1Hodgman

Posted 10 March 2013 - 11:53 PM

In my renderer, I don't even have a material class. A material is just a bunch of data (cbuffers, textures, shaders) and a bunch of commands that bind that data to the pipeline (PSSetConstantBuffers, etc).

I have classes for resources like cbuffers/textures/etc, and I also have a class called StateGroup, which can hold commands to set rendering states (which includes binding resources).

I can use StateGroup to represent a material, as well as other things, e.g.

StateGroup objectStates; // binds cbuffer with world matrix
StateGroup materialStates; // binds shader, sets blend mode, binds textures, binds material cbuffer
StateGroup lightingStates; // binds cbuffer with light positions
StateGroup[] states = { objectStates, materialStates, lightingStates };
Draw( mesh, states );

This shader resources a material holds, is it a single permutation of a shader, or a material can access all of the permutation of the shader it references?

I always reference a particular "technique", which internally may have many different permutations that can be chosen by the renderer right before each draw call.

Say I have a cube with a material, if my cube changes environment, so that the number of lights change, do I need to just use another permutation on the material(material holds a permutation info), the shader itself updates its permuation info(so all material with this shader now will use the new permutation),  do I need to change the cube material (another material with the right permutation)? or do I need to update the shader on the material(so the material got a new shader)?

If the lighting environment has changed, I wouldn't make any changes to the material or the shader. The material references a particular shader, and that shader contains techniques for different lighting enironments.

When drawing the cube, with this material/shader/lighting environment, the renderer can select the appropriate premutation at the last moment, when it has all this information available to it.

Also, when is that a material finds out what cbuffers slots to use? This is shader stuff, say you know what cbuffers a shader use cause youre using reflection at asset loading time, materials comes from models right? Not from HLSL files..I fail to see when things get linked up (shader permutations compilation, models loading, environment lighting info being updated to shader cbuffers..)

I do all of this in the tools, during "data compilation" time.

First I compile the shaders, which tells me their cbuffer layouts (which variables are in which cbuffer structures, and which slots/stagse each structure should be bound to).

Then I parse the artists material descriptions (which for me, are in the COLLADA files), and use the above structure information to create byte-arrays of cbuffer data.

Then I create binding commands, to bind these structures to the appropriate slots/stages (e.g. bind cbuffer structure #1 to pixel shader slot #3).

Then I save these cbuffers and binding commands into a "material file", which contains links to other resource files (textures, shaders, etc) and contains StateGroups and cbuffers to be used as "materials".

PARTNERS