Friday, May 20, 2005

Normal Map seams in 3ds Max

There is a bug that creates lighting seams at UV borders when using normal maps and .fx shaders in 3ds Max 7. I created a sample file to show the results of the bug. You can download it here.

This file uses HLSLnormal_map_specular.fx for the DirectX 9 shader. This shader and the required textures are also included with this zip file. More information about the shader is available here.

Three test cases are shown in the sample file. The first test case (the cylindar on the left) uses a blank normal map - meaning that all of the pixels in the normal map are (127,127,255) - so all of the normals should be pointing straight off the surface. The cylindar has a cylindrical projection UV map applied. In the final release version of Max 7 (7.0 SP1), a seam is clearly visible running from the top to the bottom of the cylindar along the edge where one side of the UV map meets the other. This seam should not occur since the faces on either side of the seam share the same smoothing group and the pixels in the normal map are all exactly the same color.

In the second test case, I'm using a more complex normal map with the same texture coordinates. The same sceam exists. This seam is not caused by the normal map because if I apply the same normal map to a flat plane and tile it, there is no seam.

In the last test case, bot the cylindar and the sphere are face mapped, so every quad on the cylindar and sphere have UV coordinates from zero to one. The seams (facets) are clearly visible on both the cylindar and the sphere - but they shouldn't be there because all those faces share smoothing groups.

I know that this is a bug because if I open the sample file in the Beta version of Max 7 (version 57), there is no seam. Here's what it looks like in Max 7 Beta:

No Seams in Max 7 Beta

And here's what it looks like in Max 7 Final version with the seams:

Normal Map Seams in Max 7 Final

I think that this bug occurs because the smoothing groups are crossing UV borders. This means that each vertex in max has to be split into two verts to send to the graphics card. To handle this case correctly both verts would have to share the same normal but for some reason, the verts on both sides of the seam are not unified.

If you add a "NormalBump" map to a standard max material and do a software render, there is no seam, so this bug only applies to the real-time viewport display.

This same bug can also be observed when using the two normal map .FX files that are shipped with 3ds Max, DiffseBump.fx and RTTNormalMap.fx, although these shaders yield incorrect lighting - so I didn't use them for this test case.

If you have more infomation about this bug, post it here.

Saturday, May 07, 2005

New Shader!

I've added a new shader to the HLSL Shaders on my web site. You can grab it here:

This new shader is the same as my Normal Map Specular shader but it adds support for three point lights. I was impressed with how much nicer the lighting looks when you can have a key light, a fill light, and a kicker/rim light. Here's an example:

All Three Lights

I'm doing all three point lights in one pass, so this shaders requires 68 pixel shader instructions. That puts it over the limit of 64 instruction in Pixel Shader 2.0 so I had to switch it to use Pixel shader 2.a. That means it requires a higher end graphics card.

A lot of people have been asking about my global illumination shader and how it works so I've also started writing a new tutorial on my method of real-time global illumination. When it's done, the tutorial will cover the use and creation of diffusely convolved cubic environment maps as well as how to create ambient occlusion maps. I'll get it done as quick as I can.