skin shading - stretch correction

Wednesday, September 30, 2009 | |

Ok, a little update on the skin shading, especially the calculation of the stretch correction map.


I encountered a problem with the implementation of the stretch-map rendering. I use the ddx() function to get the derivative of the world position in UV space, i.e. how much the world position changes from one pixel to the next. This way you get a nice approximation of the texture coordinate distortion. For more information about the whole process have a look at my previous post here.

But unfortunately when I started compiling the CG shader, I got an error message like this:

Cg in program 'frag': error C3004: function "ddx" not supported in this profile at line 36
Cg in program 'frag': error C3004: function "ddy" not supported in this profile at line 37
After a while I figured out, that the problem comes from the ARB fragment program. In OpenGL mode Unity compiles the CG into an ARB program, which do not support the derivative instructions. So I added the "#pragma only_renderers d3d9" statement, and now I got a DirectX-Only shader and with it a Windows-Only shader. So what could I do?

First I had a look at the results that this shader now gave me. I roughly skinned the head model to three joints and did a short test animation. To my surprise the stretchmap did not change so dramatically. So perhaps I could get along with a prebaked map? After all the whole skin-shading thing has become pretty complex and getting rid of some extra steps each frame sounds not too bad.

In the current version I use script to create the stretchmap in the editor, save it and use that one at runtime on both platforms, OpenGL and DirectX. I started with the actual rigging of the face, so soon I will see if this solution is sufficient when it comes to facial expressions with a lot of movement.


For comparison I created a simple rectangular polygon strip with 5 divisions in the horizontal axis. The UV coordinates are getting smaller from left to right like this:

Then the plane was lit with a directional light and a b/w line pattern was used as cookie-texture, so you can easily see how far the light is scattered. In the following image you can see the resulting RGB-image of the plane in the top row and below the absolute error (assuming that the scattering in the middle of the left polygon is correct).

As you can see, the error in the left image is increasing with the UV size decreasing, due to the equal sampling width everywhere. On the right side, where we use the precalculated stretchmap, the error stays much smaller. As a result the stripes look much more uniform, even with large changes in UV size.

0 comment(s):

Post a Comment