-
Notifications
You must be signed in to change notification settings - Fork 11
/
textureNoTile.cginc
72 lines (60 loc) · 3.31 KB
/
textureNoTile.cginc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// The MIT License (MIT) (see LICENSE.txt)
// Copyright © 2015 Inigo Quilez
// Copyright © 2021 Jens Neitzel
// One simple way to avoid texture tile repetition, at the cost of 4 times the amount of
// texture lookups (still much better than https://www.shadertoy.com/view/4tsGzf)
//
// More info: http://www.iquilezles.org/www/articles/texturerepetition/texturerepetition.htm
struct NoTileUVs
{
fixed4 ofa, ofb, ofc, ofd;
fixed2 uva, uvb, uvc, uvd, b;
fixed2 ddxa, ddxb, ddxc, ddxd;
fixed2 ddya, ddyb, ddyc, ddyd;
};
fixed4 hash4( fixed2 p ) { return frac(sin(fixed4( 1.0+dot(p,fixed2(37.0,17.0)),
2.0+dot(p,fixed2(11.0,47.0)),
3.0+dot(p,fixed2(41.0,29.0)),
4.0+dot(p,fixed2(23.0,31.0))))*103.0); }
NoTileUVs textureNoTileCalcUVs( in fixed2 uv )
{
NoTileUVs ntuvs;
fixed2 iuv = floor( uv );
fixed2 fuv = frac( uv );
// generate per-tile transform
ntuvs.ofa = hash4( iuv + fixed2(0,0) );
ntuvs.ofb = hash4( iuv + fixed2(1,0) );
ntuvs.ofc = hash4( iuv + fixed2(0,1) );
ntuvs.ofd = hash4( iuv + fixed2(1,1) );
fixed2 uvddx = ddx( uv );
fixed2 uvddy = ddy( uv );
// transform per-tile uvs
ntuvs.ofa.zw = sign(ntuvs.ofa.zw-0.5);
ntuvs.ofb.zw = sign(ntuvs.ofb.zw-0.5);
ntuvs.ofc.zw = sign(ntuvs.ofc.zw-0.5);
ntuvs.ofd.zw = sign(ntuvs.ofd.zw-0.5);
// uv's, and derivatives (for correct mipmapping)
ntuvs.uva = uv*ntuvs.ofa.zw + ntuvs.ofa.xy; ntuvs.ddxa = uvddx*ntuvs.ofa.zw; ntuvs.ddya = uvddy*ntuvs.ofa.zw;
ntuvs.uvb = uv*ntuvs.ofb.zw + ntuvs.ofb.xy; ntuvs.ddxb = uvddx*ntuvs.ofb.zw; ntuvs.ddyb = uvddy*ntuvs.ofb.zw;
ntuvs.uvc = uv*ntuvs.ofc.zw + ntuvs.ofc.xy; ntuvs.ddxc = uvddx*ntuvs.ofc.zw; ntuvs.ddyc = uvddy*ntuvs.ofc.zw;
ntuvs.uvd = uv*ntuvs.ofd.zw + ntuvs.ofd.xy; ntuvs.ddxd = uvddx*ntuvs.ofd.zw; ntuvs.ddyd = uvddy*ntuvs.ofd.zw;
// fetch and blend
ntuvs.b = smoothstep(0.25, 0.75, fuv);
return ntuvs;
}
fixed4 textureNoTile( sampler2D samp, in NoTileUVs ntuvs )
{
// Use modified UVs to sample a texture
return lerp( lerp( tex2D( samp, ntuvs.uva, ntuvs.ddxa, ntuvs.ddya ),
tex2D( samp, ntuvs.uvb, ntuvs.ddxb, ntuvs.ddyb ), ntuvs.b.x ),
lerp( tex2D( samp, ntuvs.uvc, ntuvs.ddxc, ntuvs.ddyc ),
tex2D( samp, ntuvs.uvd, ntuvs.ddxd, ntuvs.ddyd ), ntuvs.b.x ), ntuvs.b.y );
}
fixed3 textureNoTileNormal( sampler2D sampNorm, in NoTileUVs ntuvs, in half normalScale )
{
// Use modified UVs to sample a normal map, also inverting red and green channels where needed due to mirroring
return lerp( lerp( fixed3( ntuvs.ofa.z, ntuvs.ofa.w, 1 ) * UnpackNormalWithScale( tex2D( sampNorm, ntuvs.uva, ntuvs.ddxa, ntuvs.ddya ), normalScale ),
fixed3( ntuvs.ofb.z, ntuvs.ofb.w, 1 ) * UnpackNormalWithScale( tex2D( sampNorm, ntuvs.uvb, ntuvs.ddxb, ntuvs.ddyb ), normalScale ), ntuvs.b.x ),
lerp( fixed3( ntuvs.ofc.z, ntuvs.ofc.w, 1 ) * UnpackNormalWithScale( tex2D( sampNorm, ntuvs.uvc, ntuvs.ddxc, ntuvs.ddyc ), normalScale ),
fixed3( ntuvs.ofd.z, ntuvs.ofd.w, 1 ) * UnpackNormalWithScale( tex2D( sampNorm, ntuvs.uvd, ntuvs.ddxd, ntuvs.ddyd ), normalScale ), ntuvs.b.x ), ntuvs.b.y );
}