Unity2018的HDRPStandard材质分析笔记(五)

本文深入分析了Unity2018的HDRP标准材质在Frag函数中的光照计算过程,包括LightLoop的结构、接触阴影、平型光阴影的计算以及体积雾的影响。文章详细解释了光学深度、散射系数和大气厚度等概念,并探讨了如何替换BSDF实现自定义光照效果。
摘要由CSDN通过智能技术生成

 

之前用超过两篇的篇长分析了GetSurfaceAndBuiltinData,现在回到Frag函数:

    BSDFData bsdfData = ConvertSurfaceDataToBSDFData(input.positionSS.xy, surfaceData);

    PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);

这里重新计算了bsdfData和preLightData,没看到有宏参与,只能先默认Unity编译时有优化。

#ifdef _SURFACE_TYPE_TRANSPARENT
        uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_TRANSPARENT;
#else
        uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_OPAQUE;
#endif

在计算光照之前还有一个featureFlags,后面的宏定义在LightLoop.cs.hlsl:

#define LIGHT_FEATURE_MASK_FLAGS_OPAQUE (16642048)
#define LIGHT_FEATURE_MASK_FLAGS_TRANSPARENT (16510976)

这是一个24位flag,每一位都表示了一种feature。

接下来重点介绍LightLoop

LightLoop定义在LightLoop.hlsl,代码过长,不放在文章里了,看新的结构体定义。

struct LightLoopContext
{
    int sampleReflection;

    HDShadowContext shadowContext;
    
    float contactShadow; // Currently we support only one contact shadow per view
    float shadowValue; // Stores the value of the cascade shadow map
};

同样定义在LightLoop.hlsl,里面套了个HDShadowContext:

struct HDShadowContext
{
    StructuredBuffer<HDShadowData>  shadowDatas;
    HDDirectionalShadowData         directionalShadowData;
};

定义在HDShadowContext.hlsl,又套了两个娃:

struct HDShadowData
{
    float3 rot0;
    float3 rot1;
    float3 rot2;
    float3 pos;
    float4 proj;
    float2 atlasOffset;
    float edgeTolerance;
    int flags;
    float4 zBufferParam;
    float4 shadowMapSize;
    float4 viewBias;
    float3 normalBias;
    float _padding;
    float4 shadowFilterParams0;
    float4x4 shadowToWorld;
};

struct HDDirectionalShadowData
{
    float4 sphereCascades[4];
    float4 cascadeDirection;
    float cascadeBorders[4];
};

定义在HDShadowManager.cs.hlsl。

以后就不写定义在哪个文件里了。

LightLoopContext context;

context.shadowContext = InitShadowContext();
context.contactShadow = InitContactShadow(posInput);
context.shadowValue = 1;
context.sampleReflection = 0;

LightLoop一开始声明并初始化了LightLoopContext。

HDShadowContext InitShadowContext()
{
    HDShadowContext         sc;

    sc.shadowDatas = _HDShadowDatas;
    sc.directionalShadowData = _HDDirectionalShadowData[0];

    return sc;
}

直接从CPU传的StructuredBuffer。

float InitContactShadow(PositionInputs posInput)
{
    // For now we only support one contact shadow
    // Contactshadow is store in Red Channel of _DeferredShadowTexture
    // Note: When we ImageLoad outside of texture size, the value returned by Load is 0 (Note: On Metal maybe it clamp to value of texture which is also fine)
    // We use this property to have a neutral value for contact shadows that doesn't consume a sampler and work also with compute shader (i.e use ImageLoad)
    // We store inverse contact shadow so neutral is white. So either we sample inside or outside the texture it return 1 in case of neutral
    return 1.0 - LOAD_TEXTURE2D(_DeferredShadowTexture, posInput.positionSS).x;
}

获取计算好的contact shadow。

// First of all we compute the shadow value of the directional light to reduce the VGPR pressure
	if (featureFlags & LIGHTFEATUREFLAGS_DIRECTIONAL)
	{
		// Evaluate sun shadows.
		if (_DirectionalShadowIndex >= 0)
		{
			DirectionalLightData light = _DirectionalLightDatas[_DirectionalShadowIndex];

			// TODO: this will cause us to load from the normal buffer first. Does this cause a performance problem?
			// Also, the light direction is not consistent with the sun disk highlight hack, which modifies the light vector.
			float  NdotL = dot(bsdfData.normalWS, -light.forward);
			float3 shadowBiasNormal = GetNormalForShadowBias(bsdfData
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值