Materials and normals

When you create a material, there is a check box to select that the material uses “tangent space normals.” I would like to know if this means:
a) the vertex normal input is expected to be in tangent space
b) the normal map texture is expected to be in tangent space
c) the “Normal” pip input on the material block is expected to be in tangent space

Or, if one or more of those do not apply, does this means I have to convert somewhere between tangent space and world space? I ask because while I thought I had everything set up, when I tick tangent space normals to true I appear to get no visible bump mapping at all though vertex lighting appears correct. When I untick this, my normal maps seem to apply but the vertex shading seems to be wrong. The source normal map textures are not mine, but they appear to have the uniformly blue tints I think I would expect from a tangent space normal map.


That option applies to the normal map, where it’s tangent space instead of world space. By default it uses tangent space, if you are using tangent space normal maps you don’t have to do anything extra. Though remember to use correct import settings for normal maps. If you add the word Normal to the file name it will automatically import it as a normal map.

Ok. then my follow up is that the vertex data I am being given (again, the code is not originally mine, so I am trying to understand it, and the tangent stuff is new to me) My vertices have two TangentBasisComponents that look as follows:

DataType NewData;
		NewData.PositionComponent = STRUCTMEMBER_VERTEXSTREAMCOMPONENT(&VertexBuffer, FBrickVertex, X, VET_UByte4N);
		NewData.TextureCoordinates.Add(STRUCTMEMBER_VERTEXSTREAMCOMPONENT(&VertexBuffer, FBrickVertex, X, VET_UByte4N));
		NewData.ColorComponent = STRUCTMEMBER_VERTEXSTREAMCOMPONENT(&VertexBuffer, FBrickVertex, X, VET_Color);
		// Use a stride of 0 to use the same TangentX/TangentZ for all faces using this vertex factory.
		NewData.TangentBasisComponents[0] = FVertexStreamComponent(&TangentBuffer,sizeof(FPackedNormal) * (2 * FaceIndex + 0),0,VET_PackedNormal);
		NewData.TangentBasisComponents[1] = FVertexStreamComponent(&TangentBuffer,sizeof(FPackedNormal) * (2 * FaceIndex + 1),0,VET_PackedNormal);

Where tangent data comes from code that looks as follows:

for(int32 FaceIndex = 0;FaceIndex < 6;++FaceIndex)
			const FVector UnprojectedTangentX = FVector(+1,-1,0).GetSafeNormal();
			const FVector UnprojectedTangentY(-1,-1,-1);
			const FVector FaceNormal = FaceNormals[FaceIndex].ToFloat();
			const FVector ProjectedFaceTangentX = (UnprojectedTangentX - FaceNormal * (UnprojectedTangentX | FaceNormal)).GetSafeNormal();
			*TangentBufferData++ = FPackedNormal(ProjectedFaceTangentX);
			*TangentBufferData++ = FPackedNormal(FVector4(FaceNormal, FMath::Sign(UnprojectedTangentY | (FaceNormal ^ ProjectedFaceTangentX))));

I originally thought this was a substitute for regular face normals, but now I am thinking that the tangent basis is actually a separate thing, and if I want my normal maps to work correctly, I need to combine these values with the normal map (in tangent space) before passing the normal map data on to the Material parameters. Could you either explain to me or point me to some documentation that shows up to do this in the UE material shader? There doesn’t seem to be any official documentation on how this is dealt with in UE, and my shader skills are still fairly weak. I appreciate your time and patience.

What are you trying to do? The workflow for using normal maps shouldn’t require any coding.

I have a cube array generated from Andrew Scheidecker’s BrickGame plugin (which I have now modified). Among other things I have modified it to be able to apply individual texture maps to each side of any cube, with these textures coming from a tile map. The cubes have TangentBasis vectors and no normals. I have normal maps (also tiled) which I want to apply to each face. But the lighting does not seem correct (as in the normal maps don’t seem to take effect when I enable Tangent Space normals.) However, when I do that, then the vertex lighting seems incorrect but the normal maps seem to work (with the incorrect lighting) - so it seems like there is some disagreement somewhere. So I am trying to understand the relationship between lighting, tangent space, the normal map and the Normal input on the material parameters in hopes that it will become obvious to me what the mistake is.

If you wanted to replace the cube with one that has proper normals you could do that instead of figuring out the tangent issue.