Volumetric Shadows wrong when rotating Actor

I have a custom mesh component that I am using to generate geometry plane slices for volumetric rendering. (the reason is because I can render the slices in the order I want to get proper layering of translucent material). I am using a translucent material with volumetric lighting for the shadows. I understand this uses fourier opacity maps. The problem is when I rotate my custom mesh object. The shadows drastically change when rotating the mesh slightly.

I am generating the vertices in object space and then I’m using a local vertex factory so that the verts get transformed into world space.

What I would like to know is if the problem is with

a) setting wrong tangents/normals on the vertices ( I set them to flat in object space)
b) whether the fourier opacity maps are being calculated in the right space

The two screen shots show the mesh actor at rotation 0, 0, 0 and 1, 0, 0

What would cause this dramatic change in shadows? It’s doesn’t seem to happen to particle systems.

I have a video here showing something that happens when I rotate the custom mesh actor slowly. the shadows seem to rotate/oscillate in a weird way.

Possible ideas i’ve had are…

  • double rotations/transforms for the fourier shadow generation
  • radians to degrees micalculation (although I couldn’t find any clue as to where)
  • The shadows rate of spin gets faster then slows down which make me think there is some sine/cos wave doubling up going on somewhere.

https://www.youtube.com/watch?v=BlIXaF4FGVY

ok so its almost certainly bounds related. i noticed that the particle system bounds would always be world aligned even when rotated but with the mesh, the bounds are being calculated in object space as a box cube and then transformed by the given LocalToWorld FTrransform and so being rotated.

I make the bounding box small and saw the shadows being shown in a little box that was rotated. So in the calcBounds function for the mesh, I removed the rotation part and forward through just translate and scale. the shadows dont rotate now which is good but the size doesn’t adapt to the world roation of the cube. I’ll have to look at the source to see how the particle system does it.

I would just do world space bounds calculations but I noticed that the calc bounds function was being called twice, once with a scale of 1,1,1 and then again with the work scale.

not sure how to calc the bounds properly at this stage.

Hi dokipen -

Can you let me know in your Mesh Data Module what your Mesh Alignment, Camera Facing, Camera Facing Options are set to? And if you have set it in your required module what is your Screen Alignment set to?

Thank You

Eric Ketchum

Hi Eric.

Thanks for your reply. As I stated in the Question, I am using a custom mesh component inside of an actor. This is not using a particle system so there is no mesh data module or required module.

Hi dokipen -

My apologies this issue tends to come up more with Particles, I will retest with this new information and get back in touch with you as soon as I can.

Eric Ketchum

Great thanks. I need to experiment with how I calc the bounds as well.

I’ve tried getting the min/max verts, transforming by LocalToWorld and then calcing an AABB box but that didn’t work. Next I’ll try doing it how the staticMesh component calcs bounds like this…

FBoxSphereBounds NewBounds = StaticMesh->GetBounds().TransformBy(LocalToWorld);
// Add bounds of collision geometry (if present).
if(StaticMesh->BodySetup)
{
FBox AggGeomBox = StaticMesh->BodySetup->AggGeom.CalcAABB(LocalToWorld);
if (AggGeomBox.IsValid)
{
NewBounds = Union(NewBounds,FBoxSphereBounds(AggGeomBox));
}
}

Hi dokipen -

I am fairly certain that it is a bounds related issue, but without you generation code it is going to be hard for me to debug it here. If you would like to send me a copy of the project with source to look through you can link to it here or send me a PM in the Forums.

Thank You

Eric Ketchum

It started off as the same as the calcBounds() code here which is what is used in the video…

the bounds must be getting rotated because they are transformed by the localtoworld matrix. ive tried an aabb box but couldnt get that to work.

Hi dokipen -

Try looking into the Fixed Bound Settings for Particle Effects you may be able to use that code to assist you in generating the bounds for your tesseract. In addition to the bounds I also think there is a problem with rotating vertex normals that are causing you problems with the lighting. I would be curious if transforming the vertex normals to tangent space would correct some of your issue.

Finally are you generating your tesseract rotation through code or a blurprint?

Thank You

Eric Ketchum

I’m going to try to get the code to you when I get to my workstation. Do prefer the whole project, just the source + textures or a github repo?

Also with the normals, when I do the FDynamicMeshVertex setTangents in my sceneproxy, is that meant to accept tangent space normals directly or object space? Or am I meant to calc the object space normals and then run it through a matrix to convert and then set them?

Hi dokipen -

Which ever way is most convenient I can work with, if you are doing your rotation in Blueprints I would need your project though.

The engine should accept tangent space normals directly, but the tangent and binormal is where I think something is happening as it looks like in your video that the light is being calculated on a UV coordinate this is in motion. I could be wrong though which is why I wanted to see you project.

Thank You for you patience -

Eric Ketchum

I’ve pm’d you on the forums with the c++ code. Cheers!

Hey -

I received your message and we are digging through the code now and I want to test a few things and I will get back in touch with you.

Thank you for your patience.

Eric Ketchum

Thanks Eric I appreciate it.

I just saw James Golding’s Tangent generation here…

https://github.com/EpicGames/UnrealEngine/blob/5b75599e0096d94d05c1317944815234cb8e3966/Engine/Plugins/Runtime/ProceduralMeshComponent/Source/ProceduralMeshComponent/Private/KismetProceduralMeshLibrary.cpp

… which looks like it might be useful.

Hi dokipen -

Ok so after several days beating my head against it, I have narrowed it down to a tangent issue with your inversion code, when your triangles are registering as inverted the tangents are incorrectly getting inverted as well which is causing your light to flip to black. What I think you are trying to do is give the motion with the updating vertices locations and the actor rotation which seems to work beautifully, but when the triangle is registering as inverted the tangent should not be inverted as well since it will take the light and shift the direction (hence the light to dark).

Now the difficult part is going to be trying to correct this issue and the Tangent generation above may have the solution but the issue is that the code you are using is based on the 4.7.X Procedural Generation code available via a user’s plugin while James’ code above is based on a totally different set of Procedural Generation Code and so far I have not been able to get the two to play nice together.

I apologize for the delay getting back to you I wanted to make sure i had tracked down as much information as I could.

Thank You

Eric Ketchum

Hi Eric. Thanks again for your help with this. Unfortunately I still can’t get it working. The flipping of the triangle sorting order is to make sure that they are always facing the camera and that they always render back to front to keep the translucency order.

I’ve tried inverting the tangents but It had no effect. I’ve also tried transforming the tangents by the inverse actor rotation in case they were being transformed by the actor rotation. I’ve tried setting explicit tangents(albeit wrongs) but again no effect.

The only thing that affects the shadow density at the moment seems to be the bounds. Is there anyone there that knows about the fourier opacity maps and their relationship to tangents and/or bounds?

Any more help would be much appreciated!

Hi -

So I sent your issue out to our full rendering team and Daniel Wright reminded me that Translucent Shadows have been broken from January until 4.8. The CL-2561171 (will be integrated in 4.8 release, it is not currently integrated in Preview 4) will fix the issue, but also there are still some bugs in overshadowing, so this may fix some but not all of the problems.

Let me know if integrating that CL fix or 4.8 fixes your issue for you -

Eric Ketchum

Hi Eric.

I just downloaded 4.8 Release version from launcher and recompiled my code for it. The CL fix doesn’t fix the issue with the pulsing shadow intensity. I was getting my hopes up too. :slight_smile:

If Daniel has any other bright ideas then I’d be eager to hear about them.

From my intuition, it looks as though the shadow map is being transformed when the actor rotates. It isn’t a linear relationship though which you can see in the youtube video i submitted in a previous message above. It starts off a slow change and then speeds up even though the actor rotation is happening at a constant rate.

One strange thing is that I can’t see the bounds rendered in my viewport (i have an updated bit of code to see the meshcomponent in the editor viewport which I’ll forward on) so I cant see if there is an issue with the bounds.

Also this doesn’t happen with static mesh actors. Just don’t know what the difference is.

Am very eager to get this working for a game project I am working on. So if Daniel W or James Golding (who wrote the new procedural mesh component) have any clues then I’d be very grateful.

Hi dokipen -

We’ve not forgotten you. Your project converted to 4.8 was actually triggering a specific crash that we have been tracking down so I’ve been focusing on trying to solve that issue. It looks to be solved now and I am going to try to convert your project again and get a clean 4.8 copy out to people.

Thank you again for the patience -

Eric Ketchum