-
Notifications
You must be signed in to change notification settings - Fork 0
/
restir.py
60 lines (49 loc) · 1.3 KB
/
restir.py
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
from __future__ import (
annotations as __annotations__,
) # Delayed parsing of type annotations
import mitsuba as mi
import drjit as dr
from drjitstruct import drjitstruct
from dataclasses import dataclass
@drjitstruct
class RestirSample:
wo: mi.Vector3f
Lo: mi.Vector3f
@drjitstruct
class RestirReservoir:
z: RestirSample
w: mi.Float
W: mi.Float
M: mi.UInt
def update(
self,
sampler: mi.Sampler,
snew: RestirSample,
wnew: mi.Float,
active: mi.Bool = True,
):
active = mi.Bool(active)
if dr.shape(active)[-1] == 1:
dr.make_opaque(active)
self.w += dr.select(active, wnew, 0)
self.M += dr.select(active, 1, 0)
self.z: RestirSample = dr.select(
active & (sampler.next_1d() < wnew / self.w), snew, self.z
)
def merge(
self, sampler: mi.Sampler, r: "RestirReservoir", p, active: mi.Bool = True
):
active = mi.Bool(active)
M0 = mi.UInt(self.M)
self.update(sampler, r.z, p * r.W * r.M, active)
self.M = dr.select(active, M0 + r.M, M0)
@dataclass
@drjitstruct
class SampleUpdate:
s: Sample
r: mi.Float
w: mi.Float
def __init__(self):
self.s = Sample()
self.r = mi.Float()
self.w = mi.Float()