Blog Post: Improved UV Dilation using Render Targets

I created a blog post illustrating how to use the new orthographic scene capture and render target system to mostly automate the UV unwrapping and dilating of a mesh with blueprints.

http://shaderbits.com/blog/uv-dilation

It is a bit lengthy to post all here but here are some select images.

64366700594fe1115345237a637e769713c49549.jpeg

UVDilate.gif

simpledilation.jpg

af19c372be0fdcfd40993678b332e940a4370ffd.jpeg

SlopeProjection.jpg

f6eae86df634d5b1f9f3443a22704b714bc13c5c.jpeg


//////////////// UV Positional Dilation ///////////////////////////
//** Tex **// Input Texture Object storing Volume Data
//** UV **// Input float2 for UVs
//** TextureSize **// Resolution of render target
//** MaxSteps **// Pixel Radius to search


float texelsize = 1 / TextureSize;
float mindist = 10000000;
float2 offsets[8] = {float2(-1,0), float2(1,0), float2(0,1), float2(0,-1), float2(-1,1), float2(1,1), float2(1,-1), float2(-1,-1)};

float3 sample = Tex.SampleLevel(TexSampler, UV, 0);
float3 curminsample = sample;

if(sample.x == 0 && sample.y == 0 && sample.z == 0)
{
    int i = 0;
    while(i < MaxSteps)
    { 
        i++;
        int j = 0;
        while (j < 8)
        {
            float2 curUV = UV + offsets[j] * texelsize * i;
            float3 offsetsample = Tex.SampleLevel(TexSampler, curUV, 0);

            if(offsetsample.x != 0 || offsetsample.y != 0 || offsetsample.z != 0)
            {
                float curdist = length(UV - curUV);

                if (curdist < mindist)
                {
                    float2 projectUV = curUV + offsets[j] * texelsize * i * 0.25;
                    float3 direction = Tex.SampleLevel(TexSampler, projectUV, 0);
                    mindist = curdist;

                    if(direction.x != 0 || direction.y != 0 || direction.z != 0)
                    {
                        float3 delta = offsetsample - direction;
                        curminsample = offsetsample + delta * 4
                    }
                   else
                    {
                        curminsample = offsetsample;
                    }
                }
            }
            j++;
        }
    }
}

return curminsample;

This is very cool! So the problem with using the unwrapped position map as is, is the fact that you’ll get inaccurate position at the UV shell edges due aliasing? I’m assuming you would create this dilated version of the unwrapped position map offline, right? There is obviously no need to calculate this during runtime. Alternatively you could calculate it in an offline 3d package, although this is far more convenient (and better!).

I can’t wait to see today’s stream to get started!

That is where the problem starts, but even most offline renderers when doing dilation with just do a linear extrapolation with some blur to make it look nice. That is probably best when dealing with actual color textures but when the information is positional, it means the values on the edge would interpolate to values that were not continuous with the direction of the surface. It is like clamping the UVs right at the border rather than allowing them to continue past the border. If you then do things like spheremasks (which act like a ‘brush’) it means the edge pixels are effectively over weighted.

And yes, doing it as part of a BP can be important, say if you wanted to dynamically use a paintbrush on any given static mesh by just randomly choosing from the content browser without having to prep the mesh specifically to be painted on.

Btw I have no idea what is being covered on the training stream today. Something similar?

Oh yeah, totally understand the significance of the proper dilation, it’s awesome that you found a proper way of doing this. I would have probably learned to live with the issue. I think today’s stream is just covering the basics of the new render target functionality. I was hoping you were on!

Nope not this time but I am sure I will be on at some point soon to talk about stuff relating to this. have had a few people ask about the caustics rendering stuff I was messing with. I now have examples working in both scatter and gather form so I think that would make a good example to see the different versions.

Yes! Anything related to this stuff I’m 100% game!

I’ve tried to follow this tutorial and have no luck. am really noob, try to find any live video that can explain step by step tutorial. I want to learn to make this material a lot.

Hello, i was just curious if any one was able to get the custom code to work? i get only broken gray box material

There is tiny mistake in code of custom node

Thank you very much SpeakingFish for the solution.

I still can´t make the code to behave properly, as the edges of the UV islands seem to produce a black outline, I think this has to do with the alpha, produced on the render target, not properly cutting out these undesired edges.
Does anyone has a solution for this??
I attach screenshots of it in closeup with different parameter values.
Thanks in advance.

Are there any changes I need to make to the code for a RTF RG16f render target texture? Instead of the colors being in the range of 0 to 1, it’s in the range of -65504 to 65504