LumenSceneProbeGather:RadianceCache

[numthreads( 8 ,  8 , 1)]
void TraceFromProbesCS(
	uint3 GroupId : SV_GroupID,
	uint2 GroupThreadId : SV_GroupThreadID)
{
	uint TraceTileIndex = GroupId.y *  128  + GroupId.x;

	if (TraceTileIndex < ProbeTraceTileAllocator[0])
	{
		uint2 TraceTileCoord;
		uint TraceTileLevel;
		uint ProbeTraceIndex;
		UnpackTraceTileInfo(ProbeTraceTileData[TraceTileIndex], TraceTileCoord, TraceTileLevel, ProbeTraceIndex);

		uint TraceResolution = (RadianceProbeResolution / 2) << TraceTileLevel;
		uint2 ProbeTexelCoord = TraceTileCoord *  8  + GroupThreadId.xy;


		float3 ProbeWorldCenter;
		uint ClipmapIndex;
		uint ProbeIndex;
		GetProbeTraceData(ProbeTraceIndex, ProbeWorldCenter, ClipmapIndex, ProbeIndex);

		const float3 ProbeTranslatedWorldCenter = ProbeWorldCenter +  LWCToFloat( GetPrimaryView() .PreViewTranslation) ;

		if (all(ProbeTexelCoord < TraceResolution))
		{
			float2 ProbeTexelCenter = float2(0.5, 0.5);

			float2 ProbeUV = (ProbeTexelCoord + ProbeTexelCenter) / float(TraceResolution);
			float3 WorldConeDirection = OctahedronToUnitVector(ProbeUV * 2.0 - 1.0);

			float FinalMinTraceDistance = max(MinTraceDistance, GetRadianceProbeTMin(ClipmapIndex));
			float FinalMaxTraceDistance = MaxTraceDistance;
			float EffectiveStepFactor = StepFactor;


			float ConeHalfAngle = acosFast(1.0f - 1.0f / (float)(TraceResolution * TraceResolution));

			FConeTraceInput TraceInput;
			TraceInput.Setup(
				ProbeWorldCenter, ProbeTranslatedWorldCenter, WorldConeDirection,
				ConeHalfAngle, MinSampleRadius,
				FinalMinTraceDistance, FinalMaxTraceDistance,
				EffectiveStepFactor);

			TraceInput.bDitheredTransparency = true;
			TraceInput.DitherScreenCoord = RadianceProbeResolution * uint2(ProbeIndex & ProbeAtlasResolutionModuloMask, ProbeIndex >> ProbeAtlasResolutionDivideShift) + ProbeTexelCoord;

			bool bContinueCardTracing = false;

			TraceInput.VoxelTraceStartDistance = CalculateVoxelTraceStartDistance(FinalMinTraceDistance, FinalMaxTraceDistance, MaxMeshSDFTraceDistance, bContinueCardTracing);

			FConeTraceResult TraceResult = TraceForProbeTexel(TraceInput);

			SharedTraceRadiance[GroupThreadId.y][GroupThreadId.x] = TraceResult.Lighting;
			SharedTraceHitDistance[GroupThreadId.y][GroupThreadId.x] = TraceResult.OpaqueHitDistance;
		}

		GroupMemoryBarrierWithGroupSync();

		uint2 ProbeAtlasBaseCoord = RadianceProbeResolution * uint2(ProbeIndex & ProbeAtlasResolutionModuloMask, ProbeIndex >> ProbeAtlasResolutionDivideShift);

		if (TraceResolution < RadianceProbeResolution)
		{
			uint UpsampleFactor = RadianceProbeResolution / TraceResolution;
			ProbeAtlasBaseCoord += ( 8  * TraceTileCoord + GroupThreadId.xy) * UpsampleFactor;

			float3 Lighting = SharedTraceRadiance[GroupThreadId.y][GroupThreadId.x];

			{
				for (uint Y = 0; Y < UpsampleFactor; Y++)
				{
					for (uint X = 0; X < UpsampleFactor; X++)
					{
						RWRadianceProbeAtlasTexture[ProbeAtlasBaseCoord + uint2(X, Y)] = Lighting;
					}
				}
			}

			float HitDistance = min(SharedTraceHitDistance[GroupThreadId.y][GroupThreadId.x], MaxHalfFloat);

			for (uint Y = 0; Y < UpsampleFactor; Y++)
			{
				for (uint X = 0; X < UpsampleFactor; X++)
				{
					RWDepthProbeAtlasTexture[ProbeAtlasBaseCoord + uint2(X, Y)] = HitDistance;
				}
			}
		}
		else
		{
			uint DownsampleFactor = TraceResolution / RadianceProbeResolution;
			uint WriteTileSize =  8  / DownsampleFactor;

			if (all(GroupThreadId.xy < WriteTileSize))
			{
				float3 Lighting = 0;

				{
					for (uint Y = 0; Y < DownsampleFactor; Y++)
					{
						for (uint X = 0; X < DownsampleFactor; X++)
						{
							Lighting += SharedTraceRadiance[GroupThreadId.y * DownsampleFactor + Y][GroupThreadId.x * DownsampleFactor + X];
						}
					}
				}

				ProbeAtlasBaseCoord += WriteTileSize * TraceTileCoord + GroupThreadId.xy;
				RWRadianceProbeAtlasTexture[ProbeAtlasBaseCoord] = Lighting / (float)(DownsampleFactor * DownsampleFactor);

				float HitDistance = MaxHalfFloat;

				for (uint Y = 0; Y < DownsampleFactor; Y++)
				{
					for (uint X = 0; X < DownsampleFactor; X++)
					{
						HitDistance = min(HitDistance, SharedTraceHitDistance[GroupThreadId.y * DownsampleFactor + Y][GroupThreadId.x * DownsampleFactor + X]);
					}
				}

				RWDepthProbeAtlasTexture[ProbeAtlasBaseCoord] = HitDistance;
			}
		}
	}
}
FConeTraceResult TraceForProbeTexel(FConeTraceInput TraceInput)
{
	FConeTraceResult TraceResult;
	TraceResult = (FConeTraceResult)0;
	TraceResult.Lighting = 0.0;
	TraceResult.Transparency = 1.0;
	TraceResult.OpaqueHitDistance = TraceInput.MaxTraceDistance;
	TraceInput.bZeroRadianceIfRayStartsInsideGeometry = true;

	ConeTraceLumenSceneVoxels(TraceInput, TraceResult);

#if ENABLE_DYNAMIC_SKY_LIGHT
	if (ReflectionStruct.SkyLightParameters.y > 0)
	{
		float SkyAverageBrightness = 1.0f;
		float Roughness = TanConeAngleToRoughness(tan(TraceInput.ConeAngle));

		TraceResult.Lighting = TraceResult.Lighting + GetSkyLightReflection(TraceInput.ConeDirection, Roughness, SkyAverageBrightness) * TraceResult.Transparency;
	}
#endif

	return TraceResult;
}
void ConeTraceLumenSceneVoxels(
	FConeTraceInput TraceInput,
	inout FConeTraceResult OutResult)
{
#if SCENE_TRACE_VOXELS
	if (TraceInput.VoxelTraceStartDistance < TraceInput.MaxTraceDistance)
	{
		FConeTraceInput VoxelTraceInput = TraceInput;
		VoxelTraceInput.MinTraceDistance = TraceInput.VoxelTraceStartDistance;
		FConeTraceResult VoxelTraceResult;
		RayTraceGlobalDistanceField(VoxelTraceInput, VoxelTraceResult);

		#if !VISIBILITY_ONLY_TRACE
			OutResult.Lighting += VoxelTraceResult.Lighting * OutResult.Transparency;
		#endif
		OutResult.Transparency *= VoxelTraceResult.Transparency;
		OutResult.NumSteps += VoxelTraceResult.NumSteps;
		OutResult.OpaqueHitDistance = min(OutResult.OpaqueHitDistance, VoxelTraceResult.OpaqueHitDistance);
	}
#endif
}
void RayTraceGlobalDistanceField(
	FConeTraceInput TraceInput,
	inout FConeTraceResult OutResult)
{
	FGlobalSDFTraceResult SDFTraceResult;

	// Trace SDF ray
	{
		FGlobalSDFTraceInput SDFTraceInput = SetupGlobalSDFTraceInput(TraceInput.ConeOrigin, TraceInput.ConeDirection, TraceInput.MinTraceDistance, TraceInput.MaxTraceDistance, TraceInput.SDFStepFactor, TraceInput.MinSDFStepFactor);
		SDFTraceInput.bDitheredTransparency = TraceInput.bDitheredTransparency;
		SDFTraceInput.DitherScreenCoord = TraceInput.DitherScreenCoord;
		SDFTraceInput.bExpandSurfaceUsingRayTimeInsteadOfMaxDistance = TraceInput.bExpandSurfaceUsingRayTimeInsteadOfMaxDistance;
		SDFTraceInput.InitialMaxDistance = TraceInput.InitialMaxDistance;

		SDFTraceResult = RayTraceGlobalDistanceField(SDFTraceInput);
	}

	float4 LightingAndAlpha = float4(0, 0, 0, 1);

	if (GlobalSDFTraceResultIsHit(SDFTraceResult))
	{
		LightingAndAlpha = EvaluateGlobalDistanceFieldHit(TraceInput, SDFTraceResult);
	}

	OutResult = (FConeTraceResult)0;
	#if !VISIBILITY_ONLY_TRACE
		OutResult.Lighting = LightingAndAlpha.rgb;
	#endif
	OutResult.Transparency = LightingAndAlpha.a;
	OutResult.NumSteps = SDFTraceResult.TotalStepsTaken;
	OutResult.OpaqueHitDistance = GlobalSDFTraceResultIsHit(SDFTraceResult) ? SDFTraceResult.HitTime : TraceInput.MaxTraceDistance;
	OutResult.ExpandSurfaceAmount = SDFTraceResult.ExpandSurfaceAmount;
}

后面与博客内容一致:LumenScreenProbeGather:TraceVoxels_sh15285118586的博客-CSDN博客

你可能感兴趣的:(#,UE之Lumen,UE)