Announcement

Collapse
No announcement yet.

Blog Post: Improved UV Dilation using Render Targets

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    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.

    Click image for larger version

Name:	Pool_Top.jpg
Views:	1
Size:	83.5 KB
ID:	1195332

    Click image for larger version

Name:	UVDilate.gif
Views:	1
Size:	544.9 KB
ID:	1195333

    Click image for larger version

Name:	simpledilation.jpg
Views:	1
Size:	49.5 KB
ID:	1195334

    Click image for larger version

Name:	improveddilation.jpg
Views:	1
Size:	45.0 KB
ID:	1195335

    Click image for larger version

Name:	SlopeProjection.jpg
Views:	1
Size:	41.0 KB
ID:	1195336

    Click image for larger version

Name:	ImprovedDilationComparison.jpg
Views:	1
Size:	52.4 KB
ID:	1195337

    Code:
    //////////////// 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;
    Click image for larger version

Name:	DilateMaterialGraph.gif
Views:	1
Size:	63.7 KB
ID:	1195338
    Ryan Brucks
    Principal Technical Artist, Epic Games

    #2
    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!

    Comment


      #3
      Originally posted by Norman3D View Post
      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?

      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?
      Ryan Brucks
      Principal Technical Artist, Epic Games

      Comment


        #4
        Originally posted by RyanB View Post
        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!

        Comment


          #5
          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.
          Ryan Brucks
          Principal Technical Artist, Epic Games

          Comment


            #6
            Originally posted by RyanB View Post
            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!

            Comment


              #7
              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.

              Comment


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

                Comment


                  #9
                  There is tiny mistake in code of custom node
                  Attached Files

                  Comment

                  Working...
                  X