Post Process Absolute World Position is weird

The Absolute World Position node is acting weird whenever I attempt to use it in a post process material. UE5.2 only, works fine in UE4. It works perfectly normally on surface materials…

Probably this.

1 Like

Yup. That’s it. Turning ScreenPercentage to 100 fixes it.

3 Likes

So what’s the fix for having it with ScreenPercentage != 100?

A solution to calculate a corrected WorldPosition exists!

Huge thanks To Dan Gant from the Unreal Slackers discord, and his elegant and clear solution (https://discord.com/channels/187217643009212416/221799195806400512/1325549330102485035)
Here is his solution:

Step 1: Create this first material function (I named it MF_CameraToPixelDirection_FromViewportUVAndSceneDepth_ForPostProcessMaterialsFix):

Step 2: Use it in this second material function (I named it MF_WorldPosition_FromViewportUVAndSceneDepth_ForPostProcessMaterialsFix):

You can then use the MF_WorldPosition_FromViewportUVAndSceneDepth_ForPostProcessMaterialsFix’s Absolute World Position output instead of your normal World Position node.

Read the comments to understand the root of the problem and why the solution works!

3 Likes

感谢您的回复,它很好的解决了我的问题。但我在ue5中使用时仍然出现了一些bug。因此我把custom hlsl里的代码修改成了:
float2 ClipXY = (ViewportUV * 2 - 1) * float2(1,-1);
float4 ClipPos = float4(ClipXY,SceneDepth,1);
float4 WorldPos = mul(ClipPos,PrimaryView.ClipToTranslatedWorld);
WorldPos.xyz /= WorldPos.w;
return normalize(PrimaryView.TranslatedWorldCameraOrigin - WorldPos.xyz);
另外需要把scene Depth节点改成SceneTexture里的SceneDepth。这样在我这边就可以了。

Thank you for your response, which helped address my issue. However, I still encountered some bugs when implementing it in UE5. After adjustments, I modified the code in the Custom HLSL to:
float2 ClipXY = (ViewportUV * 2 - 1) * float2(1,-1);
float4 ClipPos = float4(ClipXY,SceneDepth,1);
float4 WorldPos = mul(ClipPos,PrimaryView.ClipToTranslatedWorld);
WorldPos.xyz /= WorldPos.w;
return normalize(PrimaryView.TranslatedWorldCameraOrigin - WorldPos.xyz);
Additionally, I needed to replace the ​Scene Depth node with ​SceneTexture: SceneDepth from the SceneTexture palette. With these changes, the implementation now works correctly in my project.

1 Like

I’ve implemented these solutions, and put them into a UE5.5.4 project. Unfortunately, none of them worked for me in the latest version (I didn’t test them in 5.2), but I did find a simple solution after reading Dan’s explanation- although it may not work in all situations.

By changing the material’s Blendable Location to “Scene Color After DOF” (or “Before Tonemapping” in 5.2), the problem disappears.

The problem (in 5.5.4), where the Z (blue) is present where it shouldn’t be, and appears as scan lines. (This is the core of the issue where the Z coordinate of AbsoluteWorldPosition is borked)


The solution, where the Z is correct and the (-X,-Y,-Z) area that’s clamped to 0 appears as the normal black rather than blue.

@Vioxtar @gexurong Please let me know if you see any issues with my implementations

Same problem exists with standard (non post process) materials. But in this case “Absolute World Position” acts weird if used in computation for the Opacity Mask pin, in Nanite, spline meshes.

Any workarounds in this case?

Are you referring to this effect: https://www.youtube.com/watch?v=JbkPW9zejJY&feature=youtu.be

I cannot locate the link but there can be precision issues when using Large World Coordinates and Absolute World Position. Essentially, the further you get from the origin [0,0,0] the less-precise things can be, especially when far away.

Using Camera Relative World Position (pick the node, it’s on the details panel), can help correct this. It basically creates the math centric to the camera and not the world, avoiding the precision issue. Since you almost never see so far from the camera to run into a precision issue wheres with absolute coordinates you can still travel around the level to get to such a state.

If you are using distance-based effects for grass, etc, try using camera-centric:

NO IDEA if this is the root cause, but worth a try. And FWIW IIRC using camera-centric cuts down on large-world coordinate conversions, the LWC numbers you see on the bottom of the material. Smaller #'s there just = better. So in some-cases you might just-want for this, GL!

EDIT: This isn’t it but does speak to some of what I wrote above: Large World Coordinates Rendering in Unreal Engine 5. | Unreal Engine 5.5 Documentation | Epic Developer Community