Search Unity

Question Stochastic Node Triangle Grid Smoothing

Discussion in 'Shaders' started by Keroro91, Apr 7, 2021.

  1. Keroro91

    Keroro91

    Joined:
    Dec 4, 2017
    Posts:
    1
    Hello, I'm currently using a custom node in Shader Graph to produce a Stochastic material :
    Code (CSharp):
    1. // Source / Author:
    2.     //https://www.reddit.com/user/rotoscope-/
    3.     //https://www.reddit.com/r/Unity3D/comments/dhr5g2/i_made_a_stochastic_texture_sampling_shader/
    4.     //https://pastebin.com/sDrnzYxB
    5.  
    6.  
    7. //hash for randomness
    8. float2 hash2D2D (float2 s){
    9.     //magic numbers
    10.     return frac(sin(fmod(float2(dot(s, float2(127.1,311.7)), dot(s, float2(269.5,183.3))), 3.14159))*43758.5453);
    11. }
    12.  
    13. void Tex2DStochastic_float(Texture2D Texture, SamplerState Sample, float2 UV, out float4 Out){
    14.     //triangle vertices and blend weights
    15.     //BW_vx[0...2].xyz = triangle verts
    16.     //BW_vx[3].xy = blend weights (z is unused)
    17.     float4x3 BW_vx;
    18.  
    19.     //uv transformed into triangular grid space with UV scaled by approximation of 2*sqrt(3)
    20.     float2 skewUV = mul(float2x2 (1.0 , 0.0 , -0.57735027 , 1.15470054), UV * 3.46410161);
    21.  
    22.     //vertex IDs and barycentric coords
    23.     float2 vxID = float2 (floor(skewUV));
    24.     float3 barry = float3 (frac(skewUV), 0);
    25.     barry.z = 1.0-barry.x-barry.y;
    26.  
    27.     BW_vx = ((barry.z>0) ?
    28.         float4x3(float3(vxID, 0), float3(vxID + float2(0, 1), 0), float3(vxID + float2(1, 0), 0), barry.zyx) :
    29.         float4x3(float3(vxID + float2 (1, 1), 0), float3(vxID + float2 (1, 0), 0), float3(vxID + float2 (0, 1), 0), float3(-barry.z, 1.0-barry.y, 1.0-barry.x)));
    30.  
    31.     //calculate derivatives to avoid triangular grid artifacts
    32.     float2 dx = ddx(UV);
    33.     float2 dy = ddy(UV);
    34.  
    35.     //blend samples with calculated weights
    36.     Out = mul(SAMPLE_TEXTURE2D(Texture, Sample, UV + hash2D2D(BW_vx[0].xy) + dx + dy), BW_vx[3].x) +
    37.             mul(SAMPLE_TEXTURE2D(Texture, Sample, UV + hash2D2D(BW_vx[1].xy)+ dx + dy), BW_vx[3].y) +
    38.             mul(SAMPLE_TEXTURE2D(Texture, Sample, UV + hash2D2D(BW_vx[2].xy)+ dx + dy), BW_vx[3].z);
    39.    
    40. }
    The overvall code works great but I still see the triangle grid (more visible when using a normal map as input) :
    upload_2021-4-7_14-11-49.png
    I believe the result is caused by this piece of code which could be improved to fade the grid out completely.
    Code (CSharp):
    1.     //calculate derivatives to avoid triangular grid artifacts
    2.     float2 dx = ddx(UV);
    3.     float2 dy = ddy(UV);
    Any help would be much appreciated
    Regards
     
  2. DarkSapra

    DarkSapra

    Joined:
    Nov 21, 2017
    Posts:
    5
    Hi! Did you manage to solve it?
     
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Use
    Texture.SampleGrad(Sample, UV + hash2D2D(BW_vx[0].xy) , dx, dy)
    instead of the
    SAMPLE_TEXTURE2D
    lines. (I'm perpetually annoyed Unity didn't implement
    SAMPLE_TEXTURE2D_GRAD
    .) The original source the above code is based on did this correctly, and it was translated to SRP style HLSL incorrectly.
     
    ATMLVE likes this.