Software:
Unreal Engine 4.25
Yet another case where I develop my own costly solution only to find out afterwards that there’s actually a much more efficient built-in solution.. š
In this case the subject is deriving a bump normal from a procedural or non-uv projected height map/texture (like noise, or tri-planar mapping for example).
The built-in way:
Using the pre-made material functions, PreparePerturbNormalHQ and PerturbNormalHQ, the first of which uses the low level Direct3D functions DDX and DDY to derive the two extra surface adjacent values needed to derive a bump normal, and the last uses the 3 values to generate a world-space bump normal:

- Noise coordinates are obtained by multiplying the surface shading point local position by a value to set the pattern density.
- The Noise output value is multiplied by a factor to set the resulting bump intensity.
- The PreparePerturbNormalHQ function is used to derive the 2 extra values needed to derive a bump normal.
- The PerturbNormalHQ function is used to derive the World-Space bump normal.
- Note:
Using this method, the material’s normal input must be set to world-space by unchecking Tangent Space Normal in the material properties.
The method I’m using:
This method is significantly more expensive in the number of shader instructions, but in my opinion, generates a better quality bump.
Sampling 3 Noise nodes at 3 adjacent locations in tangent-space to derive the 3 input values necessary for the NormalFromFunction material function:

- Noise coordinates are obtained by multiplying the surface shading point local position by a value to set the pattern density.
- Crossing the vertex normal with the vertex tangent vectors to derive the bitangent (sometimes called “binormal”).
- Multiplying the vertex-tangent and bitangent vectors by a bump-offset* factor to create the increment steps to the additional sampled Noise values.
* This factor should be parameter for easy tuning, since it determines the distance between the height samples in tangent space. - The increment vectors are added to the local-position to get the final height samples positions.
- The NormalFromFunction material function is used to derive a tangent-space normal from the 3 supplied height samples.
Note:
From my experience, even though the UV1, UV2 and UV3 inputs of the NormalFromFunction are annotated as V3, the function will only work is the inputs are a scalar value and not a vector/color.
Related:
UE4 – Material Functions
UE4 – Bump map
UE4 – fix an inverted normal map
UE4 – Triplanar mapping