[SOLVED] How do I get a flashlight effect to work properly with a procedurally generated mesh.

I have a custom player pawn class which has a spotlight member which acts like a miner’s helmet light. The class member is a USpotLightComponent. I instantiate it in the class constructor like this:

    m_light = CreateDefaultSubobject<USpotLightComponent>(TEXT("Light"));
    m_light->SetupAttachment(RootComponent);

The light appears to always be pointing vertically downward as the surrounding textures render very darkly when looking up, and render properly when looking down.

I printed out the Z component of the light direction, and it does seem to be changing as expected. Logging m_light->GetComponentRotation().Pitch also reports the correct values.

However, when I look directly upwards, the view is very dark. When I look directly down the view looks properly lit, and when I look horizontally, the view looks like it is lit from below.

Down view.

Up view.

Horizontal view.

It looks like the light component is rotating properly, but the actual light effect is not rotating vertically, and possible not horizontally either.

So I tried narrowing the light beam and lo and behold, it turns out that the light is moving perfectly as I rotate the viewpoint. It’s fine…so why are the textures rendering so differently at different angles? The same material is used for everything (this is a work in progress), so with the light at the same angle relative to the surface it should appear the same. It is as if the dynamic lighting is applying extra light when looking down, or rendering the light as if it were pointing down instead of in the light’s actual direction.

Your code is:

    m_light = CreateDefaultSubobject<USpotLightComponent>(TEXT("Light"));
    m_light->SetupAttachment(RootComponent);

I’m honestly surprised that it works with so little setup :D.

For the classic case of a default character in a default environment, I bet that such setup only follows the yaw orientation at best, and all other observations are just false impressions. That’s because, as you rotate your camera, the root component of your pawn, which is its collision capsule, will only rotate “horizontally” (yaw) while keeping its feet firmly on the ground.

But you mentionned using a custom pawn, so here are some observations/questions:

Firstly, is your custom player pawn some kind of spaceship that is rotating in 3 degrees of freedom with your camera? Because otherwise, there is no way that merely attaching the spotlight to the root component of the pawn, would make it point where you’re looking.

Secondly, you should probably setup the relative the location & rotation of the spotlight. I doubt that it sitting at the center of your mesh would be the optimal way of doing it, and I guess it could generate weird shadowing artifacts depending on the geometry. As for the rotation, I don’t even know if the spotlight by default points towards the forward direction. (Probably yes)

Thirdly, if you don’t have a floating spacecraft, but rather a bipedal creature with a head or something, then it would stand to reason that instead of attaching it to the root component, you should attach the spotlight to its head, or perhaps the hand holding the flashlight, etc. Then, comes the challenge of animating said body part to roughly point where the camera is looking.

It’s like a floating spaceship.

The problem was that my call to UKismetProceduralMeshLibrary::CalculateTangentsForMesh() got lost at some point in my development, so all normals on my mesh were pointing upwards.

Doh!