I’ve tried to implement this code in a Unity3D Surface Shader, overlay looks outright wrong and RNM seems to do the normal blending correctly but the lighting looks totally wrong. All the other ones look correct & pretty similar, but that might be because my test normal maps are pretty simple and on a sphere.
Here is the code for overlay:
float overlay(float x, float y)
{
if (x < 0.5)
return 2.0*x*y;
else
return 1.0 - 2.0*(1.0 - x)*(1.0 - y);
}
// Overlay Blending
float3 overlayBlend(float3 n1, float3 n2)
{
float3 n = float3(overlay(n1.x, n2.x), overlay(n1.y, n2.y), overlay(n1.z, n2.z));
return normalize(n*2.0 - 1.0);
}
RNM:
float3 rnmBlend(float3 n1, float3 n2)
{
n1 = n1*float3( 2, 2, 2) + float3(-1, -1, 0);
n2 = n2*float3(-2, -2, 2) + float3( 1, 1, -1);
return normalize(n1*dot(n1, n2)/n1.z - n2);
}
and here is the pertinent surface shader part:
void surf (Input IN, inout SurfaceOutput o)
{
float3 main_normal = UnpackNormal(tex2D (_MainNormalTex, IN.uv_MainTex));
float3 target_normal = UnpackNormal(tex2D(_TargetNormalTex, IN.uv_MainTex));
// float3 targetBlendedNormal = linearBlend(main_normal, target_normal);
// float3 targetBlendedNormal = overlayBlend(main_normal, target_normal); //not working correctly
// float3 targetBlendedNormal = partialDerivativeBlend(main_normal, target_normal);
// float3 targetBlendedNormal = whiteoutBlend(main_normal, target_normal);
float3 targetBlendedNormal = udnBlend(main_normal, target_normal); //using this for now
// float3 targetBlendedNormal = rnmBlend(main_normal, target_normal); //not working correctly
// float3 targetBlendedNormal = unityBlend(main_normal, target_normal);
o.Normal = lerp( main_normal, targetBlendedNormal, blendAmount);
}
not sure why its not working well, I can post pics if required.