Exposing the BRDF Models to the Material Editor?

Poking around at the Unreal Shader Files, is it possible to expose to different PBR BRDF models that are written into the engine to the material editor, so that materials can select them per-material? I’m looking inside BRDF.usf right now in the engine source, and multiple models are there. I assume that we can simply write our own models in here and change the #define PHYSICS_### flags to use that shader when we compile? Is that feasible?

I’m looking into ways to make the renderer much more flexible. Our options are extremely locked down at the moment. This would also be a great way to bypass the current issues with foliage shading, which are forcing us to use very expensive SSS methods.

I did originally look at that idea so I’d be eager to hear more :slight_smile: It’s a shame you can’t change the models, some for example are much better at simulating hard/glossy surfaces than others (e.g. Oren-Nayar vs Cook-Torrence).

I was hunting for the information about creating custom Lighting ID’s but didn’t get very far, feel free to share anything you may know about them that could help :slight_smile: Even at that stage, is it still impossible to change the BRDF model for that material only? For example, having Translucent Surfaces that use Cook-Torrence, and Pre-Integrated skin using Oren-Nayar. (Just for the sake of example).

Also, you say you’ve moved away from the deferred renderer which I’m assuming means you’ve worked on the forward renderer a little? Do you have things like Light Vectors and custom lighting models working? My project isn’t going to be flooded with dynamic lights and reflections, so maybe a switch would benefit this project too.

Awesome information, the trickiest part is figuring out what sits where, which files to look in etc. Being new to C++ and programming in general makes it slightly harder but I can piece together what’s happening with basic knowledge.

But yeah, would be great to see some more detail on this kind of thing. Epic’s Trello road-map does have a Parallel rendering implementation at the highest priority right now but I just want to see the rendered becoming much more flexible.

Wow!

I really like your end result !

Any chance of Oren_Nayar diffuse /anything ? It looks very good :slight_smile:

Great work!

You just need to change single #define in BRDF.usf
It’s hard to miss:



// Diffuse model
// 0: Lambert
// 1: Burley
// 2: Oren-Nayar
#define PHYSICAL_DIFFUSE	2


The you just start your game, and wait till all shaders recompile.

In any case thanks for tutorial! Un 4.2 version the line numbers are bit different in shader files though, so if anyone else wondering:

DeferredShadingCommon.usf
It start from line 253.

BasePassPixelShader.usf
Line 723

DeferredLightingCommon.usf
Line 353.

Could you also post code that you added in GetDynamicLighting function ?
I looked at it, and honestly I started doubting myself after seeing all those #if #endif BRANCH defines.

Ok thank you very much this!

I just want to tinker around bit, and yours solution is given perfect starting point to get something going (;.

You my friend… are my new favourite person :smiley:

Have you guys had any luck implementing this in 4.4? The code files have changes considerably with the advent of the new Shading Models. I’m trying to add a custom Minnaert BRDF model for a custom shader called ‘Moon’, but there’s no more ‘Diffuse Lighting’ function to switch out the shader model.

In 4.3 some of the gbuffers were reorganized to allow for a byte worth of shading model ids - 256. We’re using a range to implement a custom toon shading model.

This thread is really helpfull.
I also follow the same way to update shader code for custom lighting model, such as Cook-Torrance lighting.

Roughness = 1

Nice work Transformers! Out of curiosity did you do that in 4.5 or 4.6? The code seems to have changed a fair bit, hopefully will be able to update his tutorial when he gets around to it :slight_smile:

I did it in 4.51
Maybe the feature would handle this part without recompile editor.

has anything changed in terms of adding a new model?
would like to add a new specular model. make it lengthier in (4.8 or 4.9)

So I have recently been trying to add my own shading model and think I have found the right things to change. Here’s the stuff I have changed based on the stuff from . It seems LIGHTINGMODEL… has changed over to SHADINGMODEL… I have done this in 4.8 as of now:

DeferredShadingCommon.usf

4.8 Line 226


#define SHADINGMODELID_TWOSIDED_FOLIAGE		6
#define SHADINGMODELID_MYSHADER        		7
#define SHADINGMODELID_NUM				8


I didn’t change the encoding and decoding as looking at it, I assumed it would work with additional ID’s added? I may be wrong on this so please let me know.

====================================================================================================================================
Engine\Source\Runtime\Engine\Classes\Engine\EngineTypes.h

4.8 [Line 197]
Engine side definition of the Material Lighting Model. This allows it to be selectable in the Material Editor


MSM_TwoSidedFoliage		UMETA(DisplayName="Two Sided Foliage"),
	MSM_MyShader     		UMETA(DisplayName = "My Shader"),
	MSM_MAX,

====================================================================================================================================
Engine\Source\Runtime\Engine\Private\Materials\MaterialShared.cpp

4.8 [Line 1221]
Ensure that the shader compiler sets our new custom lighting model if selected


case MSM_TwoSidedFoliage:	OutEnvironment.SetDefine(TEXT("MATERIAL_SHADINGMODEL_TWOSIDED_FOLIAGE"),	TEXT("1")); break;
		case MSM_MyShader:		OutEnvironment.SetDefine(TEXT("MATERIAL_SHADINGMODEL_MYSHADER"),			TEXT("1")); break;
		default:

====================================================================================================================================
BasePassPixelShader.usf

4.8 [Line 845]
Set the Lighting Model ID based on the Material Lighting Model selected


#elif MATERIAL_SHADINGMODEL_CLEAR_COAT
			GBuffer.ShadingModelID = SHADINGMODELID_CLEAR_COAT;
		#elif MATERIAL_SHADINGMODEL_MYSHADER
			GBuffer.ShadingModelID = SHADINGMODELID_MYSHADER;

====================================================================================================================================

The problem I am having now is where the best place is to setup my new shader code. Any changes I am making in DefereedLightingCommong are causing a lot of unneeded shader compilations when running again. Preferably, I would like to take the BRDF functionality, put it in a separate .usf can have it use that file whenever my ID is set to my own shader. Is this possible at all with the current set up?

I would really like to implement Oren-Nayar diffuse in my game. I have a lot of rough surfaces underwater (Sand, grass, rocks, coral, aquatic animals) that really benefit from the softness of Oren-Nayar diffuse.

Sadly, I couldn’t find the Oren-Nayer model in these shader files. However, some research online lead me to this:

I plugged that code into a post process material using the G-buffer roughness, and presto! Instant Oren-Nayar substitute. It doesn’t look great on surfaces with sharp roughness <0.3, and since this is a post process it doesn’t handle translucency all too well (and particles can change brightness as they pass different roughness objects on the screen). But for my purposes it worked beautifully. Epic should make an official Oren-Nayer shading option later on for projects that are using simple, rough shaders and could benefit greatly from it.

You can change shading model in:
ShadingModels.usf(62)
Just comment Lambert and uncomment OrenNayar.
In BRDF.usf there is also Gotanda Diffuse, but I don’t know this one.

hi with the 4.17 preview we can create shaders within plugins so if you can update the tutorial it would be nice !