Switching from lambert diffuse to oren nayar diffuse !

[FONT=&amp]Hey so i’m doing a game mostly made in sand and concrete so oren nayar is way better then the default lambert, in 4.17 i was able to switch from lambert to oren nayar with this fonction in the shadingmodels.ush : [FONT=&amp]

[FONT=&amp]But this fonction isn’t here anymore in 4.22 how do i switch to oren nayar now ? thanks in advance :slight_smile: !

(Oren nayar is still in the BRDF library)

Bump.

I would like to know this as well.

Would like to know this too, since it seems to have changed in recent versions.

Well, it seems that they split it up between ShadingModels.ush and BRDF.ush.

On BRDF you’ll find the three methods defined as functions. I havne’t tried yet but ShadingModels inherit from BRDF so you probably should change the six calls to this function.


float3 Diffuse_OrenNayar( float3 DiffuseColor, float Roughness, float NoV, float NoL, float VoH )
{
    float a = Roughness * Roughness;
    float s = a;// / ( 1.29 + 0.5 * a );
    float s2 = s * s;
    float VoL = 2 * VoH * VoH - 1;        // double angle identity
    float Cosri = VoL - NoV * NoL;
    float C1 = 1 - 0.5 * s2 / (s2 + 0.33);
    float C2 = 0.45 * s2 / (s2 + 0.09) * Cosri * ( Cosri >= 0 ? rcp( max( NoL, NoV ) ) : 1 );
    return DiffuseColor / PI * ( C1 + C2 ) * ( 1 + Roughness * 0.5 );
}

You need to change the DefaultLitBxDF function in ShadingModels to use the Diffuse_OrenNayar diffuse model. You’ll need to add in the missing variables that Oren-Nayar needs to call it correctly.

I tried, but I don’t see any difference. I deleted Saved, Intermediate, DerivedDataCache and %LOCALAPPDATA%\UnrealEngine\Common\DerivedDataCache\ folders. When I open my project Unreal recompiles global shaders. I did some tests by adding errors, to see if the shaders compilation fails and it does. So I am sure my changes get compiled. I also tried setting Lighting.Diffuse *= 0 to produce some clearly visible results, but everything still looks the same. I have a simple scene with a sphere mesh and a point light.

Here’s how I changed DefaultLitBxDF in ShadingModels.ush (UE 5.6):

FDirectLighting DefaultLitBxDF( FGBufferData GBuffer, half3 N, half3 V, half3 L, float Falloff, half NoL, FAreaLight AreaLight, FShadowTerms Shadow )
{
	BxDFContext Context;
	FDirectLighting Lighting;
	Lighting.Diffuse = 0;
	Lighting.Specular = 0;
	Lighting.Transmission = 0;

#if FEATURE_LEVEL == FEATURE_LEVEL_ES3_1
	// adjust N for Adreno shader compilation bug. See UE-274816
	N = N * 0.5f;
	N = normalize(N);
#endif

	BRANCH
	if (NoL > 0.0f)
	{
#if SUPPORTS_ANISOTROPIC_MATERIALS
		bool bHasAnisotropy = HasAnisotropy(GBuffer.SelectiveOutputMask);
#else
		bool bHasAnisotropy = false;
#endif

		float NoV, VoH, NoH;
		BRANCH
		if (bHasAnisotropy)
		{
			half3 X = GBuffer.WorldTangent;
			half3 Y = normalize(cross(N, X));
			Init(Context, N, X, Y, V, L);

			NoV = Context.NoV;
			VoH = Context.VoH;
			NoH = Context.NoH;
		}
		else
		{
#if SHADING_PATH_MOBILE
			InitMobile(Context, N, V, L, NoL);
#else
			Init(Context, N, V, L);
#endif

			NoV = Context.NoV;
			VoH = Context.VoH;
			NoH = Context.NoH;

			SphereMaxNoH(Context, AreaLight.SphereSinAlpha, true);
		}

		Context.NoV = saturate(abs(Context.NoV) + 1e-5);

		// --- Oren–Nayar diffuse ---
		// Uses DiffuseColor, Roughness, NoV, NoL, VoH.
		Lighting.Diffuse = Diffuse_OrenNayar(
			GBuffer.DiffuseColor,
			GBuffer.Roughness,   // pass unsquared roughness; function handles it internally
			NoV,
			NoL,
			VoH
		);
		Lighting.Diffuse *= AreaLight.FalloffColor * (Falloff * NoL);
		//this_will_fail();

		BRANCH
		if (bHasAnisotropy)
		{
			Lighting.Specular = AreaLight.FalloffColor * (Falloff * NoL) * SpecularGGX(GBuffer.Roughness, GBuffer.Anisotropy, GBuffer.SpecularColor, Context, NoL, AreaLight);
		}
		else
		{
			if (IsRectLight(AreaLight))
			{
				Lighting.Specular = RectGGXApproxLTC(GBuffer.Roughness, GBuffer.SpecularColor, N, V, AreaLight.Rect, AreaLight.Texture);
			}
			else
			{
				Lighting.Specular = AreaLight.FalloffColor * (Falloff * NoL) * SpecularGGX(GBuffer.Roughness, GBuffer.SpecularColor, Context, NoL, AreaLight);
			}
		}

		FBxDFEnergyTerms EnergyTerms = ComputeGGXSpecEnergyTerms(GBuffer.Roughness, Context.NoV, GBuffer.SpecularColor);

		// Diffuse attenuation by specular layer (energy preservation)
		Lighting.Diffuse *= ComputeEnergyPreservation(EnergyTerms);

		// Specular multiple scattering term (energy conservation)
		Lighting.Specular *= ComputeEnergyConservation(EnergyTerms);

		Lighting.Transmission = 0;
	}

	return Lighting;
}

coming from TI’s video? that line of code should work. 5.6.1 has some more if statement around tho, for rough diffuse material support. i dunno, tbh.

works for me… tested. hmm

Yeah, I watched TI’s video I thought I should give it a shot :smiley: So my code works for you? Can you share some before and after pictures?

well… not exactly the code. but a compatible 5.6.1 permutation with a random result.

i don’t have a nice head asset in unreal rn, but this is what the shader mod does to the world lighting.

lambert

oren nayar

this is the shader alteration

it does function. computes alot more instructions for no gain and some changes. still just a lil piece of random ligthing shader code. still needs artist tweaks to get it too look good. btw… TI is not an artist. i’ll tell you that. don’t take his videos too serious, when it comes to artist and shading driven decisions. he doesn’t have that beef.

i could mod it to use half lambert and look like source engine. i don’t think he knows howto do that. :sweat_smile:

7 Likes

Thank you :slight_smile: I will try your snippet and see if I can spot any noticeable changes this time :smiley:

in UE 5.7 full release Substrate should get a new thing called “EON rough diffuse model” after a quick google search it looks like an improvement over “Oren–Nayar” and stands for “Energy-preserving Oren–Nayar” (EON)

[Portsmouth et al. 2025, “EON: A Practical Energy-Preserving Rough Diffuse BRDF”]

https://github.com/EpicGames/UnrealEngine/commit/72c33452e9e6db428b72281571dcac7b16fe312b

The default remains the current v2 version of the Chan model until we can further investigate the performance of the EON model across platforms.

And v2 version of Chan model.

[ Chan 2024, “Multiscattering Diffuse and Specular BRDFs”, Unpublished manuscript ]

https://github.com/EpicGames/UnrealEngine/commit/1c8b4a175c828fd9d5db55da581321e556c72180

honestly i don’t know why would any indie care about any of this stuff. This TI guy is living in his own fantasy world and like a typical gamer thinks a game engine covers like 90% of the work needed for a AAA game. When in reality all AAA games created in the past 20 decades were build on already existing engines and they STILL take 3-5 years to make (or even more, not to mention countless AAA games stuck in development hell and never see the light of day or shut down right after their release) and 100+ mil of dollars, especially open worlds. It doesn’t matter if unreal can give you the most advanced rendering tech or not, if you don’t have an army of artists and millions on dollars you will never be able to create these realistic assets anyway. And most players can’t even see the difference if ray-tracing is on or not, let alone some shading models… Funny how he keeps comparing baked lighting to real-time in his “commonly praised frostbite titles list” Battlefield V, SW Battlefront II, Mirror’s Edge: Catalyst (not sure why this one even on the list, when it wasn’t praised by anyone when it was releesed and it was the same old story - “original 2008 was better and run better” crowd.) all of these frostbite games use lightmaps via Enlighten middleware, that’s why they look so good becase they take days to bake on a render farm of 100+ computers, not becase they have some amazing shading model.

The Callisto Protocol uses baked lighting too, didn’t sell much and epic was giving it away for free on EGS. Striking Distance Studios next game was “Redacted” and they went with stylised visuals this time. Game didn’t sell anything sadly and was giving away for free on EGS aswell. There’s a high chance it was their last game. Realism doesn’t sell like it used to, majority of gamers are under 20 and modern gamers grow up playing on their phones. Nintendo switch 1 is the most popular console for a reason.

2 Likes

“honestly i don’t know why would any indie care about any of this stuff” I agree with him that better shading models makes even indie games look better. You don’t need ultra-realistic assets to notice the difference. In fact, the differences in shading models are probably more immediately noticeable on assets with less detail. While it may be something that people don’t immediately think about, it can definitely make even low-budget games look more appealing by just making things look more tangible.

In this pic top left is lambert and bottom right is EON