Importance-Sampling (-ish)
Closed this issue · 1 comments
lowkey42 commented
Klassisches Importance-Sampling ist vermutlich nicht direkt mit dem aktuellen Sampling-Pattern vereinbar aber eine einfache Verbesserung der Trefferquote könnte evtl. bereits dadurch erzielt werden, dass die Winkel der Punkte (in Polarkoordinaten) in Richtung der Screen-Space Normale des Ausgangspunktes verschoben (gewichtet mit 1-Z).
lowkey42 commented
Fürs Protokoll:
Python-Code für Verteilung der Samples:
import matplotlib.pyplot as plt
import math
def lerp(a, b, t):
return a + (b-a)*t
fig, ax = plt.subplots()
ax.add_artist(plt.Circle((0.5, 0.5), 0.5, color='grey'))
ax.add_artist(plt.Circle((0.5, 0.5), 0.25, color='darkgrey'))
plt.gca().set_aspect('equal', adjustable='box')
phi = ((math.sqrt(5)+1)/2)**2.0
step = math.pi * 2.0 / phi
r_outer = 0.5;
r_inner = r_outer/2;
normal = (1, 0, 0.0)
N = 128
for i in range(0, N):
t = math.sqrt(i*1.0) / math.sqrt(N);
r = r_inner + (r_outer - r_inner)*t;
angle = math.fmod(i * step, 2*math.pi);
ar = angle / (2*math.pi)
d = ar*2 if ar<0.5 else (1-ar)*2
org_d = d;
print(math.degrees(angle), d)
#d = 3.54*d - 5.69*d*d + 3.06*d*d*d
#d = 3.667*d - 7.083*d*d + 4.16667*d*d*d
#d = 1.325*d - 3.542*d*d + 2.9*d*d*d + 0.1
d = 2.5*d - 5.42*d*d + 3.6*d*d*d + 0.1
d += (1-d) * normal[2]
if ar<0.5:
angle = lerp(0, angle, d)
else:
angle = lerp(angle, math.pi*2, 1-d)
angle += 0.5*math.pi + math.atan2(normal[1], normal[0])
x = 0.5 + math.sin(angle)*r
y = 0.5 + math.cos(angle)*r
ax.add_artist(plt.Circle((x, 1-y), 0.005, color=(1, org_d, org_d)))
fig.savefig('/tmp/plotcircles.png')