Sloppy Unreal 02: Setting Up Raytracing & Generating Normal Maps In Houdini

Unreal Engine

Part two of working sloppily in Unreal covers setting up raytracing and materials. Also we’ll tackle the generation of normal maps from a grayscale image in Houdini, talk a bit about different approximations for the Fresnel term and finally poke around in Unreal’s console in order to nudge it’s raytracer to where we want it.

Matthias Winckelmann’s UE quickstart workshop.

Lego model from Mecabricks

HDRI from Aixterior

1. Lucca Troll

Unreal materials excpect only the base reflection fraction as an input for specular, because unreal calculates the fresnel internally when rendering using this formula :
vec3 fresnelSchlick(float cosTheta, vec3 f0) {
return f0 + (1.0 – f0) * pow(1.0 – cosTheta, 5.0);
}

So you should not use your own fresnel term and instead play around with the base reflection fraction, the default value used by unreal is 0.5.
Just thought i’d let you know, otherwise great video.

2. Moritz

Hi Lucca,

very interesting, is there a link to some docs that go over UE’s material internals? I’m especially interested what happens when raytracing is enabled, as in my tests the fresnel node was absolutely necessary (A is with fresnel node, B is a specular of 0.04):

Cheers, Mo

• Lucca Troll

Hello Moritz,
i could not find too much information on the internal workings of unreals materials, so i tried to recreate unreals material preview in C4D using Redshift and found out something:
First i converted the F0 value of 0.04 the the corresponding ior of 1.5 using this formula:
ior = -(f0 + 1 + 2 * sqrt(f0)) / (f0 – 1)
Doing this i found out, that unreal internally divides the specular value you give it by 2, to prevent unrealisticly reflective materials.
I came to this conclusion after using a F0 = 0.02 to calculate an ior = 1.33.
When i used this ior value in my redshift material i got this image:
https://cdn.discordapp.com/attachments/209049190293045249/785623615278284830/RedshiftTest.PNG
Wich looks very similar to the B-Image you provided above, so to me it would seem, that the more subtle specular without the custom ior node is more accurate.
I have wrote some code for you, with wich you can convert an ior to the corresponding F0 value, wich is already multiplied by 2 to make it “unreal ready”, just copy and paste this code into your material and pipe in the ior you want:

Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name=”MaterialGraphNode_2″
Begin Object Class=/Script/Engine.MaterialExpressionCustom Name=”MaterialExpressionCustom_0″
End Object
Begin Object Name=”MaterialExpressionCustom_0″
Code=”float f0 = abs((1.0 – Ior) / (1.0 + Ior));\r\nreturn f0 * f0 * 2.0;”
OutputType=CMOT_Float1
Description=”IorToF0″
Inputs(0)=(InputName=”Ior”,Input=(Expression=MaterialExpressionConstant'”MaterialExpressionConstant_2″‘))
MaterialExpressionEditorX=-528
MaterialExpressionEditorY=320
Material=PreviewMaterial'”/Engine/Transient.NewMaterial”‘
bCollapsed=True
End Object
MaterialExpression=MaterialExpressionCustom'”MaterialExpressionCustom_0″‘
NodePosX=-528
NodePosY=320
NodeGuid=3DF03C524EDEE6DF5B4BB99DB39FEC78
End Object

I hope i could help, Lucca

• Lucca Troll

Just noticed, that the code is sent does not work when pasting it inside a material, this code should work now:

Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name=”MaterialGraphNode_6″
Begin Object Class=/Script/Engine.MaterialExpressionCustom Name=”MaterialExpressionCustom_0″
End Object
Begin Object Name=”MaterialExpressionCustom_0″
Code=”float f0 = abs((1.0 – Ior) / (1.0 + Ior));\r\nreturn f0 * f0 * 2.0;”
OutputType=CMOT_Float1
Description=”IorToF0″
Inputs(0)=(InputName=”Ior”,Input=(Expression=MaterialExpressionConstant'”MaterialExpressionConstant_2″‘))
MaterialExpressionEditorX=-528
MaterialExpressionEditorY=320
Material=PreviewMaterial'”/Engine/Transient.NewMaterial”‘
bCollapsed=True
End Object
MaterialExpression=MaterialExpressionCustom'”MaterialExpressionCustom_0″‘
NodePosX=-528
NodePosY=320
NodeGuid=3DF03C524EDEE6DF5B4BB99DB39FEC78
End Object

3. Moritz

Thanks Lucca,

indeed – I just ran your tests in Octane too and you’re absolutely right – thanks for pointing this out and thanks for the script!

Cheers, Mo

• Lucca Troll

No problem, happy i could help

4. Really enjoying this series! Small hiccup, no matter how I import the lego model (as .obj) no materials assignments are included.