summaryrefslogtreecommitdiffstats
path: root/glitter.slang
blob: 5442a0f45e512cabcd60f81efb6e0489ee757002 (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
#ifndef __GLITTER_INC
#define __GLITTER_INC

#define PI 3.1415926535897932384626433832795028841971

float gaussian(float3 x, float3 mu, float sigma) {
  float3 x_minus_mu = x - mu;
  return exp(-dot(x_minus_mu, x_minus_mu) / (2 * sigma * sigma)) / (sigma * sqrt(2 * PI));
}

float det(float2x2 m) {
  return m[0][0] * m[1][1] - m[0][1] * m[1][0];
}

float dirac(float3 x) {
  // Ternary operator short-circuits in slang >:(
  return any(abs(x) < 1e-4) ? 1e4 : 0;
}

// Maps a point on the unit hemisphere to an inscribed circle.
float2 hemisphere_to_inscribed_circle(float3 p) {
  // TODO
  return 0;
}

float3 rand3_hash(float3 p)
{
    // Improved Murmurhash3 by Squirrel Eiserloh (GDC 2017)
    p = float3(dot(p, float3(127.1, 311.7, 74.7)),
               dot(p, float3(269.5, 183.3, 246.1)),
               dot(p, float3(113.5, 271.9, 124.6)));
    return -1.0 + 2.0 * frac(sin(p) * 43758.5453123);
}

public float D_Kemppinen(
  float3 worldPos,
  float3 H_tan,  // halfway vector in tangent space
  float amount,
  float roughness)
{
  float2x2 J_T__omega_h = 0;  // TODO
  float det_J_T__omega_h = det(J_T__omega_h);
  
  float sum = 0;
  // x is the current world space position.
  float3 x = worldPos;
  // omega_h is the halfway vector *in TBN coordinates.*
  float3 omega_h = H_tan;
  float3 T_omega_h = float3(
      hemisphere_to_inscribed_circle(omega_h),
      0);
  uint K_p = 1;  // TODO
  for (uint i = 0; i < K_p; ++i) {
    // x_i is the position of the facet.
    float3 x_i = worldPos;  // TODO randomize position
    // mu_i is the orientation of the facet.
    float3 mu_i = abs(rand3_hash(x_i));

    float a_star = roughness;

    float cur_gauss = gaussian(
        T_omega_h,
        mu_i,
        a_star * sqrt(det_J_T__omega_h));

    sum += cur_gauss * dirac(x_i - x);
  }

  float scale = det_J_T__omega_h / K_p;
  return sum * scale;
}

#endif  // __GLITTER_INC