summaryrefslogtreecommitdiffstats
path: root/custom31.cginc
blob: fa6b469a8b16028396c9e4a21944b693a7d4444e (plain)
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
73
74
75
#ifndef __CUSTOM31_INC
#define __CUSTOM31_INC

#include "globals.cginc"
#include "interpolators.cginc"
#include "math.cginc"
#include "quilez.cginc"

#if defined(_CUSTOM31_WORLD)
float c31_map(float3 p, float3 p_quant) {
  float2 hex_dim = float2(_Custom31_World_Hexagons_Tile_Radius, _Custom31_World_Hexagons_Tile_Thickness);

  float3 axis_normal = normalize(hash33_fast(p_quant) * 2 - 1);
  float theta = hash31_ff(p_quant) * TAU + _Time[1];
  float4 quat = get_quaternion(axis_normal, theta);
  p = rotate_vector(p, quat);

  return distance_from_hex_prism(p, hex_dim);
}

float3 c31_normal(float3 p, float3 p_quant) {
  const float epsilon = 1e-3;
  const float3 xstep = float3(epsilon, 0, 0);
  float d0 = c31_map(p, p_quant);
  return normalize(float3(
      c31_map(p + xstep.xyy, p_quant) - d0,
      c31_map(p + xstep.yxy, p_quant) - d0,
      c31_map(p + xstep.yyx, p_quant) - d0));
}
#endif  // _CUSTOM31_WORLD

void apply_custom31_world(v2f i, inout Pbr pbr, inout float3 normal_tangent) {
#if defined(_CUSTOM31_WORLD)
  // We ray march in tangent (TBN) space.
  float3 ro = float3(i.uv01.xy, 0);
  float3 rd_world = normalize(i.worldPos - _WorldSpaceCameraPos);
  float3 rd = normalize(mul(pbr.tbn, rd_world));

#if defined(_CUSTOM31_WORLD_HEXAGONS)
  // Apply hexagonal domain repetition.
  float domain_rep_period = _Custom31_World_Hexagons_Grid_Scale;
  // yx swizzle rotates hexagons 90 degrees
  float3 h = cart_to_hex(ro.yx);
  float3 h_rounded = round_hex(h / domain_rep_period) * domain_rep_period;
  ro.xy = hex_to_cart(h - h_rounded).yx;
  ro.z += _Custom31_World_Hexagons_Tile_Thickness;
  ro.z += _Custom31_World_Ray_March_Min_Dist;
#endif

  float d_acc = 0;
  float d;
  [loop]
    for (uint ii = 0; ii < _Custom31_World_Ray_March_Steps; ++ii) {
      float3 p = ro + rd * d_acc;
      d = c31_map(p, h_rounded);
      d_acc += d;
      if (d < _Custom31_World_Ray_March_Min_Dist) {
        break;
      }
      if (d > _Custom31_World_Ray_March_Max_Dist) {
        break;
      }
    }

  if (d < _Custom31_World_Ray_March_Min_Dist) {
    pbr.albedo.xyz = 1;

    normal_tangent = c31_normal(ro + rd * d_acc, h_rounded);
  } else {
    pbr.albedo.xyz = 0;
  }
#endif
}

#endif  // __CUSTOM31_INC