-
Notifications
You must be signed in to change notification settings - Fork 229
/
TextureToBlocks.compute
68 lines (61 loc) · 1.58 KB
/
TextureToBlocks.compute
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
#pragma kernel CSMain
int _Resolution;
float4 _WorldSpaceLightPos;
RWTexture3D<float4> _RWTexture3D;
float Hash (float2 n)
{
return frac(sin(dot(n, float2(13.9898, 4.1414))) * 43758.5453);
}
float Noise (float2 p)
{
float size = 256.0;
float i = (1.0 / size);
float2 pixel = p * size + 0.5;
float2 f = frac(pixel);
float2 cell = floor(pixel) / size - (float2)(i / 2.0);
float a = Hash(cell + float2(0, 0));
float b = Hash(cell + float2(i, 0));
float c = Hash(cell + float2(0, i));
float d = Hash(cell + float2(i, i));
return lerp(lerp(a, b, f.x), lerp(c, d, f.x), f.y);
}
float Fbm (float2 p)
{
float a = 0.5, b = 0.0, t = 0.0;
for (int i = 0; i < 7; i++)
{
b *= a; t *= a;
b += Noise(p);
t += 1.0; p /= 2.0;
}
return b /= t;
}
float Map (float3 p)
{
float h = p.y - Fbm(p.xz * 0.5);
return all(clamp(p, 0, 1) == p) ? h : 1.0;
}
float Shadow (float3 ro, float3 rd, float mint, float maxt, float k)
{
float t = mint;
float result = 1.0;
for (int i = 0; i < 128; ++i)
{
float h = Map(ro + rd * t);
if ( h < 0.001 ) return 0.0;
result = min(result, k * h / t);
t += h;
if (t > maxt) break;
}
return result;
}
[numthreads(8, 8, 8)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
float3 uvw = float3(id.x, id.y, id.z) / float(_Resolution);
float sdf = Map(uvw);
float3 lightDir = normalize(_WorldSpaceLightPos.xyz);
float shadow = Shadow(uvw, lightDir, 0.0625, length(lightDir), 64.0);
float3 color = (uvw.y < 0.35) ? float3(0, 0, uvw.y) : uvw.yyy;
_RWTexture3D[id] = float4(color * shadow, sdf);
}