ue4.26 base pass宏和lighting pass宏

一,basepass宏

能在母材质面板上设置的宏,为basepass宏,只能影响basepass。

可以用已有的宏MATERIAL_SSR做个试验。

我们通过下面代码可知,MATERIAL_SSR宏对应材质编辑器detail面板上的Screen Space Reflections

在ShadingModels.ush的DefaultLitBxDF中加入测试代码:

//ShadingModels.ush
...
FDirectLighting DefaultLitBxDF( FGBufferData GBuffer, half3 N, half3 V, half3 L, float Falloff, float NoL, FAreaLight AreaLight, FShadowTerms Shadow ) { BxDFContext Context; ... Lighting.Transmission = 0;
//test begin #if MATERIAL_SSR Lighting.Diffuse=float3(0,1,0); #endif //test end return Lighting; }
...

材质编辑器Details面板勾与不勾Screen Space Reflections,效果分别如下:

可见加在ShadingModel函数里的MATERIAL_SSR宏起了作用。

但这是因为我们把材质设成了 “前向透明”(Blend Mode=Translucent,Lighting Mode=Surface ForwardShading),而前向透明是完全在basepass里画的(在basepass里直接调用shadingmodel函数),所以宏MATERIAL_SSR才起作用。

假如我们把Blend Mode改为Opaque,由于Qpaque是在lighting pass里才调的shadingmodel函数,所以宏MATERIAL_SSR不再起作用(当选Opaque时Screen Space Reflections就变灰了),效果如下:

 也可以仿照MATERIAL_SSR的代码,写一个自己的宏,比如:

//Material.h
...
        /** SSR on translucency */
	UPROPERTY(EditAnywhere, Category=Translucency, meta=(DisplayName = "Screen Space Reflections"))
	uint8 bScreenSpaceReflections : 1;
        
        //yang chao begin
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = ForwardShading, meta = (DisplayName = "My Test Check"))
	uint8 bMyTestCheck : 1;
	//yang chao end    
...

  

//MaterialShared.h
...
virtual bool ShouldDoSSR() const { return false; }
virtual bool IsMyTestCheck() const { return false; }//yang chao add
... ENGINE_API virtual bool ShouldDoSSR() const override; ENGINE_API virtual bool IsMyTestCheck() const override;//yang chao add ...

  

//MaterialShared.cpp
...
bool FMaterialResource::ShouldDoSSR() const { return Material->bScreenSpaceReflections; }
bool FMaterialResource::IsMyTestCheck() const { return Material->bMyTestCheck; }//yang chao add
...
OutEnvironment.SetDefine(TEXT("MATERIAL_SSR"), ShouldDoSSR() && IsTranslucentBlendMode(GetBlendMode()));
OutEnvironment.SetDefine(TEXT("MATERIAL_MY_TEST_CHECK"), IsMyTestCheck());//yang chao add
...

  

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

//test begin
	#if MATERIAL_MY_TEST_CHECK
	Lighting.Diffuse=float3(0,1,0);
	#endif
//test end
	return Lighting;
}        
...

  设为 前向透明 时,勾与不勾My Test Check,效果分别如下:

 设为 opaque时,勾与不勾My Test Check,效果分别如下:

 可见,还是一样的结论。

也可以不改c++,用custom node实现,在材质设置为 前向半透明 的情况下,开启和关闭MATERIAL_MY_TEST_CHECK宏:

 所以,对于 前向半透明 而言,可以不增加新 shading model,而通过base pass宏来实现同样效果。

 

二,lighting pass宏

如果想让shadingmodel函数里的宏在opaque模式下起作用,需要用lighting pass宏。

例如模仿SUPPORTS_ANISOTROPIC_MATERIALS写一个新的lighting pass宏MY_TEST_CHECK2:

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

//test begin
	#if MY_TEST_CHECK2
	Lighting.Diffuse=float3(0,1,0);
	#endif
//test end
	return Lighting;
}        
... 

运行会触发断点警告:

 继续运行,效果如下:

感觉这种lighting pass宏用处不大,因为不能像base pass宏那样逐母材质设置,只能全局设置(比如用view或者指令)。而且会导致变体大量增加(因为lighting pass本身就已经有很多变体)(虽然可在ShouldCompilePermutation函数中作一些剪裁)。

与其用lighting pass宏,还不如新增shading model,或者通过写gbuffer把值传到lighting pass。

----补充:

light pass中这种变体开关(PermutationVector),也可以用于basepass,见:

ue4.26 运行时切换变体 - 知乎 (zhihu.com)

 

posted on 2023-11-20 02:23  wantnon  阅读(109)  评论(0编辑  收藏  举报

导航