I am implementing a deferred rendering framework, and I wanted to allow programmers to write custom materials. However, I did not find yet how to handle different materials. For now, a material is just a set of uniforms for me.

I wanted to write the material ID in the GBuffer, however, I don't see the point of doing it as the lightning pass is using the same shader for every fragment (obviously).

In the frosbite paper (page 15), they explain they use a Material ID and a MatDat parameter, but I did not really get what it can be and how they handle it during the lightning pass.

Is the material ID used in a simple branching condition? In this case, when a new material is created, do I have to rebuild the lightning pass uber shader by adding this branching and the code to execute?

UE4 seems to build GLSL code from the material editor, which is not something hard, but how do they handle it with the deferred renderer? Do they only plug the GLSL code into the Uber Shader?

  • \$\begingroup\$ If you really need support for different lighting models, I suggest try looking into (Tiled or clustered) Forward rendering, it can eliminate some headaches with that. :) \$\endgroup\$ Nov 6, 2016 at 16:48

2 Answers 2


In my renderer I have a material ID that I use to change the material settings of rendered objects that way each object can have a different roughness\metalness\Fresnel\specular color\lighting type.

You don't branch with the mat id you just load a different material and use that when you do your lighting eg.

struct RenderMaterial
uint vHighlight1Color;
uint vHighlight2Color;
uint vFrontColor;
uint vBackColor;
float fReflectivity;
float vHighlight1;
float vHighlight2;
float ior;
float pointlightspecpower;
float spotlightspecpower;
float sunpower;
float roughness;
float fresneladjust;
bool  GGX;
float ambientpower;

Texture2D<uint> RenderMaterialIDs; //written to in my Fill Gbuffer stage
StructuredBuffer<RenderMaterial> RenderMaterials; //Filled on the CPU with all the current RenderMaterials, loaded from disk.

//Loading material from buffer
uint MatID;
MatID = RenderMaterialIDs.Load(uint3(globalIdx.x, globalIdx.y, 0));
RenderMaterial CurrentMaterial = RenderMaterials[MatID];

// Using material data
float alpha2 = CurrentMaterial.roughness* CurrentMaterial.roughness;
float G = G_Smith(CurrentMaterial.roughness, nDotV, nDotL);
fresnelTerm = fresnelTerm * CurrentMaterial.fresneladjust;

float3 spec=CurrentMaterial.GGX ? LightingFuncGGX_OPT3 : CookTorrence

I Use a tilebased deferred renderer

  • \$\begingroup\$ What exactly is RenderMaterial? A struct defined in the shade? \$\endgroup\$ Nov 6, 2016 at 23:06
  • \$\begingroup\$ Yes it is, I updated my answer for you \$\endgroup\$ Nov 6, 2016 at 23:13
  • \$\begingroup\$ Ok, thank you. I get it, however, do you allow the programmer to write its own custom material? letting him branch his code inside the shader? \$\endgroup\$ Nov 7, 2016 at 9:00
  • \$\begingroup\$ There is no need to branch, I use CookTorrance\GGX lighting model so every type of material can be made by changing ior, roughness and metalness values. at start up I load all the different materials from disk. They do it like that in most engines its just abstracted away \$\endgroup\$ Nov 7, 2016 at 9:22

Bindless Texturing for Deferred Rendering and Decals


render uv and material id to gbuffer,

then use bindless texture to get all material info in one pass.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .