본문으로 바로가기

stochastic tiling shader

category Technical Report/Unity Shader 2022. 5. 29. 22:44
반응형

/*
hash code come from
https://briansharpe.wordpress.com/2011/11/15/a-fast-and-simple-32bit-floating-point-hash-function/
https://iquilezles.org/www/articles/texturerepetition/texturerepetition.htm?fbclid=IwAR1DP44yF51aAJZCZizV1v1GfTDciW_XfOYokIxtybMmCWGeKcQn_v-Pxvo
https://qiita.com/yuji_yasuhara/items/158bab01cfff3c39214b

https://drive.google.com/file/d/1QecekuuyWgw68HU9tg6ENfrCTCVIjm6l/view
*/
Unity 절차전 랜덤 텍스처링

https://blog.unity.com/kr/technology/procedural-stochastic-texturing-in-unity

 

Unity의 절차적 랜덤 텍스처링 | Unity Blog

이 기술은 거리를 두고 보았을 때 랜덤 노이즈와 유사한 텍스처와, 정밀한 기하학적 형태가 없는 자연스러운 머티리얼과 같은 타일러블 랜덤 텍스처 또는 랜덤에 가까운 텍스처에만 사용 가능

blog.unity.com

 

Shader "UnTilerable"
{

Properties
{
  _MainTex("RGB 01", 2D) = "white" {}
}

SubShader
{
Tags
 {
 "RenderPipeline" = "UniversalPipeline"
 "RenderType" = "Opaque"
 "Queue" = "Geometry"
 }

 Pass
 {
    Name "Universal Forward"
    Tags {"LightMode" = "UniversalForward"}

HLSLPROGRAM
 #pragma prefer_hlslcc gles
 #pragma exclude_renderers d3d11_9x
 #pragma vertex vert
 #pragma fragment frag     

  #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"

   struct VertexInput
   {
float4 vertex : POSITION;
float2 uv     : TEXCOORD0;
   };

   struct VertexOutput
    {
       float4 vertex      : SV_POSITION;
       float2 uv     : TEXCOORD0;
       float2 uv2    : TEXCOORD1;
    };

   float4 _MainTex_ST;
      //Texture2D _MainTex;
      //SamplerState sampler_MainTex;
      sampler2D _MainTex;

VertexOutput vert(VertexInput v)
   {
    VertexOutput o;
    o.vertex = TransformObjectToHClip(v.vertex.xyz);
    o.uv = v.uv.xy * _MainTex_ST.xy + _MainTex_ST.zw;    
   return o;
   }

/*

  float4 hash4(in float2 v)
   {
float4 p = float4(v * float4x2(127.1, 311.7, 269.5, 183.3, 113.5, 271.9, 246.1, 124.6));
return frac(sin(p) * 43758.5453123);
   }

 float4 hash4(in float3 v)
  {
 float4 p = float4(v * float4x3{127.1, 311.7, 74.7, 269.5, 183.3, 246.1, 113.5, 271.9, 124.6, 271.9, 269.5, 311.7});
    return frac(sin(p) * 43758.5453123);
   }
   */

float4 hash4fast(float2 gridcell)
 {
       const float2 OFFSET = float2(26.0, 161.0);
       const float DOMAIN = 71.0;
       const float SOMELARGEFIXED = 951.135664;
       float4 P = float4(gridcell.xy, gridcell.xy + 1);
       P = frac(P * (1 / DOMAIN)) * DOMAIN;
       P += OFFSET.xyxy;
       P *= P;
       return frac(P.xzxz * P.yyww * (1 / SOMELARGEFIXED));
  }

inline float3 textureNoTile(sampler2D samp, in float2 uv)
{
float2 iuv = float2(floor(uv));
float2 fuv = frac(uv);

// generate per-tile transform
float4 ofa = hash4fast(iuv + float2(0, 0));
float4 ofb = hash4fast(iuv + float2(1, 0));
float4 ofc = hash4fast(iuv + float2(0, 1));
float4 ofd = hash4fast(iuv + float2(1, 1));

float2 dx = ddx(uv);
float2 dy = ddy(uv);

// transform per-tile uvs
ofa.zw = sign(ofa.zw - 0.5);
ofb.zw = sign(ofb.zw - 0.5);
ofc.zw = sign(ofc.zw - 0.5);
ofd.zw = sign(ofd.zw - 0.5);

// uv's, and derivatives (for correct mipmapping)
float2 uva = uv * ofa.zw + ofa.xy, ddxa = dx * ofa.zw, ddya = dy * ofa.zw;
float2 uvb = uv * ofb.zw + ofb.xy, ddxb = dx * ofb.zw, ddyb = dy * ofb.zw;
float2 uvc = uv * ofc.zw + ofc.xy, ddxc = dx * ofc.zw, ddyc = dy * ofc.zw;
float2 uvd = uv * ofd.zw + ofd.xy, ddxd = dx * ofd.zw, ddyd = dy * ofd.zw;

// fetch and blend
float2 b = smoothstep(0.25, 0.75, fuv);

float3 mix01 = lerp(tex2Dgrad(samp, uva, ddxa, ddya), tex2Dgrad(samp, uvb, ddxb, ddyb), b.x);
float3 mix02 = lerp(tex2Dgrad(samp, uvc, ddxc, ddyc), tex2Dgrad(samp, uvd, ddxd, ddyd), b.x);
float3 color = lerp(mix01, mix02, b.y);


return color;
}

half4 frag(VertexOutput i) : SV_Target
 {
  half3 color = textureNoTile(_MainTex, i.uv);    
  return half4(color.rgb, 1);
 }
ENDHLSL
    }
  }
 }

 

타일링 수에 따라 위와같이 UV타일이 제대로 나오지 않는 부분있음.

반응형