Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Perspective-corrected texture filtering in post-process

Discussion in 'Shaders' started by metaleap, May 16, 2014.

  1. metaleap

    metaleap

    Joined:
    Oct 3, 2012
    Posts:
    589
    This is a bit of a crazy thing to do but believe me I have my reasons :D

    Take a look at this shot: https://dl.dropboxusercontent.com/u/136375/img/screens/unity-post-uv.png

    Everything is normally rendered geometry except the checkers-textured "plane" which is a post-process effect of sorts. Thanks to BEAM I finally figured out world-position coordinates for each screen pixel and use these to "texture a virtual plane".

    As you can see the filtering artifacts are going crazy, as the hardware is thinking of a full-screen quad geometric context, not a perspective-projected 3D plane context. Hence the filtering looks badly pixelated, of course the checkers texture for debug purposes is set to uncompressed, trilinear, aniso=9 filtering.

    Anyone got some neat ideas on how to smartly re-configure the filtering to be used in this particular tex2D(debugTex, worldPos.xz * 0.1) Cg call? Can ddx/ddy help here somehow? Right now I'm not even sure if it's just bad MIP-level selection or a general filtering mishap, fwiw without mips it looks slightly different but just as badly filtered / pixelated. I'm in #pragma glsl and #pragma target 3.0 mode.
     
    Last edited: May 16, 2014
  2. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    Maybe, you could pass them to tex2Dgrad. However, the screen space derivatives of the uv coordinates should be the same whether it's a full-screen quad or a projected plane. So it should work with or without explicit ddx/ddy.

    Code (csharp):
    1.  
    2. float2 dx = ddx(nTexCoord); // calculate the texcoord partial derivative in x in screen space for tex2Dgrad
    3. float2 dy = ddy(nTexCoord); // calculate the texcoord partial derivative in y in screen space for tex2Dgrad
    4. vCurrSample = tex2Dgrad (mMap, nTexCoord, dx, dy);
    5.  
     
  3. metaleap

    metaleap

    Joined:
    Oct 3, 2012
    Posts:
    589
    Thanks! You're right, because tex2Dgrad with ddx/ddy gives the exact same visual results as tex2D without.

    Makes me scratch my head and wonder, what the heck is causing the pixelated sampling.. it happens at all distances, even close-up, as seen in this 2nd shot:

    https://dl.dropboxusercontent.com/u/136375/img/screens/unity-post-uv-2.png

    So I'm using worldPos.xz*0.1 as the uv and I'm less than 100 units away from the world center but I guess in floats I'm already losing precision at that point and should myself remap the sampling coords to 0..1 with mod or something? Gotta look into that :D
     
  4. metaleap

    metaleap

    Joined:
    Oct 3, 2012
    Posts:
    589
    But this can't be the solution either, surely no matter what I do to turn worldPos.xz into texCoords 0..1 the sampler would do itself otherwise anyway, with the same precision and performance as, or better than, I can manually :(
     
  5. metaleap

    metaleap

    Joined:
    Oct 3, 2012
    Posts:
    589
    SOLVED. Had to up the RenderTexture precision from ArgbHalf to ArgbFloat. Damn I thought "half-precision should surely suffice" :D oh well. Thanks again :)
     
  6. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    From that latest screenshot I would indeed think it's a precision issue on the uv coordinates used.