How do I get the light levels at the player's position?

I’m trying to make a stealth game with mechanics similar to Thief. I want the player to hide in the shadows, so I tried raycasting against light sources, but only works with dynamic lights. With static lights, sometimes the indirect lighting can light up an area, making my previous technique less realistic. I want enemies to be able to see the player if the amount of light at their position is bright enough for the enemy to see. The problem is, I don’t know how to do this. So, I’ve been searching around and found this from the UDK forums. I translated the visibility code into C++ and the UE4 API, but when I test it out, my code returns 0. Here’s my function in full:

float AAdNoctvmPlayerCharacter::GetLightingAmount()
{
	FVector Loc = GetActorLocation();
	FCollisionQueryParams Params = FCollisionQueryParams(FName(TEXT("LightTrace")), true, this);
	float Result;
	
	for (TActorIterator<APointLight> ActorItr(GetWorld()); ActorItr; ++ActorItr)
	{
		if (ActorItr->IsA(APointLight::StaticClass()))
		{
			PointLight = *ActorItr;
		}
	}
	
	if (PointLight)
	{
		UPointLightComponent* LightComp = PointLight->PointLightComponent;
		
		if (LightComp)
		{
			FVector End = PointLight->GetActorLocation();
			float Distance = FVector::Dist(Loc, End);
			float LightRadius = LightComp->AttenuationRadius;
			bool bHit = GetWorld()->LineTraceTest(Loc, End, ECC_Visibility, Params);
			
			if (Distance <= LightRadius && !bHit)
			{
				Result = FMath::Pow(1.0 - (Distance / LightRadius), (LightComp->LightFalloffExponent + 1) * (LightRadius * 1.25));
				Result = FMath::Clamp(Result, 0.0f, 1.0f);
			}
			else
			{
				Result = 0.0f;
			}
			
			if (Result > 1.0f)
			{
				Result = 1.0f;
			}
		}
	}
	
	return Result;
}

Honestly, I have no idea what I’m doing with that equation. I just can’t find another way to do this. What’s wrong with it? Is there a better way to do this?

2 Likes

Whoops, I misread the original code. I refactored the equation and now i’m getting some actual numbers. They’re not the most precise results and I’m definitely gonna have to tweak the code, but it works!

Here’s the refactored equation:

Result = FMath::Pow(FMath::Max(0.0f, 1.0f - (Distance / LightRadius)), (LightComp->LightFalloffExponent + 1)) * (LightRadius * 1.25);

Hi vibgyorc6,

If your new question is not directly related to your initial question about light levels, could you please post a new question for it? We would prefer to keep different questions in different posts to make it easier for future readers with similar issues to find possible solutions.

Done and done.

Hi Vibgyorc6

Into my internship i have to make a kind of “e-lux meter”…
I have to get the luminosity of a scene/room/house …

I saw your post and i’m trying to use ur code ahah… well, i’m looking for some help… so if have any news/help… i would be very thanksful

Hey strikeblack91,

have you implemented a solution and are willed to share it?

Thank you!

@fu119922 @anonymous_user_4a89ca7d Does either of you have a solution that they are willing to share?

Kind regards,

Siebren