Friday, 30 March 2012

Tura makes precision sculpts.

There's a trick to making sculpts that I've never seen documented.
Suppose you want to make a row of 64 dentils for the cornice of a Greek temple. That can be fitted into a 4x256 sculpt map with plane stitching:

The polygons connecting the cubes will be submerged into the entablature. You can generalise this to having 64 blocks of any size and shape, all sitting on the same flat surface, but you have to be careful of resolution: there are only 256 equally spaced values available for the coordinates, and for this row of 64 blocks, only a few different mark/space ratios are possible.

You generate the map as an uncompressed PNG file and upload it, remembering to select "uncompressed upload" (which you should always do for sculpt maps). Apply a texture with 4x256 repetitions, with edge shading to emphasize the edges, and you get...nothing like.

This isn't LODding, although of course when you try to make every pixel of the sculpt map do real work, it will look bad when the renderer is only using a quarter of the vertices. That's a trade-off you have to judge: LOD well by modelling less detail, or ignore the issue and tell everyone to crank their RenderVolumeLODFactor up to 4. If you're building to sell, you probably have to go the first route.

But the problem here isn't LODding. This is what it looks like at maximum LOD, with uncompressed upload. I spent a lot of time studying my code and the pixels it had generated before deciding that the sculpt map was exactly as I'd intended. The error is in how SL does the upload/download process, and there is a solution.

It seems that on upload, the image is upsampled to have at least 4096 pixels, which here means doubling the resolution each way. I don't know why Second Life should insist on a minimum image size, but this is all I can think of consistent with what I see. (SL will also upsample to a power of 2 each way, but this sculpt map already satisfies that.) Then when used as a sculpt map, it gets downsampled to 1024 pixels, because a sculpt map is always this size at the point where it is used to render a 3D object. The upsampling is done by some sort of interpolation and the downsampling by averaging 2x2 blocks of pixels, resulting in a loss of fidelity. It may not be noticeable for organic shapes (although the degradation is still present), or for sculpt maps that were created already oversize, but it wrecks pixel-perfect positioning of the 1024 vertices.

Here's the solution.

Upsample the image yourself before uploading, not by interpolating, but by replicating each pixel into a 2x2 block of identical pixels. Then the downsampling will just restore the sculpt map to what you wanted.

If you don't need the full 1024 pixels of a sculpt, it is best to use them all anyway, to avoid the same resampling errors. If you don't have a use for them within the actual object you're modelling, just replicate one edge enough to use up the spare pixels in that direction, then do the same in the other direction. The extra polygons will have zero size and not be rendered.

Once you have 1024 pixels, do the upsampling trick and upload it, and it should render in SL exactly as it did in your head.

Pictures taken at Tura's workshop

No comments:

Post a Comment