0
\$\begingroup\$

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?

\$\endgroup\$
  • \$\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\$ – János Turánszki Nov 6 '16 at 16:48
0
\$\begingroup\$

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

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ What exactly is RenderMaterial? A struct defined in the shade? \$\endgroup\$ – David Peicho Nov 6 '16 at 23:06
  • \$\begingroup\$ Yes it is, I updated my answer for you \$\endgroup\$ – Justin William Stanley Bryant Nov 6 '16 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\$ – David Peicho Nov 7 '16 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\$ – Justin William Stanley Bryant Nov 7 '16 at 9:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.