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

Question VertexColor Pixelated as a Mask ? [SCRUBBED, HIGHJACKED to new shader]

Discussion in 'Shaders' started by daprato, Sep 2, 2020.

  1. daprato

    daprato

    Joined:
    Sep 25, 2013
    Posts:
    31
    Hi fabulous Unity people, I'm struggling creating a certain mask inside my shader. Maybe it will need some render-to-texture somewhere ? Or more maths to create a square pattern ?

    I want to get a one channel mask (like vertexColor.r) but rendering it as big binary or steped squares, not the "screenpixels" where normally the rasterization of the vertex color will do nice and smooth gradient.

    a. my vertex color
    b vertColor * bitmap
    c. rounded or step (unwanted: the angle created by the gradient vertex color)



    I'd like to reach this result (like if the vertColor was based onto the bitmap resolution provided):


    I thought about "re-sampling" if we could, Like re-playing with the UVs to round the gradient.
    or maybe checking how deeply the alphatest(cutout) is made, inserting a pass that select or not the pixels of the bitmap based on the intensity of the vertColor.

    some ideas guys ?

    Thx a lot
     
    Last edited: Sep 2, 2020
  2. daprato

    daprato

    Joined:
    Sep 25, 2013
    Posts:
    31
    Yes I could start to draw math squares.
    Code (CSharp):
    1. float2 uv = IN.uv_MainTex;
    2. float square = saturate(step(uv.y, 0.2)+ step(1-uv.y, 0.2) + step(uv.x, 0.2) + step(1-uv.x, 0.2));
    3. o.Albedo = square;
    But I'd like the vertexColor to bitmap mask to be ScreenSpace to UVs, not on absolute UVs as if I got always unique mapping. I'll use tilled mapping so I think the drawing math on UVs shouldn't work.
     
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,238
    There’s no really good way to do this with arbitrary vertex colors. It’s plausible it could be done with screen space derivatives: Get the derivatives of the base UVs & vertex colors and try to extrapolate the vertex color at the texel centers. But it won’t be perfect. And personally haven’t totally wrapped my head around doing that on non screen aligned UVs.
     
    daprato likes this.
  4. daprato

    daprato

    Joined:
    Sep 25, 2013
    Posts:
    31
    thx @bgolus
    I tried many things, but can't figure-out how to project screen-render to rasterized uvs on geometry.
    So I just forgot the idea and the flexibility of playing with data-instance that is the vertex-color to simply filter-out my pixel-reduction by a mask properly edited (need a certain step in tones + by toning a certain minimal resolution [32*32,64*64,128*128]).

    So I'll create more duplicate of material to move the mask around.

    I'm not using the text2lod to use mips, I prefer having the control of moving "underneath" the albedo that is "filtered" by the UV playing afterward.




    the shader if someone would like to play with the idea.

    Code (CSharp):
    1. Shader "DaPrato/Surface_PixelReduction"
    2. {
    3.     Properties{
    4.     _Color("Main Color", Color) = (1,1,1,0.5)
    5.     _MainTex("Texture", 2D) = "white" {}
    6.     _OffetX_c("UVs Offset X", float) = 0
    7.     _OffetY_c("UVs Offset Y", float) = 0
    8.     [NoScaleOffset]_PixelUV("PixelUV Texture", 2D) = "white" {}
    9.     [MaterialToggle]_NoMask("No Pixel Mask Used", range(0,1)) = 0
    10.     _OffetX_m("UVs Offset X", float) = 0
    11.     _OffetY_m("UVs Offset Y", float) = 0
    12.     _ScalePixel("Pixel Scale (fit well ^2)", range(1,64)) = 2
    13.     [Toggle(ROUNDTO2)]_RoundToPow2("Round to ^2", float) = 0
    14.     [Header(Debug)]
    15.     [MaterialToggle]_DebugMask("Debug: Show Pixel Mask", range(0,1)) = 0
    16.     [MaterialToggle]_DebugSource("Debug: Show Albedo Original", range(0,1)) = 0
    17.  
    18.     }
    19.  
    20.     Subshader{
    21.         Tags { "RenderType" = "Opaque" }
    22.  
    23.         CGPROGRAM
    24.         #pragma surface surf Lambert
    25.         #pragma shader_feature ROUNDTO2
    26.         struct Input {
    27.             float4 vertcolor : COLOR; // Vertex Color
    28.             float2 uv_MainTex;
    29.         };
    30.  
    31.         float4 _Color;
    32.         sampler2D _MainTex;
    33.         sampler2D _PixelUV;
    34.         float _ScalePixel;
    35.         float _DebugMask, _DebugSource;
    36.         float _RoundToPow2;
    37.         float _NoMask;
    38.         float _OffetX_c, _OffetY_c;
    39.         float _OffetX_m, _OffetY_m;
    40.         float scalePixel;
    41.  
    42.         float round2(float scale)
    43.         {
    44.             if (scale >= 1 && scale < 4) { scale = 1; }
    45.             if (scale >= 2 && scale < 4) { scale = 2; }
    46.             if (scale >= 4 && scale < 8) { scale = 4; }
    47.             if (scale >= 8 && scale < 12) { scale = 8; }
    48.             if (scale >= 12 && scale < 24) { scale = 16; }
    49.             if (scale >= 24 && scale < 42) { scale = 32; }
    50.             if (scale >= 42) { scale = 64; }
    51.             return scale;
    52.         }
    53.  
    54.         void surf(Input IN, inout SurfaceOutput o)
    55.         {
    56.  
    57.             #ifdef ROUNDTO2
    58.             scalePixel = round2(_ScalePixel);
    59.             #else
    60.             scalePixel = _ScalePixel;
    61.             #endif
    62.  
    63.             float2 uv;
    64.             float f;
    65.             float halfpixel;
    66.             float2 uvOffset_c = float2(_OffetX_c *0.1, _OffetY_c*0.1);
    67.             float2 uvOffset_m = float2(round(_OffetX_m *0.1*32)/32, round(_OffetY_m*0.1*32)/32);
    68.  
    69.             float4 pixelUV = tex2D(_PixelUV, IN.uv_MainTex + uvOffset_m);
    70.             f = round(lerp(pixelUV.r, 1, _NoMask) * 8) * scalePixel;
    71.             halfpixel = (1 / f) * 0.5;
    72.             uv = (round((IN.uv_MainTex - halfpixel) * f) / f);
    73.  
    74.             o.Albedo =  lerp(lerp(tex2D(_MainTex, uv + uvOffset_c), pixelUV.r, _DebugMask), tex2D(_MainTex, IN.uv_MainTex),_DebugSource);
    75.         }
    76.         ENDCG
    77. }
    78. Fallback "Diffuse"
    79. }
    80.  
    81.  
    *** Yes I left a lerp in a lerp for debug, you can just clean it anyway.

    textures used in demo.
    https://drive.google.com/drive/folders/11WlTYPq-vB-MDz5-0E7vB2qXIx9CVZb8?usp=sharing
     
    Last edited: Sep 6, 2020