File: Flakes.ih

package info (click to toggle)
ospray 3.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 10,040 kB
  • sloc: cpp: 80,569; ansic: 951; sh: 805; makefile: 171; python: 69
file content (71 lines) | stat: -rw-r--r-- 1,781 bytes parent folder | download | duplicates (2)
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
// Copyright 2009 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include "Noise.ih"
#include "render/bsdfs/BeckmannDistribution.ih"

OSPRAY_BEGIN_ISPC_NAMESPACE

struct Flakes
{
  float scale;
  float density;
  float spread;
  float jitter;
};

inline vec3f Flakes_eval(const Flakes &self, vec3f P, int &mask)
{
  vec3f N = make_vec3f(0.f, 0.f, 1.f);
  mask = 0;

  if (self.density <= 0.f || self.spread <= 0.f)
    return N;

  const BeckmannDistribution flakeDistribution =
      make_BeckmannDistribution(roughnessToAlpha(self.spread));
  P = P * self.scale;

  // Simple Worley cellular noise with jittered feature points
  // [Apodaca and Gritz, 1999, "Advanced RenderMan: Creating CGI for Motion
  // Pictures", pp. 255-261]
  const vec3f thisCell = floor(P) + 0.5f;
  float f1 = 1000.f;
  unsigned int cellRnd;

  for (int i = -1; i <= 1; i++) {
    for (int j = -1; j <= 1; j++) {
      for (int k = -1; k <= 1; k++) {
        const vec3f testCell = thisCell + make_vec3f(i, j, k);

        // generate a random ID for the test cell
        unsigned int rnd = cellNoise1ui(testCell);

        // generate the position of the feature point in the test cell
        const vec3f pos = testCell + self.jitter * (LCG_getFloat3(rnd) - 0.5f);

        // distance test
        const vec3f offset = pos - P;
        const float dist = dot(offset, offset); // actually dist^2
        if (dist < f1) {
          f1 = dist;
          cellRnd = rnd;
        }
      }
    }
  }

  // test whether the flake exists
  if (LCG_getFloat(cellRnd) <= self.density) {
    // generate a random normal for the flake
    float pdf;
    N = sample(flakeDistribution, pdf, LCG_getFloat2(cellRnd));
    mask = 1;
  }

  return normalize(N);
}

OSPRAY_END_ISPC_NAMESPACE